Skip to content

JavaScript中的事件模型有哪些

Posted on:2024年8月10日 at 17:04

一、事件与事件流

javascript中的事件,可以理解就是在HTML文档或者浏览器中发生的一种交互操作,使得网页具备互动性, 常见的有加载事件、鼠标事件、自定义事件等

由于DOM是一个树结构,如果在父子节点绑定事件时候,当触发子节点的时候,就存在一个顺序问题,这就涉及到了事件流的概念

事件流都会经历三个阶段:

事件冒泡是一种从下往上的传播方式,由最具体的元素(触发节点)然后逐渐向上传播到最不具体的那个节点,也就是DOM中最高层的父节点

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Event Bubbling</title>
  </head>
  <body>
    <button id="clickMe">Click Me</button>
  </body>
</html>

然后,我们给button和它的父元素,加入点击事件

var button = document.getElementById("clickMe");

button.onclick = function () {
  console.log("1.Button");
};
document.body.onclick = function () {
  console.log("2.body");
};
document.onclick = function () {
  console.log("3.document");
};
window.onclick = function () {
  console.log("4.window");
};

点击按钮,输出如下

1.button
2.body
3.document
4.window

点击事件首先在button元素上发生,然后逐级向上传播

事件捕获与事件冒泡相反,事件最开始由不太具体的节点最早接受事件, 而最具体的节点(触发节点)最后接受事件

二、事件模型

事件模型可以分为三种:

原始事件模型

事件绑定监听函数比较简单, 有两种方式:

<input type="button" onclick="fun()">
var btn = document.getElementById(".btn");
btn.onclick = fun;

特性

DOM0级事件具有很好的跨浏览器优势,会以最快的速度绑定,但由于绑定速度太快,可能页面还未完全加载出来,以至于事件可能无法正常运行

<input type="button" id="btn" onclick="fun1()">

var btn = document.getElementById('.btn');
btn.onclick = fun2;

如上,当希望为同一个元素绑定多个同类型事件的时候(上面的这个btn元素绑定2个点击事件),是不被允许的,后绑定的事件会覆盖之前的事件

删除 DOM0 级事件处理程序只要将对应事件属性置为null即可

btn.onclick = null;

标准事件模型

在该事件模型中,一次事件共有三个过程:

事件绑定监听函数的方式如下:

addEventListener(eventType, handler, useCapture)

事件移除监听函数的方式如下:

removeEventListener(eventType, handler, useCapture)

参数如下:

举个例子:

var btn = document.getElementById('.btn');
btn.addEventListener(‘click’, showMessage, false);
btn.removeEventListener(‘click’, showMessage, false);

特性

btn.addEventListener(‘click’, showMessage1, false);
btn.addEventListener(‘click’, showMessage2, false);
btn.addEventListener(‘click’, showMessage3, false);

当第三个参数(useCapture)设置为true就在捕获过程中执行,反之在冒泡过程中执行处理函数

下面举个例子:

<div id="div">
  <p id="p">
    <span id="span">Click Me!</span>
  </p>
</div>

设置点击事件

var div = document.getElementById("div");
var p = document.getElementById("p");

function onClickFn(event) {
  var tagName = event.currentTarget.tagName;
  var phase = event.eventPhase;
  console.log(tagName, phase);
}

div.addEventListener("click", onClickFn, false);
p.addEventListener("click", onClickFn, false);

上述使用了eventPhase,返回一个代表当前执行阶段的整数值。1为捕获阶段、2为事件对象触发阶段、3为冒泡阶段

点击Click Me!,输出如下

P 3
DIV 3

可以看到,pdiv都是在冒泡阶段响应了事件,由于冒泡的特性,裹在里层的p率先做出响应

如果把第三个参数都改为true

div.addEventListener("click", onClickFn, true);
p.addEventListener("click", onClickFn, true);

输出如下

DIV 1
P 1

两者都是在捕获阶段响应事件,所以divp标签先做出响应

IE事件模型

IE事件模型共有两个过程:

事件绑定监听函数的方式如下:

attachEvent(eventType, handler)

事件移除监听函数的方式如下:

detachEvent(eventType, handler)

举个例子:

var btn = document.getElementById('.btn');
btn.attachEvent(‘onclick’, showMessage);
btn.detachEvent(‘onclick’, showMessage);
原文转自:https://fe.ecool.fun/topic/82a3da79-23fb-42be-8f4b-9d52fc595954