触发高频事件后n秒内函数只会执行一次,若是n秒内高频事件再次被触发,则从新计算时间
var time = null; document.onmousewheel = function(e){ if (time) { clearTimeout(time) } time = setTimeout( () => { /* 进行滚动操做 */ time = null }, 100) } # 第一次滑动时 time 是null ,直接执行 setTimeout ,在 0.1s 内若是又继续滑动了滚轮, # 就会清除上一次的 setTimeout ,直到在 0.1s 内没有滑动滚轮,就会执行 setTimeout 中 # 的内容。
高频事件触发,但在n秒内只会执行一次,因此节流会稀释函数的执行频率
下面是js代码,这种方式有点很差理解闭包
function throttle() { let canRun = true; // 经过闭包保存一个标记 return function () { console.log(canRun) if (!canRun) return; // 在函数开头判断标记是否为true,不为true则return canRun = false; // 当即设置为false setTimeout(() => { // 将外部传入的函数的执行放在setTimeout中 // 最后在setTimeout执行完毕后再把标记设置为true(关键)表示能够执行下一次循环了。 // 当定时器没有执行的时候标记永远是false,在开头被return掉 console.log(1) canRun = true; }, 1000); }; } window.addEventListener('resize', throttle()); # 当函数被注册的时候,定义了 canRun 为 true,以后返回一个函数, # 每当事件被触发的时候,执行返回的函数中的内容。首先判断 canRun, # 若是为 true 就往下执行,而后设 canRun 为 false,执行定时器, # 在接下来的 1s 内,若是再次触发 resize 事件,canRun 的值是 false , # 会直接 return 空,不会执行任何操做。当 1s 后执行了定时器中的 # 内容并设置 canRun 为 true 后,触发事件才会从新执行定时器。 ***注意*** 1. 在添加事件的时候,后面的函数是加()的。正由于这个括号,因此在注册 事件的时候,let canRun = true 会被执行一次,而在事件被触发的时候, let canRun = true 是不会被执行的,只有在被注册时会被执行一次。 2. 触发事件之后,执行的是 throttle 函数返回的函数,而不是 throttle 函数。
这两种方式的区别:第一种是当 0.1s 内再次触发事件,会消除定时器,从新计算,适用于滚轮滚动后页面的切换。由于用户滚轮切换页面时,一次会滚动不少下;第二种是若是事件一直在触发,可是每 1s 会执行一次。函数