1. 程式人生 > 實用技巧 >Js實現防抖和節流

Js實現防抖和節流

函式節流和防抖的實現      

   防抖和節流的作用都是防止函式多次呼叫。

   區別在於,假設一個使用者一直觸發這個函式,且每次觸發函式的間隔小於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> letnum = 1; letcontent = document.getElementById('content'); functioncount() { content.innerHTML = num++; }; //非立即執行版---觸發事件後函式不會立即執行,而是在 n 秒後執行,如果在 n 秒內又觸發了事件,則會重新計算函式執行時間。 functiondebounce(func, wait) { lettimeout; returnfunction() { letcontext =this; letargs = 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> letnum = 1; letcontent = document.getElementById('content'); functioncount() { content.innerHTML = num++; }; //時間戳版--- functionthrottle(func, wait) { letprevious = 0; returnfunction() { letnow = Date.now(); letcontext =this; letargs = 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秒內只會執行一次,所以節流會稀釋函式的執行頻率