JavaScript的防抖与节流

前言

在前端开发的过程中,我们经常会需要绑定一些持续触发事件,如窗口的resize、scroll,输入框内容校验等等,如果事件处理函数调用的频率无限制,会加重浏览器的负担,导致用户体验非常糟糕,这时候就要用到防抖(debounce)和节流(throttle),减少调用频率的同时又不影响实际效果。

函数防抖(debounce)

当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。

简单来说就是,任务频繁触发的情况下,只有任务触发的间隔超过指定间隔的时候,任务才会执行。

防抖函数分为非立即执行版和立即执行版。

函数防抖实现

1、非立即执行版

<input type="text" placeholder="防抖非立即执行" id="debounceInput1">

<script>
	function debounce1(func, wait) {
		let timeout;
	    return function () {
	    	let context = this;
	        let args = arguments;
	        if (timeout) clearTimeout(timeout);
	        timeout = setTimeout(() => {
	        	func.apply(context, args)
	        }, wait);
	    }
	}
	
	//监听input的输入事件
  	$('#debounceInput1').on('input propertychange',debounce1(function(){
      	console.log($(this).val(),new Date())
  	},1000));
</script>

2、立即执行版

<input type="text" placeholder="防抖立即执行" id="debounceInput2">

<script>
	function debounce2(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)
    	}
	}
	
	//监听input的输入事件
  	$('#debounceInput2').on('input propertychange',debounce2(function(){
      	console.log($(this).val(),new Date())
  	},1000));
</script>

函数防抖应用场景

1、搜索框输入查询,若用户一直在输入中,没有必要不停的去请求服务端接口,设置一个合适的时间间隔,能有效减轻服务端压力。
2、按钮提交事件,防止短时间内重复提交。
3、浏览器窗口resize事件,不断调整浏览器窗口大小时会触发这个事件,利用防抖来让其触发一次重新计算布局。

函数节流(throttle)

当持续触发事件时,保证一定事件段内只调用一次事件处理函数。

简单来说就是,连续触发事件但在n秒中只执行一次函数,节流会稀释函数的执行频率。

节流函数有两种实现方法,时间戳和定时器。

函数节流实现

1、时间戳

<button id="btn1">点击(时间戳)</button>

<script>
	function throttle1(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;
        	}
    	}
	}
	$('#btn1').on('click',throttle1(function(){
    	console.log("时间戳",new Date())
  	},1000));
</script>

2、定时器

<button id="btn2">点击(定时器)</button>

<script>
	function throttle2(func, wait) {
    	let timeout;
    	return function() {
        	let context = this;
        	let args = arguments;
        	if (!timeout) {
            	timeout = setTimeout(() => {
                	timeout = null;
                	func.apply(context, args)
            	}, wait)
        	}
    	}
	}
	$('#btn2').on('click',throttle2(function(){
    	console.log("定时器",new Date())
  	},1000));
</script>

函数节流应用场景

1、鼠标不断触发mousedown或者mouseover事件的时候,可以利用节流在单位时间内只触发一次。
2、监听滚动事(onScoll),比如是否滑到底部加载更多数据,用节流来判断。
3、按钮点击事件。

区别

函数防抖:事件高频触发后,间隔 n 秒执行一次。
函数节流:事件高频触发中,每 n 秒执行一次。

节流函数的回调执行时机是在高频触发中,而防抖函数的回调函数执行时机是在高频触发后。

注意: 函数防抖和函数节流只是减少了事件回调函数的执行次数,并不会减少事件的触发频率。

发布了17 篇原创文章 · 获赞 0 · 访问量 180

猜你喜欢

转载自blog.csdn.net/hy_ethel/article/details/103812550