mootools fade方法的一个小陷阱
用mootools做项目的过程中发现了mootools fade方法一个比较隐秘的问题. 我们先来还原一下问题出现的场景:
<div id="main1">
test1
</div>
<button id="fade1">fade1</button>
$('fade1').addEvent('click', function() {
$('main1').set('tween', {
duration: 300,
onComplete: function(el) {
el.destroy();
}
}).fade('out');
});
我们可以简单的给div#main1一个背景以做观察,注意到onComplete回调方法中的el.destroy(), 以实现div#main1淡出后销毁, 这样写在IE9+,和其他主流浏览器中没有任何问题,但是在IE8及之前版本就会出现报错.定位在fade方法中
if (method == 'set' || to != 0) this.setStyle('visibility', to == 0 ? 'hidden' : 'visible');
else fade.chain(function(){
this.element.setStyle('visibility','hidden');
});
以上是代码的一段引用,问题就出在this.element不支持setStyle方法. 而且注意到这个方法通过fade.chain加入到调用链中. 至于调用这个方法出错了,应该就是onComplete调用在此方法前了, 考虑到mootools对DOM操作扩展的方式在低版本的IE和其他主流浏览器的不同, el.destroy()的提前调用对元素的扩展进行了清理,以便垃圾回收, 所以轮到其调用setStyle时,就报“不支持此方法”的错误了.
接下来看如何修正这个问题, 其实销毁的目的已经实现了,元素都没了,hidden不hidden显得没意义.问题是有个报错,用户体验就会打折扣.
再去看源代码,直接看Fx类中哪里fire了complete回调就行,下面是一段代码的引用,来自Fx的stop方法:
stop: function(){
if (this.isRunning()){
this.time = null;
pullInstance.call(this, this.options.fps);
if (this.frames == this.frame){
this.fireEvent('complete', this.subject);
if (!this.callChain()) this.fireEvent('chainComplete', this.subject);
} else {
this.fireEvent('stop', this.subject);
}
}
return this;
},
看if(this.frames == this.frame)这个if分支,就知道答案了,this.callChain()调用的就是上面fade.chain(..)中的方法,在此之前一句就是fire了complete回调事件,传入的参数this.subject就是onComplete中得el. 所以只要把销毁的操作放到chainComplete回调中就可以了.
<div id="main2">
test2
</div>
<button id="fade2">fade2</button>
$('fade2').addEvent('click', function() {
$('main2').set('tween', {
duration: 300,
onChainComplete: function(el) {
el.destroy();
}
}).fade('out');
});
这样问题就解决了...

浙公网安备 33010602011771号