<!DOCTYPE html>
<html>
<head>
<title>Throttle</title>
</head>
<body>
<script type="text/javascript">
var count = 0;
var resizehandler = function () {
console.log(new Date().getTime());
console.log(count++);
}
var throttle = function (method, context){
clearTimeout(method.tId);
method.tId = setTimeout(function(){
method.call(context);
}, 100);
}
window.onresize = function(){
throttle(resizehandler, window);
};
</script>
</body>
</html>
我的疑问是为什么我在一直拖的情况下,一直没有打印出第一次出现的结果。
因为按照我的理解,执行到setTimeout()以后,应该在0.1秒后打印内容,但是一直拖就没结果,想知道为什么。
因为你一直在
resize
. 此时你原来设定的事件处理器被clearTimeout()
掉了,在连续的resize
事件 (两次之间的间隔 < 100ms) 只有最后一次绑定的事件处理程序被调用。设想 window 发生一次
resize
事件时,你在事件处理器中使用setTimeout()
添加了一个将于 100ms 后调用的resizeHandler()
函数,并且把这个 timeout 的 ID 存储在resizeHandler.tId
里面。但是在 20ms 后, window 又发生了一次resize
事件,此时首先clearTimeout()
被调用,之前添加的resizeHandler()
函数将不会得到执行。所以对于连续发生的
resize
事件,我们可以得出什么结论呢? —只有当一次resize
与下一次之间的时间间隔大于 100ms 时,这个resizeHandler()
才会得到调用。这也就是你说的:今天早上在 CNBlogs 看到一个 throttle 实现 (http://www.cnblogs.com/dolphinX/p/3403821.html) 可以解决你所碰到的问题:
(个人理解) 则在两次事件间隔时间大于
delay
时,或者事件发生时距离上一次重置begin
不低于duration
, 则method
均能得到调用,其中,在后一种情况下,会把begin
重置为事件发生的时刻。调用该函数:
除此之外,我也用 jQuery 写了一个 至多每隔一段时间 调用的 throttle 扩展:
(关于
jQuery.fn.one
, 详见 http://api.jquery.com/one/)调用:
这样就可以在连续 resize 的情况下每 0.1s 打印输出内容,而在不 resize 的情况下则不输出任何内容。
以上。
(有用请支持/采纳。)
一直拖就一直 clearTimeout 了,所以不打印了