事件
事件冒泡(event bubbling),即事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点。
事件捕获(event capturing),是不太具体的节点应该更早接收到事件,而具体的节点应该最后接收到事件。
HTML事件处理程序
<div id="app" onclick="alert('zhenjianyu')"></div>
在HTML中指定事件处理程序有两个缺点:
- 存在时差问题,因为用户可能会在HTML元素一出现在页面上就触发相应的事件,但当时事件处理程序有可能尚不具备执行条件。
- 扩展事件处理程序的作用域链在不同的浏览器中会导致不同结果。不同的JavaScript引擎遵循的标识符解析规则略有差异,很可能会在访问非限定对象成员时出错。
通过HTML指定事件处理程序会使HTML和JavaScript代码紧密耦合。如果要更换事件处理程序,就要改动HTML代码和JavaScript代码。这正是许多开发人员摒弃HTML事件处理程序,转而使用JavaScript指定事件处理程序的原因所在。
DOM0级事件处理程序
let btn = document.getElementById('myBtn') btn.onclick = function(){ alert('click btn') }
以这种方式添加的事件处理程序会在事件流的冒泡阶段被处理。
DOM2级事件处理程序
用于指定和删除事件处理程序的操作:addEventListener( )和removeEventListener( )。所有DOM节点都包含这两个方法,并且它们都接受3个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。最后的布尔值参数如果是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。
通过addEventListener( )添加的事件处理程序只能使用removeEventListener( )来移除;移除时传入的参数与添加处理程序时的参数相同。这也意味着通过addEventListener( )添加的匿名函数将无法移除。
IE事件处理程序
attachEvent( )和detachEvent( ),这两个方法接受相同的两个参数,事件处理程序名称和事件处理程序函数。
在使用DOM0级方法的情况下,事件处理程序会在其所属元素的作用域内运行;在使用attachEvent( )方法的情况下,事件处理程序会在全局作用域中运行,因此this等于window。
let btn = document.getElementById('myBtn') btn.attachEvent('onclick',function(){ alert(this === window) // true })
与addEventListener( )类似,attachEvent( )方法也可以为同一个元素添加多个事件处理程序。不过,与DOM方法不同的是,这些事件处理程序不是以添加它们的顺序执行,而是以相反的顺序被触发。
事件对象:在触发DOM上的某个事件时,会产生一个事件对象,这个对象中包含着所有与事件有关的信息。包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。
事件侦听函数 兼容性
图像元素不一定要从添加到文档后才开始下载,只要设置了src属性就会开始下载。
DOMContentLoaded事件则在形成完整的DOM树之后就会触发,不理会图像、JavaScript文件、CSS文件或其他资源是否已经加载完毕。
对“事件处理程序过多”问题的解决方案就是事件委托。事件委托利用了事件冒泡机制。