前端开发的一些问题之防抖与节流
2018-11-19 11:40
471 查看
博客转载自:https://www.geek-share.com/detail/2723522120.html
前端开发中我们经常会通过监听某些事件来完成项目需求
1.通过监听 scroll 事件,检测滚动位置,根据滚动位置显示返回顶部按钮
2.通过监听 resize 事件,对某些自适应页面调整DOM的渲染(通过CSS实现的自适应不再此范围内)
3.通过监听 keyup 事件,监听文字输入并调用接口进行模糊匹配
…
下面我们用常用的scroll事件来看下具体情况
我们先来触发一个scroll事件
window.onscroll = function () { //滚动条位置 let scrollTop = document.body.scrollTop || document.documentElement.scrollTop; console.log('滚动条位置:' + scrollTop); }
下面是演示结果
从效果上,我们可以看到,在页面滚动的时候,会在短时间内触发多次绑定事件。
我们知道DOM操作是很耗费性能的,如果在监听中,做了一些DOM操作,那无疑会给浏览器造成大量性能损失。
下面我们进入主题,一起来探究,如何对此进行优化。
看完这个实例大概我们应该有一点点理解,下面我们具体看看什么是防抖和节流
防抖:
通俗理解就是:延时处理,然后如果在这段延时内又触发了事件,则重新开始延时。
原理:对处理函数进行延时操作,若设定的延时到来之前,再次触发事件,则清除上一次的延时操作定时器,重新定时。
防抖实例:
let timer; window.onscroll = function () { if(timer){ clearTimeout(timer) } timer = setTimeout(function () { //滚动条位置 let scrollTop = document.body.scrollTop || document.documentElement.scrollTop; console.log('滚动条位置:' + scrollTop); timer = undefined; },200) }
实例效果:
函数封装:
/** * 防抖函数 * @param method 事件触发的操作 * @param delay 多少毫秒内连续触发事件,不会执行 * @returns {Function} */ function debounce(method,delay) { let timer = null; return function () { let self = this, args = arguments; timer && clearTimeout(timer); timer = setTimeout(function () { method.apply(self,args); },delay); } } window.onscroll = debounce(function () { let scrollTop = document.body.scrollTop || document.documentElement.scrollTop; console.log('滚动条位置:' + scrollTop); },200)
节流:
定义:触发函数事件后,短时间间隔内无法连续调用,只有上一次函数执行后,过了规定的时间间隔,才能进行下一次的函数调用。
原理:对处理函数进行延时操作,若设定的延时到来之前,再次触发事件,则清除上一次的延时操作定时器,重新定时。
代码实现:
let startTime = Date.now(); //开始时间 let time = 500; //间隔时间 let timer; window.onscroll = function throttle(){ let currentTime = Date.now(); if(currentTime - startTime >= time){ let scrollTop = document.body.scrollTop || document.documentElement.scrollTop; console.log('滚动条位置:' + scrollTop); startTime = currentTime; }else{ clearTimeout(timer); timer = setTimeout(function () { throttle() }, 50); } }
实例效果:每隔500毫秒触发一次事件
函数封装:
/** * 节流函数 * @param method 事件触发的操作 * @param mustRunDelay 间隔多少毫秒需要触发一次事件 */ function throttle(method, mustRunDelay) { let timer, args = arguments, start; return function loop() { let self = this; let now = Date.now(); if(!start){ start = now; } if(timer){ clearTimeout(timer); } if(now - start >= mustRunDelay){ method.apply(self, args); start = now; }else { timer = setTimeout(function () { loop.apply(self, args); }, 50); } } } window.onscroll = throttle(function () { let scrollTop = document.body.scrollTop || document.documentElement.scrollTop; console.log('滚动条位置:' + scrollTop); },800)阅读更多
相关文章推荐
- 关于自由流功能开发过程中前端的一些问题汇总
- web前端开发在IE7下的一些问题汇总
- 前端开发遇到的一些小问题
- web大前端开发中一些常见的安全性问题
- APP前端开发时应注意的一些问题
- 前端webview开发中遇到的一些问题及其解决方法
- 前端开发跨域问题,
- 前端开发中,浏览器相关细节问题
- IOS开发的一些技巧和常见问题
- WEB前端开发人员须知的常见浏览器兼容问题及解决技巧
- 新手前端开发基础小问题
- 前端开发常见的面试问题
- hadoop开发环境搭建时出现的一些问题
- 用友NC二次开发一些经验以及处理的问题
- camera开发中遇到的一些问题, 备忘
- mono开发asp.net mvc 中的一些问题
- 安卓开发中关于软键盘处理的一些问题
- 做网页前端遇到的一些问题
- ffmpeg开发中的问题(十二) 一些小点
- JAVA开发中的一些浏览器兼容问题