jQuery EasyUI1.4版本已经出来有些日子了,因为组件体系动作较大,也产生了不少Bug,不过1.4.1版本一直迟迟不出,本篇文章记录一下1.4版本layout组件很严重的一个Bug(其实内部是因为parser,panel,layout三个组件共同作用形成的)。
我们知道layout依赖panel组件,每个layout实例由一个或者多个region组成,每个region其实就是一个panel实例。而panel组件有个resize事件,我们将这个事件可以写在region对应DOM的data-options里面,也可以在layout实例化之后,调用panel组件构造函数重新构造一下需要绑定resize事件的region。
不过在实际使用中,我发现了一个很大的问题:如果在IE6-IE8下,layout的实例就是对应BODY标签的话,我所绑定的resize组件,将会被无限次重复不停地调用,很容易撑爆内存。
经过一整天的分析,发现根源是:IE6-IE8环境下,window对象的onresize事件,不光是在用户调整浏览器窗口大小的时候会被触发,即便是代码里面设置body高度的时候,该事件同样会被触发!
这种额外的触发方式,恰恰使对应于body的layout实例在处理自适应布局的时候构成了事件间调用的闭环,简而言之就是:一个动作触发了一个resize事件处理器,而这个resize事件处理器内部又执行了一个可以触发该事件处理器的动作,也就构成了无限循环。
详细的分析过程,我就不介绍了,说实话太绕了,不知道要费多少口舌才能说清楚。只将最后个人认为比较安全的处理方案给出来。
最后,layout和panel组件均不需要改动代码,需要更改代码的组件是parser组件,而且只是加一个条件限制,我们拿1.4版本的"src/jquery.parser.js"来改,看到247-248行:
- t._size('min'+p1, '');
- t._size('max'+p1, '');
- t._size(p, v);
给这几个设置大小的语句加上一个条件就可以了,改为:
- if(target.tagName == 'BODY' && t[p]()==v){
- //如果layout实例的宿主DOM是body,且高度和宽度没有发生变化,则不用重新设置大小
- }else{
- t._size('min'+p1, '');
- t._size('max'+p1, '');
- t._size(p, v);
- });
如果哪位同学有更好的解决方案,可以留言告之。好了,本篇文章就到此为止,又一天过去了……
注:这个Bug在1.4.1版本中已经修正,使用的方式,跟本文不太一样。
管理员 世纪之光 : 2015年04月03日09:20:15 地下1层