JS防抖和节流

JS防抖和节流

  • 防抖 (debounce 弟棒死):指触发事件后在n秒内函数只执行一次,若在n秒内再次触发则重新计算
    常见应用:搜索、下拉触底加载下一页

  • 节流 (throttle 死rua头):连续发生的事件在n秒内只执行一次

防抖

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<style>
		#content{
			width: 500px;height: 150px;
			background-color: beige;
			color: #484848;
			text-align: center;
			font-size: 60px;
			font-weight: 600;
			line-height: 150px;
		}
	</style>
	<body>
		<input id="search" type="text" oninput="count()"/>
		<div id="content"></div>
		<script>
			let num = 1;
			let content = document.getElementById("content");
			function count(){
				content.innerHTML=num++;
			}
                        //触发完毕过两秒执行,重新触发,时间重新计算
			function debounce(func,wait){
				let timeout;
				return function(){
					if(timeout) {
						clearTimeout(timeout)
					}
					timeout = setTimeout(function(){
						func.apply(this);
					},wait)					
				}
			}
			content.onmousemove = debounce(count,2000);
			// content.onmousemove = count;
		</script>
	</body>
</html>
防抖方式2
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<style>
		#content{
			width: 500px;height: 150px;
			background-color: beige;
			color: #484848;
			text-align: center;
			font-size: 60px;
			font-weight: 600;
			line-height: 150px;
		}
	</style>
	<body>
		<input id="search" type="text" oninput="count()"/>
		<div id="content"></div>
		<script>
			let num = 1;
			let content = document.getElementById("content");
			function count(){
				content.innerHTML=num++;
			}
			//触发完毕立即执行,过1秒才能再次执行,但1秒内只能执行1次,1秒后再次触发仍只执行一次就要再等1秒
			function debounce(func,wait){
				let timeout;
				return function(){				
					if(timeout) clearTimeout(timeout)				
					let callNow = !timeout; 
					//类型转换,第一次执行没有timeout定时器,timeout为false,!timeout=true,callNow为true
					timeout = setTimeout(()=>{
						timeout = null;//清空当前定时器句柄
					},wait)	
					if(callNow) func.apply(this);//第一次执行
				}
			}
			content.onmousemove = debounce(count,1000);
		</script>
	</body>
</html>

节流

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<style>
		#content{
			width: 500px;height: 150px;
			background-color: beige;
			color: #484848;
			text-align: center;
			font-size: 60px;
			font-weight: 600;
			line-height: 150px;
		}
	</style>
	<body>
		<input id="search" type="text" oninput="count()"/>
		<div id="content"></div>
		<script>
			let num = 1;
			let content = document.getElementById("content");
			function count(){
				content.innerHTML=num++;
			}
                        //如果一直触发,每隔1秒执行一次					
			function throttle(func,wait){
				let timeout;
				return function(){
					if(!timeout){
						timeout = setTimeout(()=>{
							timeout = null;  //清空定时器句柄
							func.apply(this); //执行count
						},wait)
					}
				}				
			}
			content.onmousemove = throttle(count,1000);
		</script>
	</body>
</html>

节流方式2(比方式1更加节省性能)
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<style>
		#content{
			width: 500px;height: 150px;
			background-color: beige;
			color: #484848;
			text-align: center;
			font-size: 60px;
			font-weight: 600;
			line-height: 150px;
		}
	</style>
	<body>
		<input id="search" type="text" oninput="count()"/>
		<div id="content"></div>
		<script>
			let num = 1;
			let content = document.getElementById("content");
			function count(){
				content.innerHTML=num++;
			}
			//通过时间戳方式								
			function throttle(func,wait){
				let prev = 0; //上次记录的时间
				return function(){
					let now = Date.now(); //当前时间
					if(now-prev > wait){ //当前时间-上次时间>等待时间
						func.apply(this);  //执行函数,发送请求
						prev = now;  //重置上次记录时间
					}
				}
			}
			content.onmousemove = throttle(count,1000);
		</script>
	</body>
</html>

posted @ 2020-08-02 11:15  Daeeman  阅读(126)  评论(0编辑  收藏  举报