jQuery EasyUI 1.3.6版panel面板加载bug

来源:互联网 发布:sql注入漏洞危害 编辑:程序博客网 时间:2024/06/07 20:37
       最近接手一个项目,由于是个老系统,没有用bootstrap实现布局,采用的jQuery EasyUI。在实际开发中发现了panel面板的一个大bug,出现跟API文档描述不一致的情况。

按照1.3.6版本的API中文文档,使用panel:
$('#p').panel({    
    href:'content_url.php',    
    onLoad:function(){    
        alert('loaded successfully');    
    }    
});  

       上面的代码放到了菜单导航触发事件代码内部,结果当点击其它链接后,再次点击某链接,出现id为p的节点面板会不断叠加,也就是说后面的面板不断叠加在了当前面板的前面,只是没有显示出来,它们都在id值为p的节点内部。这样界面显示是没有异常的,但面板内部节点绑定的事件就可能出现问题了。例如面板中存在id为uploadClick的按钮,绑定的上传事件就会被多次触发。

       我把它理解为panel函数加载面板时没有查看是否有缓存,于是找到文档,查看有没有相关属性的设置,找到这样一条信息:


       于是加上该属性,并设置其值为true或false查看是否有不同效果,结果显示效果没有变化,确定该属性值其实是无效的!
       这是从效果来看,不够,继续从源码分析,看其逻辑。通过cache关键字查找,料想必定在if判断语句中,才是最终其真正发挥价值的地方。于是找到这个函数的代码:
function _1b5(_1b6){var _1b7=$.data(_1b6,"panel");var opts=_1b7.options;if(opts.href){if(!_1b7.isLoaded||!opts.cache){_1b7.isLoaded=false;_1b8(_1b6);if(opts.loadingMessage){$(_1b6).html($("<div class=\"panel-loading\"></div>").html(opts.loadingMessage));}$.ajax({url:opts.href,cache:false,dataType:"html",success:function(data){_1b9(opts.extractor.call(_1b6,data));opts.onLoad.apply(_1b6,arguments);_1b7.isLoaded=true;}});}}else{if(opts.content){if(!_1b7.isLoaded){_1b8(_1b6);_1b9(opts.content);_1b7.isLoaded=true;}}}function _1b9(_1ba){$(_1b6).html(_1ba);if($.parser){$.parser.parse($(_1b6));}};};

       现在知道,jQuery Easy UI真正起加载面板的代码,是上面第11行的ajax函数。于是,我在这个ajax函数前面加了个alert(1),调试代码发现每次都有弹出,也就是确实如前所述,不管cache属性值为true或false,都加载了面板。也就是说!_1b7.isLoaded||!opts.cache始终为true。将alert(_1b7.isLoaded)放到紧随该判断语句后,得知_1b7.isLoaded的值始终为false。

       由上面代买第2行得知_1b7取决于_1b6形参。于是继续查找_1b5函数的调用,以查找_1b6形参的值是否被设置死了为false。(后面不贴源代码,排版太乱太杂,感兴趣的自己查找下)于是看到两个函数调用了_1b5函数,它们是_1be和_1ce。在往调用层上查找,有个_1b0调用了_1ce,参数为this,_1be没有上一层了,也是传参this。因为在调用过层中,未重新赋值,也就是说最根本的_1b7.isLoaded就是this.isLoaded。

       至此,我们只要确定this的isLoaded属性的赋值情况就可以了,查找isLoaded关键字,发现只有一条直接跟this关联的函数:
return jq.each(function(){
$.data(this,"panel").isLoaded=false;
if(href){
$.data(this,"panel").options.href=href;
}
_1b5(this);
}
       至此,谜团解开,this.isLoaded的值一直都为false,而且即便不赋值,默认也为false,所以印证了上面那句话,_1b6形参的值确实是被设置死了为false,加载panel面板跟ceche的属性值无关,所以确定1.3.6版存在bug。

       那么怎么解决这个问题,其实反而简单了,就是在调用panel方法前面,去掉重复面板就可以了,例如$(".window").remove();当然你也可以下载最新版,至于最新版有没有这个问题,我初步测试了一下,有,还是去掉重复面板吧,也就一句代码而已。虽然现在不流行用jQuery Easy UI了,但老项目不好大改动,另外这样也可以培养解决问题,追根溯源的思维。
原创粉丝点击