一、事件与事件流

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

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

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

  • 事件捕获阶段(capture phase)
  • 处于目标阶段(target phase)
  • 事件冒泡阶段(bubbling phase)

事件冒泡是一种从下往上的传播方式,由最具体的元素(触发节点)然后逐渐向上传播到最不具体的那个节点,也就是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元素上发生,然后逐级向上传播

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

二、事件模型

事件模型可以分为三种:

  • 原始事件模型(DOM0级)
  • 标准事件模型(DOM2级)
  • IE事件模型(基本不用)

原始事件模型

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

  • HTML代码中直接绑定
<input type="button" onclick="fun()">
  • 通过JS代码绑定
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;

标准事件模型

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

  • 事件捕获阶段:事件从document一直向下传播到目标元素, 依次检查经过的节点是否绑定了事件监听函数,如果有则执行
  • 事件处理阶段:事件到达目标元素, 触发目标元素的监听函数
  • 事件冒泡阶段:事件从目标元素冒泡到document, 依次检查经过的节点是否绑定了事件监听函数,如果有则执行

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

addEventListener(eventType, handler, useCapture)

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

removeEventListener(eventType, handler, useCapture)

参数如下:

  • eventType指定事件类型(不要加on)
  • handler是事件处理函数
  • useCapture是一个boolean用于指定是否在捕获阶段进行处理,一般设置为false与IE浏览器保持一致

举个例子:

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

特性

  • 可以在一个DOM元素上绑定多个事件处理器,各自并不会冲突
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事件模型共有两个过程:

  • 事件处理阶段:事件到达目标元素, 触发目标元素的监听函数。
  • 事件冒泡阶段:事件从目标元素冒泡到document, 依次检查经过的节点是否绑定了事件监听函数,如果有则执行

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

attachEvent(eventType, handler)

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

detachEvent(eventType, handler)

举个例子:

var btn = document.getElementById('.btn');
btn.attachEvent(‘onclick’, showMessage);
btn.detachEvent(‘onclick’, showMessage);

JavaScript中的事件模型如何理解?的更多相关文章

  1. 理解javascript中的事件模型

    javascript中有两种事件模型:DOM0,DOM2.而对于这两种的时间模型,我一直不是非常的清楚,现在通过网上查阅资料终于明白了一些. 一.  DOM0级事件模型 DOM0级事件模型是早期的事件 ...

  2. 说说JavaScript中的事件模型

    1.javascript中为元素添加事件处理程序的方法有以下几种方式,可以为javascript元素添加事件处理程序 (1) 直接将事件处理代码写在html中(2) 定义一个函数,赋值给html元素的 ...

  3. JavaScript中对事件简单的理解(1)

    事件(event) 1.什么是JavaScript事件? 事件是文档或浏览器中发生的特定交互瞬间. 2.事件流 事件流描述的是从页面中接受事件的顺序,包含IE提出的事件冒泡流与Netscape提出的事 ...

  4. JavaScript中的事件模型

    JS中的事件 1.鼠标事件 onclick   ondbclick   onmouseover   onmouseout 2.HTML事件 onload   onunload   onsubmit   ...

  5. JavaScript中对事件简单的理解

    事件(event) 1.什么是JavaScript事件? 事件是文档或浏览器中发生的特定交互瞬间. 2.事件流 事件流描述的是从页面中接受事件的顺序,包含IE提出的事件冒泡流与Netscape提出的事 ...

  6. JavaScript中对事件简单的理解(2)

    事件(event) event对象 (1)什么是event对象? Event 对象代表事件的状态,比如事件在其中发生的元素.键盘按键的状态.鼠标的位置.鼠标按钮的状态.事件通常与函数结合使用,函数不会 ...

  7. 深入理解javascript中的事件循环event-loop

    前面的话 本文将详细介绍javascript中的事件循环event-loop 线程 javascript是单线程的语言,也就是说,同一个时间只能做一件事.而这个单线程的特性,与它的用途有关,作为浏览器 ...

  8. 了解javascript中的事件(二)

    本文目录如下: 零.寒暄 一.事件的分类 二.事件代理 2.1 问题引出 2.2 什么是事件代理 2.3 完整示例 二.事件代理 三.事件代理思想的用处 四.总结 零.寒暄 这篇博客本该出现在两个月以 ...

  9. JavaScript中的事件循环机制跟函数柯里化

    一.事件循环机制的理解 test();//按秒输出5个5 function test() { for (var i = 0; i < 5; i++) { setTimeout(() => ...

  10. javascript 中的事件机制

    1.javascript中的事件. 事件流 javascript中的事件是以一种流的形式存在的. 一个事件会也有多个元素同时响应. 有时候这不是我们想要的效果, 我们只是需要某个特定的元素相应我们的绑 ...

随机推荐

  1. AAC音频编码之--概念介绍

    一 概念 AAC,全称Advanced Audio Coding,是一种专为声音数据设计的文件压缩格式.与MP3不同,它采用了全新的算法进行编码,更加高效,具有更高的"性价比".利 ...

  2. day09-数据格式化&验证以及国际化

    数据格式化&验证以及国际化 1.数据格式化 1.1基本介绍 说明:在我们提交数据(比如表单时),SpringMVC 是怎样对提交的数据进行转换和处理的 基本数据类型可以和字符串之间自动进行转换 ...

  3. 移远EC20 4G模块Linux驱动移植和测试

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  4. [Leetcode 1981. 最小化目标值与所选元素的差] 记忆化搜索

    记忆化搜索 class Solution { int ans = 5001; public int minimizeTheDifference(int[][] mat, int target) { i ...

  5. js原型详解

    js中的原型毫无疑问一个难点,学习如果不深入很容易就晕了! 任何一个js知识点,比如事件流,闭包,继承等,都有许许多多的说法,对于这些知识点我们都应该先熟练的使用,然后自己整理一套属于自己的理解说辞, ...

  6. 你的DDPG/RDPG为何不收敛?

    园子好多年没有更过了,草长了不少.上次更还是读博之前,这次再更已是博士毕业2年有余,真是令人唏嘘.盗链我博客的人又见长,身边的师弟也问我挖的几个系列坑什么时候添上.这些着实令我欣喜,看来我写的东西也是 ...

  7. FPGA 原语之一位全加器

    FPGA原语之一位全加器 1.实验原理 一位全加器,三个输入,两个输出.进位输出Cout=AB+BC+CA,本位输出S=A异或B异或C.实验中采用三个与门.一个三输入或门(另外一个是两个或门,功能一致 ...

  8. IDEA彩虹括号插件Rainbow Brackets

    IDEA搜索插件Rainbow Brackets 安装后重启IDEA 效果如图:不同层级的括号会变成不同的颜色,便于区分. 光标定位到前一个括号后,使用快捷键ALT+鼠标右键可以只查看当前括号中的内容 ...

  9. #状压dp#洛谷 3959 [NOIP2017 提高组] 宝藏

    题目 选定一个起点 \(S\),找到一棵生成树,最小化 \[\sum_{i=1}^n dep_i\times dis_i \] \(n\leq 12\) 分析 设 \(dp[d][S]\) 表示当前树 ...

  10. #左偏树,树形dp#洛谷 1552 [APIO2012]派遣

    题目 分析 那我指定管理层之后,选择薪水越小的人越好, 考虑小根堆,由于需要合并,所以采用左偏树 代码 #include <cstdio> #include <cctype> ...