JavaScript节流函数Throttle详解.doc.pdf

上传人:tbuqq 文档编号:5616058 上传时间:2020-07-02 格式:PDF 页数:6 大小:209.92KB
返回 下载 相关 举报
JavaScript节流函数Throttle详解.doc.pdf_第1页
第1页 / 共6页
JavaScript节流函数Throttle详解.doc.pdf_第2页
第2页 / 共6页
JavaScript节流函数Throttle详解.doc.pdf_第3页
第3页 / 共6页
JavaScript节流函数Throttle详解.doc.pdf_第4页
第4页 / 共6页
JavaScript节流函数Throttle详解.doc.pdf_第5页
第5页 / 共6页
点击查看更多>>
资源描述

《JavaScript节流函数Throttle详解.doc.pdf》由会员分享,可在线阅读,更多相关《JavaScript节流函数Throttle详解.doc.pdf(6页珍藏版)》请在三一文库上搜索。

1、在浏览器 DOM 事件里面,有一些事件会随着用户的操作不间断触发。比如:重新调整浏览器窗 口大小 (resize),浏览器页面滚动 ( scroll),鼠标移动 ( mousemove) 。也就是说用户在触发这些浏览器 操作的时候,如果脚木里面绑定了对应的事件处理方法,这个方法就不停的触发。 这并不是我们想要的,因为有的时候如果事件处理方法比较庞人,DOM 操作比如复杂,还不断 的触发此类事件就会造成性能上的损失,导致用户体验下降( UI 反映慢、浏览器卡死等) 。所以 通帘来讲我们会给相应事件添加延迟执行的逻辑。 通常來说我们用卜 ?面的代码來实现这个功能: var COUNT = 0; f

2、unction testFn() console.log(COUNT+); / 浏览器resize的时候 / 1.清除之前的计时器 / 2.添加一个计时器让真正的函数testFn延后100毫秒触发 window.onresize = function () var timer = null; clearTimeout(timer); timer = setTimeout(function() testFn(); , 100); ; 细心的同学会发现上面的代码其实是错课的,这是新手会犯的一个问题:setTimeout函数返I 川 值应该保存在一个相对全局变最里面,否则每次resize的时候都会产

3、生一个新的计时器, 这样就 达不到我们发的效果了 于是我们修改了代码: var timer = null ; window.onresize = function () clearTimeout(timer); timer = setTimeout(function() testFn(); , 100); ; 这时候代码就正常了,但是又多了一个新问题 产生了一个全局变量timerc 这是我们不想 见到的,如果这个页面述有別的功能也叫timer 不同的代码 Z 前就是产生冲突。为了解决这个问 题我们要用 JavaScript的一个语言特性:闭包closures o相关知识读者可以去MDN 中了解

4、,改造 后的代码如下: / * * *函数节流方法 *param Function fn 延时调用函数 *param Number delay延迟多长时间 *return Function 延迟执行的方法 */ var throttle = function (fn # delay) var timer = null; return function () clearTimeout(timer); timer = setTimeout(function() fn(); / delay); ; window?onresize = throttle(testFn, 200, 1000); 我们用一

5、个闭包函数 ( throttle 节流) 把 timer 放在内部并返回延时处理函数,这样以来timer 变量 对外是不可见的,但是内部延时函数触发时还可以访问到timer 变量。 当然这种写法对于新手來说不好理解,我们口J以变换一种写法來理解一下: var throttle = function (fn # delay) var timer = null ; return function () clearTimeout(timer); timer = setTimeout(function() fn(); / delay); ; var f = throttle(testFn, 200);

6、 window.onresize = function () f 0 ; ; 这里主要了解一点: Throttle 被调用后返回的function 才是真正的 onresize触发时需要调用的函 数 现在看起來这个方法已经接近完美了,然而实际使用中并非如此。举个例子: 如果用户不断的resize浏览器窗口大小,这时延迟处理函数一次都不会执行 于是我们又要添加一个功能:当用户触发resize的时候应该在某段时间内至少触发一次, 既然是 在某段时间内,那么这个判断条件就可以取当前的时间毫秒数,每次函数调川把当前的时间和 上一次调用时间和减,然后判断差值如果大于某段时间就直接触发,否则还是走time

7、out的延迟 逻辑。 下面的代码里面需要指出的是: 1.previous变量的作用和 timer 类似,都是记录上一次的标识,必须是相对的全局变量 2.如果逻辑流程走的是“至少触发一次“的逻辑,那么函数调用完成需要把previous 重置成 当询吋间,简单來说就是:相对于下一次的上一次其实就是当前 / *函数节流方法 *param Function fn 延时调川函数 *param Number delay延迟多长时间 *param Number atleast至少多长时间触发一次 *return Function延迟执彳亍的方法 */ var throttle = function (fn

8、# delay, atleast) var timer = null; var previous = null ; return function () var now = +new Date (); if ( !previous ) previous = now; if ( now - previous atleast ) fn(); / 重置上一次开始时间为木次结束时间 previous = now; else clearTimeout(timer); timer = setTimeout(function() fn(); / delay); ; 实践: 我们模拟一个窗口scroll 时节

9、流的场景,也就是说当用户滚动页面向下的时候我们需要节 流执行一些方法,比如:计算DOM 位置等需要连续操作DOM 元素的动作 完整代码如下: throttle var COUNT = 0, demo = document.getElementByld(demo ); function testFn () demo.innerHTML += 1 testFN 被调用了 + +COUNT + 次vbr *; var throttle = function (fn, delay, atleast) var timer = null ; var previous = null; return func

10、tion () var now = +new Date (); if ( !previous ) previous = now; if ( atleast ; window.onscroll = throttle(testFn, 200); / window.onscroll = throttle(testFn, 500, 1000); 我们用两个 case来测试效果,分别是添加至少触发atlcast参数和不添加 : / case 1 window.onscroll = throttle(testFn, 200); / case 2 window?onscroll = throttle(testFn, 200, 500); easel 的表现为:在页而滚动的过程(不能停止)中testFN不会被调用,直到停止的吋候会调用 一次,也就是说执行的是throttle 里面最后一个 setTimeout ,效果如图(查看原gif 图): case 2 的表现为:在页面滚动的过程(不能停止)中testFN第一次会延迟 500ms执行(来 自至 少延迟逻辑),后來至少每隔500ms执行一次,效果如图至此为止,我们想要实现的效果已经 基本完成。后续的一些辅助性优化读者可以口己琢磨, 如:函数 this指向, 返回值保存等。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1