在有些情况我们也许会碰到如下场景,监听一个input框的输入事件,但是大多数情况下,我们不是为了监听用户输了什么,而是想知道用户输到什么时候结束了,所以如果实时监听键盘事件,在每次用户敲击键盘的时候去触发一个函数,这样就多了非常多无用的操作,比如window.resize事件
//在你的控制台输入以下代码
window.onresize = ()=> {
console.info('onresize');
};
可以看到 如果我们简单的变化浏览器的大小,控制台会一直打印,这并不是我们需要的,我们往往只需要知道,用户在哪里停下就可以了
function throttle(method,context){
clearTimeout(method.timer)
method.timer = setTimeout(function(){
method.call(context)
},500)
}
代码意思很明显,这个方法接受你想防抖的函数以及他的上下文,然后在500ms延时之后执行这个函数,若下一次函数在500ms内调用则清除上个定时器然后在延迟500ms执行,函数防抖有效的防止了一个函数被多次调用,比如onresize,onmouseover和上述的键盘监听事件
再来试试
function fun(){
console.log('onresize')
}
function throttle(method,context){
clearTimeout(method.timer);
method.timer=setTimeout(function(){
method.call(context);
},500);
}
window.onresize = ()=>throttle(fun,window)
把这段代码拷进你的控制台然后在试试,是不是好多了
相比于防抖,节流就是在让函数在特定的时间内只执行一次
// 函数节流
var canRun = true;
document.getElementById("throttle").onscroll = function(){
if(!canRun){
return
}
canRun = false
setTimeout( function () {
console.log("函数节流")
canRun = true
}, 500)
}
用一个flag让该函数在500ms内只执行一次
他们都是可以防止一个函数被无意义的高频率调用
区别在于:
事件委托就是利用事件冒泡机制指定一个事件处理程序,来管理某一类型的所有事件。
即:利用冒泡的原理,把事件加到父级上,触发执行效果。
**好处:
例子:ul中触发每个li来改变他们的背景颜色
'ul'>
- 111111
- 222222
- 333333
window.onload = function(){
let oUl = document.getElementById('ul');
let aLi = oUl.getElementsByTagName('li');
let but = document.getElementById('button');
let now = 3;
// 事件源:event对象,不管在哪个事件中,只要你操作的哪个元素就是事件源
// ie:window.event.srcElement
// 标准:event.target
oUl.onmouseover = function(e){
let ev = e || window.event;
let target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase() == 'li'){
target.style.background = 'red';
}
}
oUl.onmouseout = function(e){
let ev = e || window.event;
let target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase() == 'li'){
target.style.background = '';
}
}
but.onclick = function(){
now ++;
let newLi = document.createElement('li');
newLi.innerHTML = 111111 * now;
oUl.appendChild(newLi);
}
}
另外:由于在$(document).ready()方法内注册的事件,只要DOM就绪就会被执行,因此可能此时元素的关联文件未下载完,例如与图片有关的HTML下载完毕,并且已经解析为DOM树了,但很有可能图片还未加载完毕,所以例如图片的高度和宽度这样的属性此时不一定有效。
要解决这个问题,可以使用JQuery中另一个关于页面加载的方法—load()方法。load()方法会在元素的onload事件中绑定一个处理函数。如果处理函数绑定在元素上,则会在元素的内容加载完毕后触发。如:$(window).load(function(){})=====window.onload = function(){}…