资讯专栏INFORMATION COLUMN

JavaScript捕获和冒泡探讨

caikeal / 1189人阅读

摘要:上个星期在微博中一个关于捕获和冒泡代码的讨论,可能没有动手实现一篇的人无法给出确定的答案。目标阶段事件对象到达其事件目标。在此阶段注册的事件监听器会对相应的冒泡事件进行处理。

上个星期在微博中一个关于javascript捕获和冒泡代码的讨论,可能没有动手实现一篇的人无法给出确定的答案。

这里再来回顾一下之前的三条微博。

事件的执行顺序

JavaScript冒泡和捕获考察题目看图回答问题,晚上公布答案。

问:点击Li,JS的执行顺序是什么?

JavaScript捕获和冒泡探讨

总结就是:先捕获,后冒泡,捕获从上到下,冒泡从下到上(形象点说法:捕获像石头沉入海底,冒泡则像气泡冒出水面)

问:假如去掉注释 event.stopPropagation(); 结果又会输出什么?

答:去掉event.stopPropagation()
之后,由于事件有捕获和冒泡时先执行捕获,捕获到div之后,事件被阻止,后面就不在继续传播了。所以只输出divcallback.

在上面的代码如果增加一个div.addEventListener("click",callbackdiv2,false);

则div先执行捕获,接着执行上面这句冒泡,所以微博里的一个朋友评论说事件执行过捕获就不会执行冒泡其实是不对的。

div.addEventListener("click",callbackdiv,true);这一句只能是捕获才执行。

以上代码代码:演示

事件不同浏览器处理函数

element.addEventListener(type, listener[, useCapture]); // IE6~8不支持(捕获和冒泡通过useCapture,默认false)
element.attachEvent(’on’ + type, listener); // IE6~10,IE11不支持(只执行冒泡事件)
element[’on’ + type] = function(){} // 所有浏览器(默认执行冒泡事件)

JavaScript捕获和冒泡探讨

W3C规范中定义了3个事件阶段,依次是捕获阶段、目标阶段、冒泡阶段。事件对象按照上图的传播路径依次完成这些阶段。如果某个阶段不支持或事件对象的传播被终止,那么该阶段就会被跳过。举个例子,如果Event.bubbles属性被设置为false,那么冒泡阶段就会被跳过。如果Event.stopPropagation()在事件派发前被调用,那么所有的阶段都会被跳过。

捕获 阶段:

在事件对象到达事件目标之前,事件对象必须从window经过目标的祖先节点传播到事件目标。 这个阶段被我们称之为捕获阶段。在这个阶段注册的事件监听器在事件到达其目标前必须先处理事件。

目标 阶段:

事件对象到达其事件目标。 这个阶段被我们称为目标阶段。一旦事件对象到达事件目标,该阶段的事件监听器就要对它进行处理。如果一个事件对象类型被标志为不能冒泡。那么对应的事件对象在到达此阶段时就会终止传播。

冒泡 阶段:

事件对象以一个与捕获阶段相反的方向从事件目标传播经过其祖先节点传播到window。这个阶段被称之为冒泡阶段。在此阶段注册的事件监听器会对相应的冒泡事件进行处理。

在一个事件完成了所有阶段的传播路径后,它的Event.currentTarget会被设置为null并且Event.eventPhase会被设为0。Event的所有其他属性都不会改变(包括指向事件目标的Event.target属性).

跨浏览器的事件处理函数:

var EventUtil = {
  addHandler: function(element, type, handler) {
    if (element.addEventListener) {  // DOM2
      element.addEventListener(type, handler, false);
    } else if (element.attachEvent) {  // IE
      element.attachEvent("on" + type, handler);
    } else {  // DOM0
      element["on" + type] = handler;
    }
  },

  removeHandler: function(element, type, handler) {
    if (element.removeEventListener) {
      element.removeEventListener(type, handler, false);
    } else if (element.detachEvent) {
      element.detachEvent("on" + type, handler);
    } else {
      element["on" + type] = null;
    }
  }
};

跨浏览器的事件对象:

var EventUtil = {
  getEvent: function(e) {
    return e ? e : window.e;
  },

  getTarget: function(e) {
    return e.target || e.srcElement;
  },

  preventDefault: function(e) {
    if (e.preventDefault) {
      e.preventDefault();
    } else {
      e.returnValue = false;
    }
  },

  stopPropagation: function(e) {
    if (e.stopPropagation) {
      e.stopPropagation()
    } else {
      e.cancelBubble = true;
    }
  }
}

可以看我之前写过的一篇文章:如何停止冒泡和阻止默认行为

ps:半个月没发文章,因为我最近在搞这个:开发头条网,然后我发现这个东西做好和做坏根本没有出路,我考虑要不要下掉,呜呜……,请赐予我动力吧。

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

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

相关文章

  • 「前端面试题系列7」Javascript 中的事件机制(从原生到框架)

    摘要:要想注册过的事件能够被解除,必须将回调函数保存起来,否则无法解除。当用阻止浏览器的默认行为时,会做下面这件事停止回调函数执行并立即返回。 showImg(https://segmentfault.com/img/bVboOcb?w=750&h=422); 前言 这是前端面试题系列的第 7 篇,你可能错过了前面的篇章,可以在这里找到: 理解函数的柯里化 ES6 中箭头函数的用法 thi...

    Tony 评论0 收藏0
  • 【译】JavaScript面试问题:事件委托this

    摘要:主题来自于的典型面试问题列表。有多种方法来处理事件委托。这种方法的缺点是父容器的侦听器可能需要检查事件来选择正确的操作,而元素本身不会是一个监听器。 showImg(http://fw008950-flywheel.netdna-ssl.com/wp-content/uploads/2014/11/Get-Hired-Fast-How-to-Job-Search-Classifieds...

    浠ラ箍 评论0 收藏0
  • JS DOM Event

    摘要:事件处理程序事件侦听器的设定级级首先讲级事件处理程序对事件的方式被称为事件处理程序或事件侦听器,但这两者之间是有区别的。此外,不能对事件目标事件类型执行阶段都相同的对象注册多个相同的事件侦听器。 关于这一篇章有太多对于我来说杂且乱的知识点,单单是分别DOM层级划分我看过的文章就有(0,2,3)的,(0,2)的,由于自己知识掌握还很薄弱所以只能参考别人文章结合自己理解来写,这其中也涉及到...

    WelliJhon 评论0 收藏0
  • javascript -- 事件--事件流-- 冒泡 --捕获

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

    leeon 评论0 收藏0

发表评论

0条评论

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