做有态度的前端团队

网易FEG前端团队

简单梳理下最近项目遇到的某些bug或者事件不支持情况,和解决方法。

1、JQ监听输入框value值改变事件(propertychange),浏览器之间的差异。

a:js赋值给输入框时,google浏览器不触发propertychange,IE可以触发,所以这里处理下

解决:加下判断浏览器,js赋值不触发时,使用trigger("propertychange")触发

js代码:

$('.dj input').bind('input propertychange', function() {
    if(val > 70){
        alert("最大值是70,不能超过最大值");
        $(this).val("70");
        if(!document.all){
            $(this).trigger("propertychange"); //js赋值时,google浏览器不触发propertychange,IE可以触发,所以这里处理下
        }           
    return;  
  }     
  pageCom.changeDG();

});
b:IE与google,对value改变触发事件(在下面情况)的差别。google浏览器触发一次,IE浏览器触发两次。

下面输入框显示情况,当选中数字后,然后数字键盘输入"5",google浏览器当做value值只改变一次(更改值7500);而IE浏览器当做改变两次,第一次改变的数值是700,第二次是7500。猜想是浏览器机制的不同的原因,导致的问题
20160429_1.png

在下面具体PC项目情况下(如下图),我的处理方式
20140429_2.jpg

html 代码简化如下:

<!--动态数据显示html代码 -->
<dl class="cls">
    <dt><img src="" alt="" /></dt><!--图片icon -->
    <!-- 这里是属性列表-->               
</dl>

未发现IE请求多次时的处理,JS代码简化如下:

/* 技能切换与输入框值改变时,都触发该方法:changeJineng( params ) ,重新写入数据  */

var getBackData = function( params ){ // /params为多个参数
    $.ajax({
            async:false,
            url:url,
            dataType:'jsonp',
            data:{
                'func':'dh_zuoqi',
                'a1':a1, //坐骑等级value
                'a2':a2, //坐骑成长率value
                'a3':a3,  //熟练度value
                'a4':a4,  //属性值
                'type':type //高低技能类型等区分
            },
            success:function(result){
                var val = result.data //获取返回数值
                /*...其他代码此处省略...*/

                $obj.find("dt").children("img").attr({"src":imgSrc}); /*更换技能图标icon*/

                $obj.append('<dd><i class="'+iconType+'"></i>'+txtL+'<font class="red">'+val+'</font>'+txtR+'</dd>') ; /*填入内容*/

        }
    });
}

var changeJineng = function( params ){ //params为多个参数 

    /*...其他代码此处省略...*/

     /**切换技能时清掉老数据
    /**当触发两次的情况下,此处有bug,(以上截图为例)第一次更改值为700,第二次更改值为7500,两个几乎同时触发,当两次都执行到这里时,已经完成清除上一步数据的操作,但第一次请求的数据还没来得及写入页面,所以结果,两个请求的处理结果都写入页面了,重复了,IE浏览器就是这个情况
**/
    $("dl").find("dd").remove();

     /* $sx 为一技能属性列表。数据从json格式数据取(技能列表、图标icon、属性与属性值、属性描述文案),每个技能有多个属性,每条属性都要请求一次接口,获取返回的数值*/
    for(var i=0; i<$sx.length; i++){

        /*..其他代码此处省略..*/

        /*getBackData方法接口请求处理 */
        getBackData( params ); //params为多个参数

    }
}

解决数据重复问题(猜想是浏览器机制的原因,暂时不能解决多次请求,只能改其他方法避免显示重复数据):

方法:初始化(或切换)属性列表时,给不同属性节点加上class值(或ID值),当输入框值更改时,只需根据class查找对应的属性,进行值的更改就可以,即使多次触发,更改的东西也是对应上同一个属性

js代码:

var getBackData = function( params, boolean ){ // /params为多个参数,多加布尔boolean参数,判断是切换技能触发,还是更改输入框值触发
    $.ajax({
            async:false,
            url:url,
            dataType:'jsonp',
            data:{
                'func':'dh_zuoqi',
                'a1':a1, //坐骑等级value
                'a2':a2, //坐骑成长率value
                'a3':a3,  //熟练度value
                'a4':a4,  //属性值
                'type':type //高低技能类型等区分
            },
            success:function(result){
                var val = result.data //获取返回数值
                /*...其他代码此处省略...*/

                $obj.find("dt").children("img").attr({"src":imgSrc}); /*更换技能图标icon*/

                if(( boolean ){/*当切换技能时处理*/
                    $obj.append('<dd class="'+sxid+'"><i class="'+iconType+'"></i>'+txtL+'<font class="red">'+val+'</font>'+txtR+'</dd>') ; /*填入内容*/
                }else{/*当输入框值更改时处理,只需根据class查找对应的属性,进行更改值就可以*/
                    $obj.find("."+sxid).find(".red").html(val);  //即使多次触发,更改后的值也是最新一次触发后处理的值
                }
            }
    })
}

var changeJineng = function( params ,boolean ){ //params为多个参数 ,多加布尔boolean参数,判断是切换技能触发,还是更改输入框值触发
    /*...其他代码此处省略...*/

    /**切换技能时清掉老数据
    $("dl").find("dd").remove();

    /* $sx 为一技能属性列表。数据从json格式数据取(技能列表、图标icon、属性与属性值、属性描述文案),每个技能有多个属性,每条属性都要请求一次接口,获取返回的数值*/
    for(var i=0; i<$sx.length; i++){

    /*..其他代码此处省略..*/

    /*getBackData方法接口请求处理 */
    getBackData( params , boolean ); //params为多个参数,多加布尔boolean参数,判断是切换技能触发,还是更改输入框值触发

    }
}

2、移动端长按事件(touchstart,touchend),长按时,在松开后,不执行touchend方法的bug

处理方法:在touchstart方法里边,后面添加这句代码:e.preventDefault();

js代码如下:

    var caTime;
    $(".add").on({
        touchstart:function(e){
            caTime = setInterval(function(){
                pageCom.addNum($(e.target));
            },100);
            e.preventDefault();//关键代码
            return false;           
        },
        touchend: function(e){            
            if(caTime){
                clearInterval(caTime);
            }
            pageCom.changeSld($(e.target));
            return false; 
        }
    });

手机阅读请扫描下方二维码: