<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="text" id="search">
<script>
//https://www.jianshu.com/p/c8b86b09daf0
// 目的:尽量在用户输入完之后,才发送一次http请求,减少服务器压力
// 1.每次输入使用定时器延迟发送请求
// 2.使用闭包保存定时器id,每次输入,如果旧定时器没有执行就清除旧定时器,设置新的定时器
// 3.那么当用户不输入一段delay时间时就可以只发送一次请求。
function debounce(fn, delay) {
let timer = null;
//返回一个闭包函数
return function (e) {
//e事件对象 之所可以接收e
//判断当前输入是否有定时器
if (timer) {
//有计时器,那么阻止之前的计时器执行
clearTimeout(timer);
console.log('清除之前的定时器', timer);
}
//保存settimeout
//使用箭头函数,将this指向由window对象变为input节点对象
timer = setTimeout(() => {
console.log();
//因为在settimeout的函数体内所以使用call可以立刻执行,当然也可以用bind,但是要手动执行
//call和apply的传参不一样 这里e是一个对象,且fn只结束欧一个参数使用call。当然也可以使用argument类数组对象
fn.call(this, e);
//首先fn是由window调用的,如果不使用箭头函数的this是无法指向input节点对象,
//这里的this由闭包函数给予,同时闭包函数被input节点的事件监听调用
//正常执行了,清除保存的定时器ID
timer = null;
}, delay)
}
}
let inputNode = document.querySelector('#search');
inputNode.addEventListener('input', debounce(function (event) {
// console.log(this === inputNode);//判断是否已经指向了节点 true
console.log(`发送${this.value}到请求`);
//访问element的构造函数的原型属性value
console.log(`用户最后输入的字符为${event.data}`);
// console.log(event);
}, 1000))
</script>
</body>
</html>
上一篇

2021-05-20
下一篇

2021-05-18