扫码关注官方订阅号
Throttle
我的疑问是为什么我在一直拖的情况下,一直没有打印出第一次出现的结果。
因为按照我的理解,执行到setTimeout()以后,应该在0.1秒后打印内容,但是一直拖就没结果,想知道为什么。
认证高级PHP讲师
因为你一直在 resize. 此时你原来设定的事件处理器被 clearTimeout() 掉了,在连续的 resize 事件 (两次之间的间隔 < 100ms) 只有最后一次绑定的事件处理程序被调用。
resize
clearTimeout()
设想 window 发生一次 resize 事件时,你在事件处理器中使用 setTimeout() 添加了一个将于 100ms 后调用的 resizeHandler() 函数,并且把这个 timeout 的 ID 存储在 resizeHandler.tId 里面。但是在 20ms 后, window 又发生了一次 resize 事件,此时首先 clearTimeout() 被调用,之前添加的 resizeHandler() 函数将不会得到执行。
setTimeout()
resizeHandler()
resizeHandler.tId
所以对于连续发生的 resize 事件,我们可以得出什么结论呢? —只有当一次 resize 与下一次之间的时间间隔大于 100ms 时,这个 resizeHandler() 才会得到调用。这也就是你说的:
今天早上在 CNBlogs 看到一个 throttle 实现 (http://www.cnblogs.com/dolphinX/p/3403821.html) 可以解决你所碰到的问题:
function throttle(method, delay, duration) { var timer = null, begin = new Date(); return function () { var context = this, args = arguments, current = new Date(); clearTimeout(timer); if (current - begin >= duration) { method.apply(context, args); begin = current; } else { timer = setTimeout(function () { method.apply(context, args); }, delay); } }; }
(个人理解) 则在两次事件间隔时间大于 delay 时,或者事件发生时距离上一次重置 begin 不低于 duration, 则 method 均能得到调用,其中,在后一种情况下,会把 begin 重置为事件发生的时刻。
delay
begin
duration
method
调用该函数:
window.onresize = throttle(resizehandler, 100, 200);
除此之外,我也用 jQuery 写了一个 至多每隔一段时间 调用的 throttle 扩展:
(function ($) { if (!$) { return; } $.fn.throttle = function (eventName, f, dur) { /// <param name="eventName" type="String"/> /// <param name="f" type="Function"/> /// <param name="dur" type="Number"/> dur = dur || 400; var that = this, g = function () { setTimeout(function () { that.each(f).one(eventName, g); }, dur); }; that.one(eventName, g); return that; } })(window.jQuery);
(关于 jQuery.fn.one, 详见 http://api.jquery.com/one/)
jQuery.fn.one
调用:
$(window).throttle("resize", resizeHandler, 100);
这样就可以在连续 resize 的情况下每 0.1s 打印输出内容,而在不 resize 的情况下则不输出任何内容。
以上。 (有用请支持/采纳。)
一直拖就一直 clearTimeout 了,所以不打印了
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
因为你一直在
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 了,所以不打印了