JavaScript捕获和冒泡探讨

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

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

事件的执行顺序java

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

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

JavaScript捕获和冒泡探讨code

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

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

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

在上面的代码若是增长一个div.addEventListener('click',callbackdiv2,false);ip

则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:半个月没发文章,由于我最近在搞这个:开发头条网,而后我发现这个东西作好和作坏根本没有出路,我考虑要不要下掉,呜呜……,请赐予我动力吧。

相关文章
相关标签/搜索