系统学习DOM(四)

230 阅读3分钟

这是我参与更文挑战的第7天,活动详情查看:更文挑战

DOM 除了节点和操作 API,还有一个重要的部分,那就是事件,这里将做比较全面的介绍。

一、事件流

事件流描述从页面接收事件的顺序,DOM2 事件流分为3个阶段:捕获阶段、目标阶段和冒泡阶段。

  • 捕获阶段:document 对象首先接收到事件,然后沿 DOM 树依次向下,直到实际目标元素
  • 目标阶段:目标元素接收到事件
  • 冒泡阶段:由目标元素沿 DOM 树依次向上,直到 document

所以捕获阶段一定先于冒泡阶段;addEventListener 的第三个参数就是指定在捕获还是冒泡阶段触发。

二、事件处理程序

事件处理程序有3种指定方式,分别如下:

  • HTML 事件处理程序:通过 html 属性设置事件处理程序,例如:
<input type="button" value="Click Me" onclick="alert('Clicked')">
  • DOM0 级事件处理程序:通过 element 属性设置事件处理程序,例如:
var btn = document.getElementById("myBtn");
btn.onclick = function(){
    alert("Clicked");
};
  • DOM2 级事件处理程序:通过 addEventListener/removeEventListener 方法添加/移除事件处理程序,例如:
var btn = document.getElementById("myBtn");
var handler = function(){
    alert(this.id);
};
btn.addEventListener("click", handler, false);

btn.removeEventListener("click", handler, false);

推荐使用第三种方式。

三、事件对象

兼容 DOM 的浏览器在调用事件处理程序时会将一个 event 对象传给它,event 常用的属性和方法如下:

  • target:事件目标,即触发事件的 DOM 元素
  • type:事件类型,例如 'click'、'mouseover' 等
  • preventDefault:阻止默认行为,例如 <a href="#">xxx</a> 点击是会默认在 URL 上添加 '#',通过调用 e.preventDefault() 可以取消这种默认行为
  • stopPropagation:阻止事件冒泡

四、事件类型

浏览器的事件非常多,主要分为如下几个类型:

  • UI 事件,当用户与页面上的元素交互时触发,例如:'load'、'unload'、'resize'、'scroll'
  • 焦点事件,当元素获得或失去焦点时触发,例如 'blur'、'focus'
  • 鼠标事件,当用户通过鼠标在页面上执行操作时触发,例如 'click'、'dbclick'
  • 滚轮事件,当使用鼠标滚轮(或类似设备)时触发,例如 'mousewheel'
  • 文本事件,当在文档中输入文本时触发,例如 'textInput'
  • 键盘事件,当用户通过键盘在页面上执行操作时触发,例如 'keydown'、'keypress'、'keyup'
  • 合成事件,当为 IME(Input Method Editor,输入法编辑器)输入字符时触发
  • 变动(mutation)事件,当底层 DOM 结构发生变化时触发,例如 'DOMSubtreeModified'
  • HTML5 事件,例如 'contextmenu'、'beforeunload'、'DOMContentLoaded'、'hashchange'
  • 设备事件,例如 'orientationchange'
  • 触摸手势,例如 'touchstart'、'touchend'、'gesturestart'、'gestureend'

五、内存性能

Web 页面添加事件处理程序的数量会直接影响内存和性能,通常有如下两种处理方式:

  • 事件委托,即利用事件冒泡在父元素(通常是 document)上设置一个事件处理程序,等子元素事件冒泡到父元素上时统一处理
  • 移除事件处理程序,即在不用 DOM 节点时,手动移除上面绑定的事件,注意:

如果带有事件处理程序的元素被 innerHTML 删除 了,那么原来添加到元素中的事件处理程序极有可能无法被当作垃圾回收。(红宝书第13.5.2节)

六、模拟事件

可以使用 createEvent 方法来创建 event 对象,例如:

var btn = document.getElementById("myBtn");
var event = document.createEvent("MouseEvents");
event.initMouseEvent("click", true, true, document.defaultView, 0, 0, 0, 0, 0, false, false, false, false, 0, null);

btn.dispatchEvent(event);

至此,DOM 事件相关的内容基本介绍完毕。