一、函数防抖
定义:事件在n秒后触发,不管在这个时间节点中执行多少次事件,只有最后一次事件是触发
对比场景:游戏中的回城 DNF中的抬枪
使用场景:
- 上拉刷新,下来加载--scroll事件- resize- 文本的输入验证(连续输入文字后发送Ajax请求进行验证,验证一次就够了)
1-1 原生JavaScript-button实现防抖
<body><!-- 什么叫函数防抖:事件n秒后触发,不管在这个时间段中执行多少次事件,该事件只针对最后一次触发 --><button id="btn">函数防抖</button><script>var btn = document.getElementById("btn");var timer;btn.onclick = function(){if(timer){clearTimeout(timer);}timer = setTimeout(()=>{console.log("loading");timer = null},500)}/*3s*/</script></body>
1-2 input实现防抖
<body><input type="text" id="input"><script>var input = document.getElementById("input");var timer;input.addEventListener("keyup",()=>{if(timer){clearTimeout(timer);}timer = setTimeout(()=>{console.log(input.value)timer = null;},1000)})</script></body>
1-3 封装防抖
<body><input type="text" id="input"><script>var input = document.getElementById("input");var timer/* 封装防抖函数 */function debounce(fn,delay=500){if(timer){clearTimeout(timer);}timer = setTimeout(fn,delay)}input.addEventListener("keyup",()=>{debounce(()=>{console.log(input.value);})})</script></body>
1-4 闭包封装防抖
<body><input type="text" id="input"><script>var input = document.getElementById("input");input.addEventListener("keyup",debounce(()=>{console.log(input.value);}))/* 闭包 1、返回值是一个函数 2、返回函数使用返回函数外面定义的局部变量闭包好处:不会造成全局的污染*/function debounce(fn,delay=500){let timer = null;return function(){if(timer){clearTimeout(timer);}timer = setTimeout(fn,delay);}}</script></body>
.1-5 apply改变this
<body><input type="text" id="input"><script>var input = document.getElementById("input");input.addEventListener("keyup",debounce(function(){console.log(this.value)}))/* 闭包 1、返回值是一个函数 2、返回函数使用返回函数外面定义的局部变量闭包好处:不会造成全局的污染*/function debounce(fn,delay=500){let timer = null;return function(){console.log(this)if(timer){clearTimeout(timer);}timer = setTimeout(()=>{console.log(this)fn.call(this);},delay);}}/* function才能使用call,apply */</script></body>
二、函数节流
2-1 原生JavaScript-button实现节流
单位时间之内,只触发一次,如果在这个单位时间之内多次触发,最终也只会执行一次
使用场景
1、射击游戏中的鼠标事件2、input输入框搜索联想
<style>#app{width: 100px;height: 100px;border: 1px solid #333;}</style></head><body><div id="app" draggable="true">可拖拽</div><script>/* 单位时间之内,只触发一次,如果在这个单位时间之内多次触发,最终也只会执行一次 *//*1、射击游戏中的鼠标事件2、input输入框搜索联想*/let timer = null;const app = document.getElementById("app");app.addEventListener("drag",function(e){if(timer){return}timer = setTimeout(()=>{console.log(e.offsetX,e.offsetY);timer = null},1000)})</script></body>
2-2 封装节流函数
<style>#app{width: 100px;height: 100px;border: 1px solid #333;}</style></head><body><div id="app" draggable="true">可拖拽</div><script>const app = document.getElementById("app");app.addEventListener("drag",throttle(function(e){console.log(e.offsetX,e.offsetY);}))function throttle(fn,delay=500){let timer = null;return function(){if(timer){return}timer = setTimeout(()=>{/* arguments是函数内部的一个对象,接收函数传递过来的参数 */console.log(arguments);fn.apply(this,arguments)timer = null},delay)}}</script>
