JavaScript 节流
2023-03-27 10:00:04
157

文章封面

节流(throttle)

概念

当多个事件在规定时间内多次触发,回调函数最终只会执行一次

场景

  1. 监听页面的滚动事件
  2. 鼠标移动事件
  3. window resize事件

基本实现

<body>
	<input data-id="9527" type="text" />
	<button id="cancel">取消</button>
</body>
<script>
	const inputEl = document.querySelector("input");
	const btn = document.getElementById("cancel");

	function throttle(fn, delay) {
		let timer;
		let isInvoke = false;
		return function() {
			if (!timer) {
				timer = setTimeout(() => {
					fn.apply(this, arguments);
					timer = undefined;
				}, delay);
			}
		};
	}

	let counter = 0;
	const inputChange = function(event) {
		console.log(`发送了 ${++counter} 次网络请求`, event);
	};

	// 输入框的input事件
	inputEl.oninput = throttle(inputChange, 1000);
</script>

首次立即执行

<body>
	<input data-id="9527" type="text" />
	<button id="cancel">取消</button>
</body>
<script>
	const inputEl = document.querySelector("input");
	const btn = document.getElementById("cancel");

	function throttle(fn, delay, immediate = false) {
		let timer;
		let isInvoke = false;
		return function() {
			if (immediate && !isInvoke) {
				fn.apply(this, arguments);
				isInvoke = true;
			}
			if (!timer) {
				timer = setTimeout(() => {
					fn.apply(this, arguments);
					timer = undefined;
				}, delay);
			}
		};
	}


	let counter = 0;
	const inputChange = function(event) {
		console.log(`发送了 ${++counter} 次网络请求`, event);
	};

	// 输入框的input事件
	inputEl.oninput = throttle(inputChange, 1000, true);
</script>

取消执行

<body>
	<input data-id="9527" type="text" />
	<button id="cancel">取消</button>
</body>
<script>
	const inputEl = document.querySelector("input");
	const btn = document.getElementById("cancel");

	function throttle(fn, delay, immediate = false) {
		let timer;
		let isInvoke = false;
		const _throttle = function() {
			if (immediate && !isInvoke) {
				fn.apply(this, arguments);
				isInvoke = true;
			}
			if (!timer) {
				timer = setTimeout(() => {
					fn.apply(this, arguments);
					timer = undefined;
				}, delay);
			}
		};
		_throttle.cancel = function() {
			clearTimeout(timer)
			timer = null;
		}
		return _throttle;
	}

	let counter = 0;
	const inputChange = function(event) {
		console.log(`发送了 ${++counter} 次网络请求`, event);
	};
	const _throttle = throttle(inputChange, 1000, true)

	// 输入框的input事件
	inputEl.oninput = _throttle

	// 取消按钮的点击事件
	btn.onclick = function() {
		_throttle.cancel()
	}
</script>
如有帮助,点赞鼓励一下吧!
评论
一键登录