<!DOCTYPE html>
<html lang="zh-cmn-Hans">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="IE=edge, chrome=1">
<title>debounce</title>
<style>
#container{
width: 100%; height: 200px; line-height: 200px; text-align: center; color: #fff; background-color: #444; font-size: 30px;
}
</style>
</head>
<body>
<div id="container">
</div>
<!--
防抖的原理是:
你尽管的触发事件,但我一定会再n秒之后执行,就是说触发了事件n秒之后才执行,重复触发的时候会重复计算定时时间
-->
<script type="text/javascript">
var count = 1;
var container = document.getElementById('container');
function getUserAction(e) {
console.log(e);
container.innerHTML = count++;
};
//定义防抖函数
var immediate=true
function ki(getUserAction,may, immediate){
var tiome;
return function(){
var gui=this
var args = arguments;
/*
这个是解决了上面打印是undfind的问题,因为事件函数都是打印自身对象
了解arguments这个对象之前先来认识一下javascript的一些功能:
其实Javascript并没有重载函数的功能,但是Arguments对象能够模拟重载。
Javascrip中每个函数都会有一个Arguments对象实例arguments,它引用着函数的实参,
可以用数组下标的方式"[]"引用arguments的元素。arguments.length为函数实参个数,
arguments.callee引用函数自身。
*/
//重点是这里
console.log(gui)
clearTimeout(tiome)
tiome=setTimeout(
function(){
//修改getUserAction的this指向问题 不然一开始指向的window
getUserAction.apply(gui,args)
},may)
}
}
//onmousemove 事件会在鼠标指针移到指定的对象时发生。
container.onmousemove =ki(getUserAction,100)
</script>
</body>
</html>
上面的防抖是点击了之后n秒才触发执行:
还有一种是立即触发就执行的代码:
f//立即执行版本
function lo(getUserAction,may){
var tiome;
return function(){
var gui=this
var args = arguments;
//如果这个定时器存在,就清除这个定时器
if(tiome) clearTimeout(tiome)
//声明个变量不等于这个不定时器
const callnow=!tiome
tiome=setTimeout(()={
//这个是再定时器之后执行,然后重新让tiome为null
tiome=null
},may)
//因为js是单线程的,所以会先执行下面的if 最后执行定时器 所有此时是立即执行的,等定时完毕之后再执行函数
//这里是重新判断 是否此时不是这个定时器 不是就开始打印执行 然后再重新定时
if(callnow) getUserAction.apply(gui,args)
}
}
总结:
1.首先防抖只是减少了触发事件的次数,不管用户如何点击 ,,再规定的事件内 都直执行一次
2.内部的this指向问题
3.内部函数打印自身e为undfined的问题
4.arguments对象能够执行函数重载 也就是函数对象本身,可以用作来获取this
其实Javascript并没有重载函数的功能,但是Arguments对象能够模拟重载。
Javascrip中每个函数都会有一个Arguments对象实例arguments,它引用着函数的实参,
可以用数组下标的方式"[]"引用arguments的元素。arguments.length为函数实参个数,
arguments.callee引用函数自身。