今天在做项目的时候,遇到了这样一个问题:我现在做的东西和地图相关,地图上有各种标记,鼠标移动到每个标记会有一个浮动框显示此标记的经度、纬度等等各种信息,移出这个标记则浮动框会消失。由于标记太多,移动到特定标记的过程中就会碰到其它标记,导致很多浮动框出现一下然后消失,很影响用户体验。怎么解决呢?防抖!我想你应该能听懂我上面说的意思吧,可以查看百度百科页面中个人中心那一行,快速的在首页、分类等之间滑动,是不会展开菜单的。既然有了防抖,就顺便也说一下节流吧。
节流
节流,顾名思义,开源节流。就是省,省啥?省性能,减少消耗呗。我就举个例子啊,比如onscroll、onresize这些事件,你要是在这些事件里面执行某些方法,那么这些方法将执行多次,因为你在滑动或者变化窗体大小的过程中还会继续出发这些事件的。我想只执行一次,咋办?看代码:
var i = 0;
function handler() {
console.log(i++);
}
window.onscroll = function() {
clearTimeout(handler.id)
handler.id = setTimeout(function(){
handler();
},1000)
}
在函数第一次执行时,设置一个定时器,以后继续执行时删除前面的定时器,在生成一个新的。这样就会只执行一次了,节流吧:)
这种还可以用于淘宝这样的秒杀活动,你不管点击多少次都只执行一次,或者在规定的时间内只能执行多少次。
防抖
防抖,更加形象,防止你手一抖触发不必要的事件(怎么想到了这么一句话:随着身体一阵颤抖,一切都变得索然无味==! )。用途甚多,就比如我上面那个例子,必须在我移到标记上面一秒钟之后才出现浮动框,滑动经过的标记不该出现浮动框。还有联想输入提示,在输入停止后在进行加载数据等。偷懒了一下,就用了上面节流的代码,稍微改造了一下:
var num = window.pageYOffset;
function handler() {
console.log(window.pageYOffset);
num = window.pageYOffset;
}
window.onscroll = function() {
clearTimeout(handler.id);
handler.id = setTimeout(function(){
if(window.pageYOffset != num) {
handler();
} else {
clearTimeout(handler.id);
}
},1000)
}
这段代码其实是防抖与节流的结合。其实移动一下其实滚动条会触发多次滚动事件的,所以节流了一下。对于这段代码,将滚动条从顶部移动一下,再移动回来,一秒之后判断是否和原来的一样,一样就不输出,不一样就会输出一次。
最后
节流与防抖的区别在于节流至少会执行一次,防抖会在等待一个时间间隔后判断,若重新触发事件了则删除原来的定时器重新计算。