Appearance
EventLoop
EventBus
事件系统是一个典型的发布——订阅模式
实现一个简单的EventBus
DOM事件
参考:DOM编程之事件(二)
事件流
根节点->捕获->事件目标节点->冒泡->根节点
事件委托
事件冒泡模型在为大量单独元素上注册处理程序提供了解决方案(在其公有祖先元素上注册事件,即事件委托)。作用:节省内存,方便管理新增或删除节点时注册事件的逻辑
事件委托就是事件目标不直接处理事件,而是委托其父元素或者祖先元素甚至根元素(document)的事件处理函数进行处理。可以通过事件对象的target属性获得真正触发事件的引用。
事件委托是建立在冒泡模型之上的。
多个事件执行顺序
- 某些操作会同时出发多个事件,如点击事件执行顺序:touchstart -> touchend -> click
- 事件执行顺序先捕获后冒泡。
addEventListener
第三个参数设置为ture时是在捕获阶段执行,而默认是false在冒泡阶段执行。
去抖
函数调用n秒后才会执行,如果函数在n秒内被调用的话则函数不执行,重新计算执行时间
基本思路是采用定时器来实现,在指定时间内连续触发,则清除上一次的定时器,并重新生成新的定时器
js
function debounce(cb, delay) {
var timer = null
return function () {
clearTimeout(timer)
var args = arguments,
context = this
timer = setTimeout(() => {
cb.apply(context, args)
}, delay);
}
}
去抖函数的问题在于:它是在我们事件结束后的一段时间内才会执行,会有一个延迟性。如果函数触发的频率过快,则原本的回调函数一次都不会执行,因为生成的定时器被频繁的清除。不过这也是去抖函数本身的目的,即重新计算执行时间
节流
函数预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新周期
基本思路是通过比较时间戳来实现
js
function throttle(cb, duration) {
var start = new Date()
return function () {
var context = this,
args = arguments,
now = new Date()
if (now - start >= duration) {
cb.apply(context, args);
start = now;
}
}
}
需要注意的是,节流函数和去抖函数本身没有减少事件的触发次数,而是控制事件处理函数的执行来减少实际逻辑处理过程,提高浏览器性能。
Vue事件原理
注册到单个vNode对应的dom实例上
React事件原理
事件委托注册到根节点上面,并且通过合成事件池进行性能优化,在React17版本有调整