函数节流和防抖的实现
防抖和节流的作用都是防止函数多次调用。
区别在于,假设一个用户一直触发这个函数,且每次触发函数的间隔小于wait,防抖的情况下只会调用一次,而节流的 情况会每隔一定时间(参数wait)调用函数。
1.防抖实现:每次触发事件时都取消之前的延时调用方法
//<div id="content" style="height:150px;line-height:150px;text-align:center; color: #fff;background-color:#ccc;font-size:80px;"></div> <script> let num = 1; let content = document.getElementById('content'); function count() { content.innerHTML = num++; }; //非立即执行版---触发事件后函数不会立即执行,而是在 n 秒后执行,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。 function debounce(func, wait) { let timeout; return function() { let context = this; let args = arguments; if (timeout) clearTimeout(timeout); timeout = setTimeout(() => { func.apply(context, args) }, wait); } } //立即执行版 ---触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数的效果。 // function debounce(func,wait) { // let timeout; // return function () { // let context = this; // let args = arguments; // if (timeout) clearTimeout(timeout); // let callNow = !timeout; // timeout = setTimeout(() => { // timeout = null; // }, wait) // if (callNow) func.apply(context, args) // } // } content.onmousemove = debounce(count, 1000); </script>
2.节流实现:每次触发事件时都判断当前是否有等待执行的延时函数
//<div id="content" style="height:150px;line-height:150px;text-align:center; color: #fff;background-color:#ccc;font-size:80px;"></div> <script> let num = 1; let content = document.getElementById('content'); function count() { content.innerHTML = num++; }; //时间戳版--- function throttle(func, wait) { let previous = 0; return function() { let now = Date.now(); let context = this; let args = arguments; if (now - previous > wait) { func.apply(context, args); previous = now; } } } // //定时器版 // function throttle(func, wait) { // let timeout; // return function() { // let context = this; // let args = arguments; // if (!timeout) { // timeout = setTimeout(() => { // timeout = null; // func.apply(context, args) // }, wait) // } // } // } content.onmousemove = throttle(count, 1000); </script>
高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率
函数节流和防抖的实现
防抖和节流的作用都是防止函数多次调用。
区别在于,假设一个用户一直触发这个函数,且每次触发函数的间隔小于wait,防抖的情况下只会调用一次,而节流的 情况会每隔一定时间(参数wait)调用函数。
1.防抖实现:每次触发事件时都取消之前的延时调用方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
//<div id="content" style="height:150px;line-height:150px;text-align:center; color: #fff;background-color:#ccc;font-size:80px;"></div> <script> let num = 1; let content = document.getElementById( 'content' ); function count() { content.innerHTML = num++; }; //非立即执行版---触发事件后函数不会立即执行,而是在 n 秒后执行,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。 function debounce(func, wait) { let timeout; return function () { let context = this ; let args = arguments; if (timeout) clearTimeout(timeout); timeout = setTimeout(() => { func.apply(context, args) }, wait); } } //立即执行版 ---触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数的效果。 // function debounce(func,wait) { // let timeout; // return function () { // let context = this; // let args = arguments; // if (timeout) clearTimeout(timeout); // let callNow = !timeout; // timeout = setTimeout(() => { // timeout = null; // }, wait) // if (callNow) func.apply(context, args) // } // } content.onmousemove = debounce(count, 1000); </script> |
2.节流实现:每次触发事件时都判断当前是否有等待执行的延时函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
//<div id="content" style="height:150px;line-height:150px;text-align:center; color: #fff;background-color:#ccc;font-size:80px;"></div> <script> let num = 1; let content = document.getElementById( 'content' ); function count() { content.innerHTML = num++; }; //时间戳版--- function throttle(func, wait) { let previous = 0; return function () { let now = Date.now(); let context = this ; let args = arguments; if (now - previous > wait) { func.apply(context, args); previous = now; } } } // //定时器版 // function throttle(func, wait) { // let timeout; // return function() { // let context = this; // let args = arguments; // if (!timeout) { // timeout = setTimeout(() => { // timeout = null; // func.apply(context, args) // }, wait) // } // } // } content.onmousemove = throttle(count, 1000); </script> |
高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率