JavaScript节流函数
1.节流函数的通常使用场景?
(1).频繁调整浏览器窗口大小(resize事件)
(2).浏览器页面滚动事件(scroll事件)
(3).鼠标移动(mousemove事件)
(4).input和textarea输入(change事件)
(5)touchmove事件
也就是说,如果用户在浏览器页面中进行操作,而脚本中绑定了某些事件,这些事件会不停的触发
如果不限定触发次数,有可能会导致浏览器卡死或者崩溃,同时也会造成流量的浪费,手机端表现特别明显。
2.场景实例
拿resize事件写一个简单的节流函数:
let count = 0; function test() { console.log(count++); } let timer = null; window.onresize = function () { clearTimeout(timer); timer = setTimeout(() => { test(); }, 200); };上面的代码就是一个简单的节流函数,但是存在不足。比如,timer变量是在全局作用域中,如果全局变量中存在其他场景的timer,这样就会造成冲突,因此,我们把这个节流函数封装一个闭包,如下:
let count = 0; function test() { console.log(count++); } let throttle = function(fn, delay) { let timer = null; return function() { clearTimeout(timer); timer = setTimeout(() => { fn(); }, delay); } }; window.onresize = function() { throttle(test, 1000)(); };优化之后的代码是上面这个样子,那么这段代码运行起来性能不能达到我们的预期吗?经过在浏览器中运行发现,在1000毫秒内程序确实是延迟执行了,但是执行后反馈来的结果却是一堆的连续数据,这说明优化的还不行。我们继续改进。
let count = 0; function test() { console.log(count++); } let throttle = function(fn, delay, step) { let timer = null; let prev = null; return function() { let now = + new Date(); if (timer) { clearTimeout(timer); } if (!prev) { prev = now; } if (now - prev >= step) { fn(); prev = now; } else { timer = setTimeout(() => { fn(); }, delay); } } }; let resize = throttle(test, 1000, 1000); window.onresize = function() { resize(); };
上面是改动之后的代码,经测试发现,throttle方法必须要先初始化一次,然后在执行。上面我们初始化的方法是resize;
然后,在window的onresize方法中执行resize这个方法,效果达到预期!
3.总结
节流函数在合适的场景下适当运用,可以提高用户体验,减少流量的浪费;节流函数在初期编辑的时候,如果是新手,可能不能一步写完整,因此,当运用节流方法的时候利用浏览器调试,逐步优化自己的代码。
如果你觉的本文写的还可以,请点个赞!同时,欢迎留言谈论!谢谢!