手撕源码系列(防抖)

119 阅读1分钟

定义:防抖,多次事件触发被判定为一次。(可以选择第一次触发or最后一次)

思路: 1.设置fn函数。
2.设置debounce(函数):多次fn函数触发 判定为 一次fn函数
3.body的点击事件绑定debounce函数

  • 源码
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<button type="button" id="btn1">购物车+1</button>
	</body>
</html>
<script type="text/javascript">
	function func(){
		console.log('OK')
	};
	
	function debounce(func,wait=500,immediate = false){
		let timer =null;
		return function anonymous(...params){
			let now = immediate && ! timer;
			clearTimeout(timer);
			now? func.call(this, ...params):null,
			timer = setTimeout(()=>{
				timer = null;
				!immediate?func.call(this, ...params):null
			},wait);
		}
	};
	
	btn1.onclick = debounce(func,500,true);
</script>

详解

	function func(){
		console.log('OK')
	};
	
	function debounce(func,wait=500,immediate = false){
		'// func是想要执行的函数;wait为间隔的时间;immediate为是否判定立即触发,true为立即触发,false为最后一次触发。'
		let timer =null;
		'//初始化timer'
		return function anonymous(...params){
			let now = immediate && ! timer;
			'//now为立即执行的含义;初始化时候tiemer为null,!null为true.当多次点击的时候,timer不再是null了。那么!timer就是false。
			//now用来作为判定是否为立即触发与最后触发。'
			clearTimeout(timer);
			'//当多次触发的时候,每触发一次就会清除掉定时器,那么之前的定时器里的函数就被清理掉。然后下面会新增定时器函数的'
			now? func.call(this, ...params):null,
			'//now=true;立即执行'
			timer = setTimeout(()=>{
				timer = null;
				'//当定时器定时到了之后,开始执行内部的函数。然后timer为null。这样以后再触发的话,就能正常执行了。'
				!immediate?func.call(this, ...params):null
			},wait);
			
		}
	};
	
	btn1.onclick = debounce(func,500,true);
	'//给按钮加点击事件
	//点击触发debounce函数。多次点击,不断触发匿名函数。'