浅析前端函数防抖与节流

在前端开发的过程中,我们经常会遇到持续触发的事件,如resize、scroll、mousemove等等,但是我们并不想在执行的时候频繁的去触发相应事件,此时函数防抖节流可以很好的解决。

所谓防抖,是指触发事件后在n秒内函数只能执行一次,如果在n秒内又触发了事件,则会重新计算函数执行时间。

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

非立即执行版:

function debounce (func, wait) {
	var timeout;
	return function () {
		var context = this;
		var args = arguments;
		if (timeout) clearTimeout(timeout);
		timeout = setTimeout (function () {
			func.apply(context, args);
		}, wait);
	}
}
立即执行版:
function debounce (func, wait) {
	var timeout;
	return function () {
		var context = this;
		var args = arguments;
		if (timeout) clearTimeout(timeout);
		var runNow = !timeout;
		timeout = setTimeout(function () {
			timeout = null;
		}, wait);
		if (runNow) func.apply(context, args);
	}
}

综合版:

/**
 * @desc 函数防抖
 * @param func 函数
 * @param wait 延迟执行毫秒数
 * @param immediate true 表立即执行,false 表非立即执行
 */
function debounce (func, wait, immediate) {
	var timeout;
	return function () {
		var context = this;
		var args = arguments;
		if (timeout) clearTimeout(timeout);
		if (immediate) {
			var runNow = !timeout;
			timeout = setTimeout(function () {
				timeout = null;
			}, wait);
			if (runNow) func.apply(context, args);
		} else {
			timeout = setTimeout(function () {
				func.apply(context, args);
			}, wait);
		}
	}
}
所谓节流,就是指连续触发事件但是在n秒中只执行一次函数

函数节流分为时间戳版与定时器版。

时间戳版:

function throttle (func, wait) {
	var previous = 0;
	return function () {
		var now = Date.now();
		var context = this;
		var args = arguments;
		if (now - previous > wait) {
			func.apply(context, args);
			previous = now;
		}
	}
}

定时器版:

function throttle (func, wait) {
	var timeout;
	return function () {
		var context = this;
		var args= arguments;
		if (!timeout) {
			timeout = setTimeout (function () {
				timeout = null;
				func.apply(context, args);
			}, wait);
		}
	}
}

上述两个版本的区别是时间戳版的函数执行是在时间段开始的时候,而定时器版的函数执行是咋时间段结束的时候。

综合版:

/**
 * @desc 函数节流
 * @param func 函数
 * @param wait 延迟执行毫秒数
 * @param type 1 表时间戳版,2 表定时器版
 */

function throttle (func, wait, type) {
	if (type === 1) {
		var previous = 0;
	}else if (type === 2) {
		var timeout;
	}
	return function () {
		var rcontext = this;
		var args = arguments;
		if (type === 1) {
			var now = Date.now();
			if (now - previous > wait) {
				func.apply(context, args);
				previous = now;
			}
		} else if (type === 2) {
			if (!timeout) {
				timeout = setTimeout(function () {
					timeout = null;
					func.apply(context, args);
				}, wait);
			}
		}
	}
}

 

你可能感兴趣的:(前端)