let list = document.getElementById("myLinks");
list.addEventListener("click", (event) => {
let target = event.target;
switch(target.id) {
case "doSomething":
document.title = "I changed the document's title";
break;
case "goSomewhere":
location.href = "http:// www.wrox.com";
break;
case "sayHi":
console.log("hi");
break;
}
});
事件意味着用户或浏览器执行的某种动作。比如,单击(click)、加载(load)、鼠标悬停(mouseover)。为响应事件而调用的函数被称为事件处理程序(或事件监听器)。事件处理程序的名字以"on"开头,因此 click 事件的处理程序叫作 onclick,而 load 事件的处理程序叫作 onload。
事件处理程序
事件处理程序有很多指定方式
HTML事件处理程序
特定元素支持的每个事件都可以使用事件处理程序的名字以 HTML 属性的形式来指定。
DOM0事件处理程序
把一个函数赋值给(DOM 元素的)一个事件处理程序属性。
在事件处理程序里通过 this 可以访问元素的任何属性和方法。以这种方式添加事件处理程序是注册在事件流的冒泡阶段的。
通过将事件处理程序属性的值设置为 null,可以移除通过 DOM0 方式添加的事件处理程序,如下面的例子所示:
DOM2事件处理程序
DOM2 Events 为事件处理程序的赋值和移除定义了两个方法:addEventListener()和 removeEventListener()
接收 3 个参数:事件名、事件处理函数和一个布尔值,true 表示在捕获阶段调用事件处理程序,false(默认值)表示在冒泡阶段调用事件处理程序。
✨注意:事件名前面没有on,有on的是事件处理程序
通过 addEventListener()添加的事件处理程序只能使用 removeEventListener()并传入与添加时同样的参数来移除。这意味着使用 addEventListener()添加的匿名函数无法移除
IE事件处理程序
attachEvent()和 detachEvent()。这两个方法接收两个参数:事件处理程序的名字和事件处理函数。因为 IE8 及更早版本只支持事件冒泡,所以使用attachEvent()添加的事件处理程序会添加到冒泡阶段,不需要三个参数。
✨IE与 DOM0 方式区别:
主要区别是事件处理程序的作用域。
使用 DOM0方式时,事件处理程序中的 this 值等于目标元素。
使用 attachEvent()时,事件处理程序是在全局作用域中运行的,因此 this 等于 window。
事件对象
在 DOM 中发生事件时,所有相关信息都会被收集并存储在 event 对象中。
HTML属性指定的事件也有event对象
event对象中有很多属性和方法,下面介绍最主要的几个:
type
被触发的事件类型,如click,mouseover等事件名。
currentTarget和target
currentTarget表示当前事件处理程序所在的元素,this始终等于currentTarget。target表示事件目标。
如果我们在button和body上都添加了事件处理程序:
✨总结:点击的元素决定着target,当前元素的事件处理程序决定这currentTarget。也就是说,在一个事件流中,target是不变的,但是由于target的父元素也存在事件处理程序,那么父元素的事件处理程序中的currentTarget就是父元素本身。
preventDefault()
preventDefault()方法用于阻止特定事件的默认动作。比如,链接的默认行为就是在被单击时导航到 href 属性指定的 URL。如果想阻止这个导航行为,可以在 onclick 事件处理程序中取消,如下面的例子所示:
stopPropagation()
stopPropagation()方法用于立即阻止事件流在 DOM 结构中传播,取消后续的事件捕获或冒泡。例如,直接添加到按钮的事件处理程序中调用 stopPropagation(),可以阻止 document.body 上注册的事件处理程序执行。比如:
事件委托
“过多事件处理程序”的解决方案是使用事件委托。事件委托利用事件冒泡,可以只使用一个事件处理程序来管理一种类型的事件。
如下,有三个li元素,点击每个元素都有不同的事件触发
使用事件委托,只要给所有元素共同的祖先节点添加一个事件处理程序,就可以解决问题。