当类似用户改变浏览器窗口大小的事件,有可能会连续触发多次。有的页面需要做到联动处理,在多次触发中可能会卡死,尤其是在性能低下的IE上若每次触发都执行一些图形渲染更是个大问题。
以下代码就解决了这个问题。绑定了window的resize事件,但是每次触发后会延迟500毫秒,给每次触发这个事件进行了tag标识,只处理连续触发后的最后一次的触发行为。
$(function(){ var tag = 0; var coverChartWidth = function(t){ if(t != tag){return;} var w = $(document).width() || 0; if(w < 1150){ $('#chartTable').width(1150); } }; $(window).bind('resize',function(){ tag++; (function(t){ setTimeout(function(){ coverChartWidth(t); },500); })(tag); }); });
用tag标识的方法确实太麻烦了,借鉴网友的更好的方法代码如下:
//可进一步扩展为支持可传参的fn var onFooEndFunc = function(fn) { var delay = 50; // 根据实际情况可调整延时时间 var executionTimer; return function() { if (!!executionTimer) { clearTimeout(executionTimer); } //这里延时执行你的函数 executionTimer = setTimeout(function() { //alert('123'); fn(); }, delay); }; };
在使用的时候直接调用这个 onFooEndFunc 函数,把你需要的处理函数传进去即可。
下面以document.onmousemove为例,自己试试运行的效果,使用延时处理前,移动鼠标,会发现事件触发非常频繁,使用延时处理后,移动鼠标,事件就没那么频繁了。
测试代码:(在线测试:http://pgkk.github.io/testDelayEvent.html)
<html>
<head>
<script type="text/javascript">
var count = 0;
var myfn = function() {
document.getElementById("TextArea1").value = "Executed " + (++count) + " times.";
}
var normalevent = function() {
count = 0;
document.getElementById("TextArea1").value = "Executed 0 times.";
document.onmousemove = myfn;
};
var endevent = function() {
count = 0;
document.getElementById("TextArea1").value = "Executed 0 times.";
document.onmousemove = onFooEndFunc(myfn);
};
</script>
</head>
<body>
<input id="normal" value="恢复正常" οnclick="normalevent()" type="button" />
<input id="end" value="使用延时" οnclick="endevent();" type="button" />
<textarea id="TextArea1" style="height: 40px; width: 200px; color: #ff0000; clip: rect(auto, auto, auto, auto);"></textarea>
</body>
</html>
上面只是以 document.onmousemove为例,还有很多其他DOM事件存在相同问题,例如onScroll, onMouseMove, onResize,同理,都可以用这个方法来解决,具体还可以看这里的例子,方法本质上都是一样的。