最近在做项目的过程中遇到了一个问题,就是鼠标在移动太快的时候不会触发mouseleave,会导致之前mouseenter显示的内容一直显示,最终在网上看到节流函数(throttle)就试了一下,完美解决,这里跟大家分享一下。具体什么是节流函数(throttle),网上有一大推的文章,这里就只简单的给大家介绍一下:
1.定义
规定在一个单位时间内,只能触发一次函数,如果这个单位时间内触发多次函数,只有一次生效; 典型的案例就是鼠标不断点击触发,规定在n秒内多次点击只有一次生效。
2.实现原理
其原理是用时间戳来判断是否已到回调该执行时间,记录上次执行的时间戳,然后每次触发 scroll 事件执行回调,回调中判断当前时间戳距离上次执行时间戳的间隔是否已经到达 规定时间段,如果是,则执行,并更新上次执行的时间戳
主要适用于
resize、scroll、mousemove等事件触发监听,比如我这里的mouseleave也可以用
我这个项目是用vue写的,下面直接上代码,简单粗暴,必要的地方我会有注释:
html部分:
<template>
<div @mouseenter="showList" @mouseleave="hideList">
</template>
js部分:
<script>
export default {
data () {
return {
count: 0,
hideList: () => {}
}
},
created () {
this.hideList = this.fnThrottle(this.hideListThrottle, 100);
},
methods: {
hideListThrottle() {
this.listShow = false; // 这里是我的代码内容,换成自己的代码即可
},
/**
******这里是节流函数******
* @param {Function} fn 延时调用函数
* @param {Number} delay 延迟多长时间
* @param {Number} atleast 至少多长时间触发一次
* @return {Function} 延迟执行的方法
*/
fnThrottle (fn, delay, atleast) {
let timer = null;
let previous = null;
return function () {
let now = +new Date();
if (!previous) previous = now;
if (atleast && now - previous > atleast) {
fn();
previous = now;
clearTimeout(timer)
} else {
clearTimeout(timer);
timer = setTimeout(function () {
fn();
previous = null
}, delay)
}
}
},
}
</script>
【注意】要把hideList函数放到data属性中,然后在created生命周期给hideList赋值,不然的话会执行多次你的那个函数(即我这里的hideListThrottle)。