美文网首页
开发bug记录

开发bug记录

作者: 木白no1 | 来源:发表于2016-06-06 10:26 被阅读697次
    1. 在chrome浏览器出现Uncaught SyntaxError: Unexpected token u

    在chrome浏览器出现 Uncaught SyntaxError: Unexpected token u 页面一片空白 显示不了,在Firefox正常

    问题原因: 由于使用了localStorage ,会造成废弃或者未定义的数据,就是udefined,当使用Json.parse()解析值为udefined的Json数据时 chrome 就会抛出错误,而FireFox会返回正确的字符窜,

    解决方法,使用LocalStorage.removeItem()把拥有undefined的数据清掉; 问题链接

    2. new Date()对象的兼容性问题

    chrome浏览器支持 “1990-08-10 15:20:10”的格式,其他浏览器不支持,统一支持的是new Date(2015,10,20,15,12),但是chrome得出的是正确的时间,而firefox与IE 的出的时间比正常的时间少了8个小时
    chrom:

    chrome获取时间

    fireFox:

    firefox获取时间

    或许是时区的问题,但是可以使用valueOf()取它们的毫秒数是一样的。所以还是老实的getDate,getHours、getMinute吧

    jq.formatCommonTime = function(millisec, isSample) {
        var time = new Date();
        time.setTime(millisec || 0); //设置需要格式化的时间
    
        if (!!isSample) {
            return (time.getMonth() + 1) + '月' + time.getDate() + '日';
        }else{
            return time.getFullYear() + '年' + (time.getMonth() + 1) + '月' + time.getDate() + '日 ' + time.getHours() + ':' + ((time.getMinutes() < 10) ? "0" : "") + time.getMinutes();
        }
    }
    
    3、IE浏览器控制台出现 Exception in window.onload: Error: An error has ocurredJSPlugin.3005

    原因是IE浏览器自身更新问题 只要下载补丁更新就好了补丁下载链接

    4 、需要判断出IE8浏览器
    <!--[if lt IE 9]>
          .series em{
               text-align: right!important;
           }
    <![endif]-->
    //如果是因为其他原因使用不了,比如sass编译会出错,可以使用Jquery方法判断
    //判断是否是IE8及以下
        var ie8 = $.support.leadingWhitespace;
        if(!ie8){
            $('em').addClass('ie8');
        }
    
    5、Jquery 使用scroll()函数在IE8及以下出现问题

    原因是监听的是document、或者body,只有改成window就可以了。

    //滚动显示侧边栏
    $(window).scroll(function(){
            var scrollTop = $(document).scrollTop();
            if(scrollTop >= 630){
                    $('.m-menu').show();
            }else{
                    $('.m-menu').hide();
            }
    });
    
    6、在服务器上安装 npm install的时候出现

    npm WARN package.json methods@0.0.1No license field.
    npm WARN package.json methods@0.0.1No repository field.
    npm WARN package.json methods@0.0.1No readme data.

    只要在package.json 里面加上

    "repository":{"type":"git","url":"git://github.com/username/repository.git"}
    or
    {"name":"my-application","version":"0.0.1","private":true}
    

    就可以了

    7、移动端视频播放支持

    移动端不支持视频自动播放,所以只好采用poster的方式,如果采用遮盖一层封面的话,则需要点击两次才可以。
    还有在安卓手机的微信,当切换page时(fullpage.js会出现),播放器会浮起,所以在离开当前页面时把视频remove掉,页面加载时重新生成视频。

    但是好像iphone手机是支持自动播放的,但是偶尔又不行了。在安卓端如果把controls加上、autoplay去掉,基本可以播放,但是video标签需要换一种格式来写,也可能有些手机对视频的格式有要求:

           if(b._$IS['android']){
                videoFlag = '<video width="100%" controls="controls" preload="auto"><source src="' + _vLink + '"><p>你的手机不支持video播放器</p></video>';
            }else{
                videoFlag = '<video width="100%" preload="auto" src="' + _vLink + '" autoplay="autoplay"></video>';
            }
    

     var videoFlag = '<video width="100%" controls="controls" preload="auto"><source src="' + _vLink + '">
    <source src="https://broken-links.com/tests/media/BigBuck.webm" type="video/webm">
    <source src="https://broken-links.com/tests/media/BigBuck.theora.ogv" type="video/ogg">
    <p>你的手机不支持video播放器</p>
    </video>';
    

    8、隐藏元素的滚动条

    #element::-webkit-scrollbar {display: none;}
          //If you want all scrollbars hidden, use
    ::-webkit-scrollbar {display: none;}
          // I'm not sure about restoring - this did work, but there might be a right way to do it:
     ::-webkit-scrollbar {display: block;}
    

    overflow属性设置的值为visible、scroll、hidden、auto

    visible 默认值。使用该值时,无论设置的"width"和"height"的值是多少,其中的内容无论是否超出范围都将被强制显示。
    hidden 效果与visible相反。任何超出"width"和"height"的内容都会不可见。
    scroll 无论内容是否超越范围,都将显示滚动条。
    auto 当内容超出范围时,显示滚动条,否则不显示。
    所以当div里面的内容高度不固定时,如果超出高度就出现滚动条,如果高度不够那就不出现滚动条,这个时候应该使用auto

    9、移动端页面上出现没能适配整个屏幕

    在移动端的页面中,在chrome模拟调试时发现是完全可以适配屏幕的,但是到了其他浏览器以及微信上出现了页面可以左右滚动的问题,检查html,body,都没有发现有元素溢出,一层层排查进来,发现是内容区域的确有div溢出了,原因是宽度定为了屏幕宽度90%,需要居中,使用left:50%,margin-left:-25%;类似的方法,可能有些浏览器的渲染方式不一样,才会出现这种问题

    10、IE8不支持innerHTML的赋值,报未知运行错误。

    在ie8中,可以看淡dom对象是有innerHTML属性的,并且能获取到innerHTML的值,但是呢,却不能给innerHTML赋值, 比如说 domObj.innerHTML = "1"都不行。一番查找之后,发现innerHTML的确有这个问题,但是也只是局限于在tbody中不能用innerHTML插入tr或者是不能往inline元素插入block元素,但我的情况并不属于这两种。是网div里面插入div,实在搞不清楚原因,所以也只能另寻办法了。就是使用createElement()生成节点,然后再appendChild()的方式解决ie8下的问题

        if(!eu._$ltIE10()){
              this.__serviceList.innerHTML = str;
         }else{
              e._$clearChildren(this.__serviceList);
              var _nodeList = e._$html2node(str);
              this.__serviceList.appendChild(_nodeList);
        }
    
        //html2node 方法的实现方式:
    
        _e._$html2node = function(_html){
            var _div = document.createElement('div');
            _div.innerHTML = _html;
            var _list = _e._$getChildren(_div);
            return _list.length>1?_div:_list[0];
        };
    

    按照html2node的实现方式,其实ie8是支持innerHTML的,唯一可能不同的就是this.__serviceList 与_div;

    11、ios点击返回按钮取缓存数据时候,如果接口返回的数据的key一样,ios会以为这些数据都是同一份。

    做的一个webView页面时候,使用相同的key(原来只是wish_card,并没有index),不同的课程id去请求数据,然后以相同的key返回数据,
    页面刚加载的时候,数据是正确的,但是随便点击一个课程卡片跳转到详情页,然后再返回的时候页面却使用了同一份数据。

    //初始化课程卡片
          $('.course-box').each(function(index, item) {
              var courseIds = $(item).attr('data-courseIds');
              if(!!courseIds){
                  getCourseData(item, courseIds, index);
              }
          });
    
          function getCourseData (node, courseIds, index) {
             
              var cardInfo = '[{"key":"wish_card' + index + '","secKillFlag":0,"infos":' + courseIds + '}]';
              var _cardInfo = {jsonStr:cardInfo};
              var url ="http://study.163.com/promote2015Q3/getCourseInfos.htm";
    
              jq.post(url, _cardInfo, cbGetCourseData, 'json');
    
              function cbGetCourseData (data) {
                 
                  var options = {
                      showCart: false,
                      showCount: true,
                      showDesc: false,
                      showLector: true,
                      type: 2,
                      gaPrefix:"",
                      data: data['wish_card' + index]
                  };
    
                  $(node).courseCard(options);
              }
          }
    

    返回的数据类型:{"wish_card4":[{"productId":1278001,"productName":"漫画统计å­
    初步判断是ios读取缓存的问题,因为用fiddler抓包,返回的时候并没有重新发出请求。那么因为是取的同一份数据,那么应该会是因为ios判断这些数据都是同一份,
    js代码里面唯一能让ios产生混淆的应该是key的问题了,于是给key加了index,然后就解决了

    13、firefox 与chrome 获取html 文档的方式不一样
    当获取页面的窗口进行页面滚动时,chrome、ie、safari使用的是document.body,而firefox取的是document.documentElement,所以可以选择使用这样的方式解决兼容性问题

     var docBody = document.body || document.documentElement;(可以取window 比如$(window))
    
    //我的奖励明细
    $('#j-myDetail').click(function(){
     //fireFox 中document.body.scrollTop 永远等于0、
    //chrome中document.documentElement.scrollTop 永远为0,
    //但是因为页面刚加载完scrollTop都是0  所以无法使用这个来判断,所以暂时还是判断UA
        var docBody = (ua.indexOf('firefox') != -1) ? document.documentElement : document.body;
                $(docBody).animate({scrollTop: $('.l-m-sharelist').offset().top},200,function(){
                      $('#j-openList').addClass('open');
                      $('#j-dataList').slideDown(10,function(){}).addClass('hasOpen');
                 });
         });
    
    14、服务器端记录的cookie需要带上domain、path才能清掉
    //如果服务器端记录cookie,那么一般都是记在根域名、根目录下、比如study记的cookie
    domain: .study.163.com     path:  /
    
    //那么在专题页面清除cookie的时候,是path不一样,专题的path /topics/sales,所以是删除不了的
    $.removeCookie('inviteFromSpringsales'); 
    
    //改成
    $.removeCookie('inviteFromSpringsales',{path:'/',domain:'study.163.com'});
    
    15、javascript中的深拷贝和浅拷贝

    其实深拷贝与浅拷贝的最终得到的结果都一样的,只是浅拷贝出来的新对象与元对象指向同一个内存地址,改变任何一个都会影响到另一个对象。而深拷贝则是把数据拷贝出来放到新的内存地址,两个对象的数据不会影响

    //浅拷贝:
    var obj1 = {  a:1,  b:{ c:2 }};
    var obj2 = obj1;
    console.log(obj2); //{  a:1,  b:{ c:2 }};
    
    obj2.b.c = 3;
    console.log(obj1) //{  a:1,  b:{ c:3 }};
    //obj1的值也改变了
    
    //深拷贝:
    var obj1 ={a:1,b:{c:2}};
     function deepCopy(_originObj){
      if(_originObj==null)return null;
      if(typeof _originObj !== "object"){
                return _originObj;
            }
            var _clone = {};
      
            if(_originObj.constructor == Array){
                _clone = [];
            }
      
            for(var i in _originObj){  
                _clone[i] = arguments.callee(_originObj[i]);
            }
            return _clone; 
     }
    var obj2 = deepCopy(obj1);
    console.log(obj2); //{a:1,b:{c:2}}
    
    obj2.b.c = 3;
    console.log(obj1); //{a:1,b:{c:2}}
    //obj1并不会被改变
    
    16、使用Object.prototype.toString.call(_data).toLowerCase()=='[object '+_type+']'; 判断一个变量的数据类型

    (1) 在toString方法被调用时,会执行下面的操作步骤:
    (2) 如果this的值为undefined,则返回"[object Undefined]".
    (3) 如果this的值为null,则返回"[object Null]".
    (4) 让O成为调用ToObject(this)的结果.
    (5) 让class成为O的内部属性[[Class]]的值.
    (6) 返回三个字符串"[object ", class, 以及 "]"连接后的新字符串.

        var _isTypeOf = function(_data,_type){
            try{
                _type = _type.toLowerCase();
                if (_data===null) return _type=='null';
                if (_data===undefined) return _type=='undefined';
                return Object.prototype.toString.call(_data).toLowerCase()=='[object '+_type+']';
            }catch(e){
                return !1;
            }
        };
    
    16、文件上传获取判断文件的尺寸大小

    判断文件的width and height 、_URL方法只支持现代浏览器,移动端未测试过,使用的时候会出现一个问题,img.onload方法并不会阻塞js的执行,所以需要使用图片大小判断的后续代码,只能放到onload方法中执行。
    方法一: 只需要获取input:file 框就可以

    try{
        var _URL = window.URL || window.webkitURL,
            img = new Image();
        img.onload = function(){
            console.log(this.width + '*' + this.height);
            if(this.width < 800 || this.height < 300){
                that.errorTips('图片大小不能小于800*300哦');
                uploadPro.__resetFile();
                return false;
            }
            that.filename = _fileName;
            return true;
        }
        img.src = _URL.createObjectURL(this.__realUpload.files[0]);
    }catch(e){
        console.log('can not get image width and height');
    }
    

    方法二: 需要获得图片的url

    var img = new Image();
    img.onload = function(){
        console.log(this.width + '*' + this.height);
        if(this.width < 600 || this.height < 300){
            mUploadErrorTips('图片大小不能小于600*300哦');
            $('#j-selectFile').css({'display':'block'});
            $('.filename').html('');
            $('#j-reselectBox').css({'display':'none'});
            return false;
        }else{
            saveData();
        }
    }
    img.src = _data.originPhotoUrl;
    
    17、一些奇奇怪怪的bug

    (1) 一些情况下对非可点击元素监听click事件,ios下不会触发,css增加cursor:pointer就搞定了。当然想要干脆静止点击就是not-allowed。
    (2) qq浏览,uc浏览以及ios的浏览器,滚动时不会触发scroll事件,但会触发touchmove。当停止滚动后会出发scroll。
    (3) -webkit-tap-highlight-color可以取消点击高亮。
    (4) android4.4以下版本,设置圆角属性需要在直接元素上,向父元素设置圆角并且指定overflow:hidden是不会生效的。

    18、关于微信屏幕支付宝支付的解决方案

    因为考拉那边在微信中可以使用微信支付,经过抓包分析发现,微信屏蔽是根据当前页面的链接来的,当webView页面加载完毕之后,
    (1) 微信发现当前页面的链接如果是阿里的链接,那么就会跳转到另外一个页面。
    (2) 解决方案是在自己的域名下的文件嵌套一个iframe,然后使用iframe加载支付宝的页面就ok了,
    (3) 因为微信app里面监听不到iframe加载完毕的事件,也就无法判断iframe加载的页面。

    主要逻辑:
    在支付页面,前端会把支付物品信息通过form表单通过iframe提交给后端,然后后端把物品的信息编码成一个链接然后redirect到阿里的支付页面,然后在iframe中这个链接会跳转到阿里的支付页面,正常情况下这样就结束了。

    但是为了解决按返回按钮后的复杂操作,所以决定新开一个页面进行提交,所以并不需要后端直接跳转,而是先跳转到一个新的页面并把支付链接回填回来。

    然后前端拿到支付链接之后,把链接赋值到iframe中,那么iframe就会跳转到支付宝的支付页面,就可以了。
    但是前端给siframe的src赋值时,出现了一个refused display page 'http://study.163.com/xxx', because x-frame-sameorigin 的错误,页面显示不出来,
    原因是前端不能手动给iframe设置与父页面相同域名的链接?,所以只好叫后端跳转了。

    payOrder.ftl 提交物品信息给后端

    <form action="/pay/orderRedirectPage.htm" name="payForm" id="payForm">
        <input type="hidden" name="orderUrl" id="toPayUrl"/>
    </form>
    

    后端跳转到 alipayOrder.ftl 并回填支付链接

    <body style="min-height:520px;margin:0;padding:0;background-color:#f5f5f9;">
    <!-- 顶部导航栏 -->
    <div class="g-content" style="min-height:520px;">
       
        <iframe src="" style="min-height:520px;" id="j-alipay" name="alipay" src="" style="border:none;" width="100%" height="100%"></iframe>
        <form action="/pay/mobileAlipay.htm" name="payForm" id="payForm" target="alipay">
            <input type="hidden" name="orderUrl" id="toPayUrl"/>
            <input type="hidden" name="redirectToAlipay" value="true" id="toPayUrl"/>
        </form>
    </div>
    <!-- @NOPARSE -->
    <script>
        <#if orderUrl?exists>window.orderUrl = "${orderUrl?html}";</#if>
        if(!!window.orderUrl){
            document.getElementById('toPayUrl').value = window.orderUrl;
            console.log(window.orderUrl);
            document.forms[0].submit();
        }
    </script>
    <!-- /@NOPARSE -->
    

    alipayOrder.ftl 获取到支付链接再构造一个表单通过iframe提交给后端,然后后端直接进行跳转,那么iframe里面就可以跳转到支付宝支付页面了。

    19、在ios微信浏览器中出现fixed定位低z-index元素覆盖在absolute定位高z-index元素上面

    在微信浏览器中,首先要弹出一个框,点击这个弹框的一个按钮之后,如果保存成功,就会关闭当前弹框,然后再弹出另一个框,然后就出现了cover层覆盖在了弹框上面

    结构以及样式如下
    蒙层样式

    div.m-com-mask {
        z-index: 1000;
        background-color: #3b3b3b;
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        width: 100%;
        height: 100%;
        opacity: 0.75;
        filter: alpha(opacity=75);
    }
    

    弹窗样式

    div.m-winmark {
        position: absolute;
        z-index: 4001;
        top: 886.5px;
        left: 47px;
        border: 1px solid #BABECB;
        background: #ffffff;
        color: #444;
        box-shadow: 0px 3px 14px #aaa;
        -webkit-box-shadow: 0px 3px 14px #aaa;
    }
    

    html结构

    <div class="auto-1464943864173 m-com-mask"> </div>
    <div class="auto-1464943864174 m-basewin" style="top: 886.5px; left: 47px;">
      <div class="zbar" id="auto-id-1464943864232">
          <div class="icon ic4"></div>
          <div class="cnt cntnom">关注成功!</div>
      </div>
      <span class="zcls" title="关闭" id="auto-id-1464943864231">×</span>
    </div>
    

    其实简单的说就是两个兄弟元素A、B,A是fixed定位但是层级z-index低,B是absolute定位但是层级高,按正常情况B是覆盖在A前面的,但是在微信浏览器情况确实A覆盖在B的前面,但是更奇葩的是,就算A覆盖在B的前面了,还是可以点到B的。结果就是以下


    Paste_Image.png

    但是如果点击确认,没有关闭下面的弹框的话,那么是正常的,比如这样

    Paste_Image.png

    同样的操作,同样的弹框,只是是否把底下的弹框remove掉,就会出现这样的问题,所以可能就是下面的弹框remove的问题?尝试使用了transform:translate3d(0, 0, 0)也没解决。后来还是没找到原因,最后因为是在移动端,所以只能暂时也把弹框的定位改成fixed再居中把原有的定位覆盖就没有问题了。

    body div.m-basewin {
        position: fixed!important;
        top: 50%!important;
        transform: translateY(-50%);
        -webkit-transform: translateY(-50%);
        -ms-transform: translateY(-50%);
    }
    
    20、在iphone5s版微信中,flex布局不起作用

    由于flex有新老版本的问题,iphone5没有更新flex的写法,所以还是加上老的写法就解决了

        ul{
            display: -webkit-box;      /* OLD - iOS 6-, Safari 3.1-6 */
             display: -moz-box;         /* OLD - Firefox 19- (buggy but mostly works) */
             display: -ms-flexbox;      /* TWEENER - IE 10 */
             display: -webkit-flex;     /* NEW - Chrome */
            background-color: #f2f4f7;
            height: 100%;
        }
    
        li{
            -webkit-box-flex:1;
            -webkit-flex:1;
            flex: 1;
            text-align: center;
        }
    
    21、使用fs.readFileSync()读取文件,打包之后中文乱码

    使用browserify打包html模板文件,需要用到fs.readFileSync()方法,在编辑器中明确显示是utf-8编码,但是打包后的文件中文乱码。我用的控制台是powerShell,但是使用git bash打包是正常的。原因是控制台的编码跟文件编码不一致导致的。所以只要更改控制台的编码就可以了,解决方法:
    中文编码号(GB2312): 936
    utf8: 65001

    • 运行cmd
    • 输入chcp,查看当前的控制台的编码
    • 输入chcp 65001,回车,控制台的编码就被设置成了utf8的编码
    • 打包之后,中文就不会乱发了

    详细参考

    22、在异步请求回调函数中新打开页面或者提交form表单被浏览器拦截

    在平常需要做的一些操作可能是需要先发一个请求给后端,在返回的结果做判断之后做一些操作,但是最近发现在异步请求回调中打开新窗口或者提交form表单新打开窗口都会被浏览器拦截。因为浏览器会认为这个是不安全的操作(比如广告之类的)。
    解决方法是把异步请求变为同步请求,发请求之后阻断浏览器,回调之后打开窗口,然浏览器认为这两个操作是同一个操作就可以了。或者是异步请求回调之后抛出一个事件,然后结束。在回调外面监听抛出的事件,然后新打开窗口。

    23、使用browserify、gulp打包之后会出现在每个字符之间多了一个NUL

    为了从gulp打包过度到browserify打包方式,先用browserify把js根据依赖来打包出一个js文件。然后使用gulp把打包出来的js与html再打包成一个html文件。打包出来的html文件出现了乱码

    Paste_Image.png

    原因是两次打包用的编码不一样。还是用的powershell,就是设置了utf8编码,好像打包出来的是uft-16 with BOM的,所以经过gulp再次打包之后就会出现这种情况。所以还是找个cmd编码的统一的。比如git bash打包出来就没有问题。

    24、 css3 兼容性写法

    // flex

    ul {
      display: -webkit-box;      /* OLD - iOS 6-, Safari 3.1-6 */
      display: -moz-box;         /* OLD - Firefox 19- (buggy but mostly works) */
      display: -ms-flexbox;      /* TWEENER - IE 10 */
      display: -webkit-flex;     /* NEW - Chrome */
      display: flex;             /* NEW, Spec - Opera 12.1, Firefox 20+ */
     }
    
    li {
      -webkit-box-flex: 1;      /* OLD - iOS 6-, Safari 3.1-6 */
      -moz-box-flex: 1;         /* OLD - Firefox 19- */
      width: 20%;               /* For old syntax, otherwise collapses. */
      -webkit-flex: 1;          /* Chrome */
      -ms-flex: 1;              /* IE 10 */
      flex: 1;                  /* NEW, Spec - Opera 12.1, Firefox 20+ */
    }
    

    // transform

        transform: translate(-50%,-50%);
        -ms-transform: translate(-50%,-50%);
        -webkit-transform: translate(-50%,-50%);
        -o-transform: translate(-50%,-50%);
        -moz-transform: translate(-50%,-50%);
    
    25、css min-width属性不认auto值,且选择器权重无效。

    使用web端的组件,需要覆盖一些样式,在iphone及一些浏览器没有问题,但是在某些安卓手机上,发现尽管权重已经比之前的大,但是不起作用。调试发现,需要覆盖掉的min-width属性的值设置为auto不起作用,查看w3c发现min-width的值没有auto,所以才会出现问题,改为0就好了,选择器权重的问题,不知道什么问题,加!important就好了

    26、解决点击浏览器返回按钮不刷新文件,请求头出现provisional headers are shown问题

    点击浏览器返回按钮之后,浏览器会从缓存里面读取上一个页面的页面数据,如果此时需要实时更新则会出现问题问题,比如前后两次后端在html中不一样的情况,出现这样的情况可以让后端返回html时带上cache-control缓存头,让浏览器点击返回按钮时,强制去服务器请求新的页面。

    以上问题出现常见的现象是request headers出现provisional headers are shown,解释如下

    之所以会出现这个警告,是因为去获取该资源的请求其实并(还)没有真的发生,所以 Header 里显示的是伪
    信息,直到服务器真的有响应返回,这里的 Header 信息才会被更新为真实的。不过这一切也可能不会发生,
    因为该请求可能会被屏蔽。比如说 AdBlock 什么的,当然了不全是浏览器扩展,具体情况具体分析了
    

    当然,如果导致出现provisional headers are shown这个信息的问题有很多,具体参考这篇文章provisional headers are shown

    相关文章

      网友评论

          本文标题:开发bug记录

          本文链接:https://www.haomeiwen.com/subject/ldqldttx.html