什么是事件?
事件是我们在编程时系统内发生的动作或者发生的事情(譬如点击鼠标、敲击键盘)。事件的本质是程序各个组成部分之间的一种通信方式,也是异步编程的一种实现。事件有多种类型,以下代码我们以“鼠标点击”事件为例。
浏览器的事件模型,就是通过监听函数(listener)监听事件,在事件发生改变后作出反应。事件的「默认行为」是指浏览器规定的行为,例如单击超链接会跳转...
事件的传播
一个事件发生后,会在子元素和父元素之间传播(propagation)。这种传播分成三个阶段:
- 事件捕获阶段(capture phase): 从dom树节点往下找到目标节点
- 事件目标处理阶段(target phase): 到达目标节点
- 事件冒泡阶段(bubbling phase): 最后从目标节点往顶层元素传递
![179203c4649c261d4f306c1802f111e1.png](https://i-blog.csdnimg.cn/blog_migrate/dc1d3f76b08e8e3b19e8532845cec92a.jpeg)
监听事件
JavaScript 有三种方法为事件绑定监听函数:
- 1.HTML 的 on- 属性
- 元素的事件监听属性,都是on加上事件名,比如onload就是on + load,表示load事件的监听代码。
- HTML 语言允许在元素的属性中,直接定义某些事件的监听代码:<body οnlοad="doSomething()">。这些属性的值是将会执行的代码(所以函数不要忘记加括号())
- 使用这个方法指定的监听代码,只会在冒泡阶段触发。
- 2.元素节点的事件属性
- div.onclick = function (event) { console.log('1')}
- 使用这个方法指定的监听函数,也是只会在冒泡阶段触发。
- 3.EventTarget.addEventListener()
- window.addEventListener('load', doSomething, false)
总结:
- “HTML 的 on- 属性”:违反了 HTML 与 JavaScript 代码相分离的原则,不推荐使用。
- “元素节点的事件属性”:同一个事件只能定义一个监听函数,如果定义两次 onclick 属性,后一次定义会覆盖前一次。不推荐使用。
- EventTarget.addEventListener() 推荐使用,优点:
- 同一个事件可以添加多个监听函数。
- 能够指定在哪个阶段(捕获阶段还是冒泡阶段)触发监听函数。
- DOM 节点之外的其他对象(比如 window、XMLHttpRequest 等)也有这个接口,它是整个 JavaScript 统一的监听函数接口。
如何阻止事件冒泡和默认行为:
- event.stopPropagation()
- event.preventDefault()
事件委托(事件代理)
概述:根据捕获与冒泡,如果我们有许多以类似方式处理的元素,那么就不必为每个元素都分配一个事件处理程序 —— 而是将单个处理程序放在它们的共同祖先上。
优点:
- 减少内存的使用(减少函数的使用)
- 可以监听动态元素
例子如下:
<ul id="myLink">
<li id="1">aaa</li>
<li id="2">bbb</li>
<li id="3">ccc</li>
</ul>
我们若要给其中的每个<li>
标签都加上一个点击事件。
简易版:
ul.addEventListener('click', function(e){
if(e.target.tagName.toLowerCase() === 'li'){
fn() // 执行某个函数
}
})
高级版:
function delegate(element, eventType, selector, fn) {
element.addEventListener(eventType, e => {
let el = e.target
while (!el.matches(selector)) {
if (element === el) {
el = null
break
}
el = el.parentNode
}
el && fn.call(el, e, el)
})
return element
}