资讯专栏INFORMATION COLUMN

事件处理---事件等级模型,捕获,冒泡,默认事件。

csRyan / 1358人阅读

摘要:事件处理器和事件侦听器事件处理器它是通过是由元素提供的属性注册的函数。事件处理器内部的关键字被设置为注册该事件处理器的元素。而事件侦听器则指向严格模式下。

前言 在讲事件处理之前先看看下面几点:

以下所说到的 IE 都是指 IE8 以及更早期版本的 IE

以下所说到的 IE 都是指 IE8 以及更早期版本的 IE

以下所说到的 IE 都是指 IE8 以及更早期版本的 IE

我们先了解 EventTarget它一个接口,由一个可以接受事件的对象实现的; 同时也可以给它添加侦听器

EventTarget,可以是 elementdocumentwindowXMLHttpRequest 等等。

事件处理器和事件侦听器 事件处理器

它是通过是由 DOM 元素提供的 on{eventtype} 属性注册的函数。

它的作用:帮助管理元素如何对事件反应。

// 这模式为 DOM 0级事件
Click me
点我咯
// 点击之后都会有弹出 ‘I am div1 ’ 。 // 缺点如下: // 第一种:把代码写在了 html 元素里面,简直灾难.... // 第二种:他们之间有强耦合性,如果修改函数名,两个地方到哦要改。

同时也可以用 js ,帮 DOM 元素添加 on{eventtype}

// 同样为 DOM 0级事件
快点我

事件侦听器

它是通过 *EventTarget.addEventListener()注册的对象或函数。

EventTarget.addEventListener(eventtype, listener, options)

- **eventtype**: 事件类型,如 *click* , *change* , *focus* 等等 。可以点[这里][2]看看有哪些事件类型 。

- **listener**: 它为一个函数。当监听的事件触发时,要执行什么操作。

- **options**: 下面会说。

IE 的话,则是:EventTarget.attachEvent(eventNameWithOn, listener)。

- **eventNameWithOn**: 这里的事件类型要带 ***on*** 。

// DOM 2级事件

Click me
事件处理器和事件侦听器的不同

事件处理器在同一个事件类型上不能绑定多个事件。而事件侦听器可以。

// 第一个例子, 点击后会只弹出 1 。

Click me
// 第二个例子, 点击只会弹出 2 。
Click me
// 为何弹出不一样?这是因为生成DOM树和JS执行的方式不同。

事件处理器内部的 this 关键字被设置为注册该事件处理器的 DOM 元素。 而事件侦听器则指向 undefined (严格模式下)。

事件捕获和事件冒泡

这里先说下 addEventListener 的第三个参数 *options

options 有很多选择,点这里可以看。主要讲的是里面 useCapture

useCapture 它是 Boolean 值。

- *false* : 默认值。事件会冒泡。
- *true* : 事件会捕获。

注意:IE 下,只有冒泡,没有捕获。所以 attachEvent 没有第三个参数

事件冒泡
如果子元素和父元素都有事件处理程序,触发子元素的事件后,父级的事件跟着触发,就像在水里吐出气泡,再往上触发父级的父级事件。如上图
注意了,他们的事件类型是一致才行!!!。

事件处理器情况

// 点击div3,弹出的数字顺序是: 3 -> 2 -> 1 。

事件侦听器情况

// 点击 div3 , 弹出顺序:"I am div3" -> "I am div2" -> "I am div1"

如果事件处理器事件侦听器 都有呢,怎么执行?代码就不写了,其实就是上面的结合。答案如下:

    3 -> "I am div3" -> 2 -> "I am div2" -> 1 -> "I am div1"
    因为DOM先生成,获取onclick,加载JS时,再注册监听事件。

事件捕获
其实和事件冒泡差不多,只是先从父到子。
注意了,他们的事件类型是一致才行!!!。

代码其实跟上面差不多,就是 addEventListener() 第三个参数 false 改为 true

div1.addEventListener("click", fn1, true);
div2.addEventListener("click", fn2, true);
div3.addEventListener("click", fn3, true);

// 点击div3, 弹出的顺序为 "I am div1" -> "Iam div2" -> "I am div3"

事件流
事件流又称为事件传播,DOM2级事件规定的事件流包括三个阶段:事件捕获阶段处于目标阶段事件冒泡阶段
首先发生的是事件捕获,为截获事件提供了机会。然后是实际的目标接收到事件,最后一个阶段是冒泡阶段,可以在这个阶段对事件做出响应。

由于 addEventListener 同一事件类型可以监听多个事件,如图:

let div1 = document.getElementById("div1");
let div2 = document.getElementById("div2");
let div3 = document.getElementById("div3");

let fn1 = () => alert("I am div1");
let fn2 = () => alert("I am div2");
let fn3 = () => alert("I am div3");

div1.addEventListener("click", fn1, true);
div1.addEventListener("click", fn1, false);

div2.addEventListener("click", fn2, true);
div2.addEventListener("click", fn2, false);

// 如果 处于目标阶段,有没 true 和 false 都一样的了。
// 如果点击的是 div3 ,可写成 div3.addEventListener("click", fn3)
div3.addEventListener("click", fn3, true);
div3.addEventListener("click", fn3, false);

点击 div3, 执行顺序:

"I am div1" -> "I am div2" -> "I am div3" -> "I am div2" -> "I am div1" 。

阻止事件冒泡和事件捕获

触发事件程序,函数内都可以获取一个事件对象 event ,而 IE 的事件对象是 window.event

event 对象有个方法 stopPropagation , 它可以阻止事件冒泡和捕获。

IEwindow.event 有个 cancelBubble 方法,组止冒泡。

  // 部分关键代码
  let fn1 = () => alert("I am div1");

  let fn2 = () => {
    alert("I am div2");
    event.stopPropagation();

    // IE 是 window.event.cancelBubble(),当然下面addEventListener 改为 attachEvent。
  }

  let fn3 = () => alert("I am div3");

  div1.addEventListener("click", fn1, true);
  div1.addEventListener("click", fn1, false);

  div2.addEventListener("click", fn2, true);
  div2.addEventListener("click", fn2, false);

  div3.addEventListener("click", fn3, true);
  div3.addEventListener("click", fn3, false);

点击 div3,执行顺序:"I am div1" -> "I am div2" 。

如果有事件捕获和冒泡,则先执行事件捕获( 上面有说 )。所以先弹出 " I am div1" 。

由于 fn2 里面有 event.stopPropagation() ,阻止捕获和冒泡,所以弹出 "I am div2",之后就没了。

默认事件

当我们点击链接,会跳到新的加载页面,当我们完成 input 的按回车,就会提交。 等等这些都是元素的默认事件。

但不是所有元素都有默认事件的。可以根据 该元素的事件对象 eventcancelable 值来判断, false 则没有默认事件。

阻止默认事件

我们可以通过 event.preventDefault 阻止默认事件,IE 的是 window.event.returnValue

阻止默认事件 不在 事件流 当中的,当然也不会影响冒泡和捕获。

百度

点击之后,不会跳转到百度哦。

最后

虽然现在 MVVM 框架是主流,但基础的东西还是要理解透。如果写一个原生的组件时候,那么这些会涉及到的。
在此祝大家冬至快乐!也提前说声圣诞快乐!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/90372.html

相关文章

  • javascript -- 事件--事件流-- 冒泡 --捕获

    摘要:在内联模型中,事件处理函数是标签的一个属性,用于处理指定事件。事件捕获与冒泡原理图事件流同时支持两种事件模型捕获型事件和冒泡型事件,但是,捕获型事件先发生。 javascript -- 事件 事件是js和用户操作交互的桥梁, JavaScript 有三种事件模型:内联模型、脚本模型和 DOM2 模型 内联模型 这种模型是最传统接单的一种处理事件的方法。在内联模型中,事件处理函数是 HT...

    leeon 评论0 收藏0
  • JS中的事件顺序(事件捕获冒泡)

    摘要:问题如果一个元素和它的祖先元素注册了同一类型的事件函数例如点击等那么当事件发生时事件函数调用的顺序是什么呢比如考虑如下嵌套的元素 问题 如果一个元素和它的祖先元素注册了同一类型的事件函数(例如点击等), 那么当事件发生时事件函数调用的顺序是什么呢? 比如, 考虑如下嵌套的元素: ----------------------------------- | outer ...

    张迁 评论0 收藏0
  • JS中的事件顺序(事件捕获冒泡)

    摘要:问题如果一个元素和它的祖先元素注册了同一类型的事件函数例如点击等那么当事件发生时事件函数调用的顺序是什么呢比如考虑如下嵌套的元素 问题 如果一个元素和它的祖先元素注册了同一类型的事件函数(例如点击等), 那么当事件发生时事件函数调用的顺序是什么呢? 比如, 考虑如下嵌套的元素: ----------------------------------- | outer ...

    ixlei 评论0 收藏0
  • DOM事件

    摘要:目标阶段事件对象到达事件对象的事件目标。如果事件类型指示事件不冒泡,则事件对象将在完成此阶段之后停止。气泡阶段事件对象以相反顺序传播目标的祖先,从的父对象开始,并以窗口结束。涉及到事件委托时这两个所指的元素才会不一样参考等级概述事件流 DOM DOM(Document Object Model) 全称文档对象模型. 文档可以是HTML, XML, 或者XHTML文档.DOM定义 的是一...

    yy13818512006 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<