js 事件冒泡与事件捕获

一、事件冒泡

事件冒泡是指在事件发生过程中先从目标节点开始执行,并一层一层的相父节点依次查询直到document,并执行相同事件的过程。

 btn1.addEventListener('click',function(e){
        //true 为事件捕获,false 为事件冒泡
        //false为默认方式,冒泡方式执行
        //点击btn1时,如果是事件冒泡,则先执行btn1上的click事件,然后执行父元素div1上的click事件
        //如果是事件捕获,则先执行父元素上的click事件,然后执行btn1上的click事件
        var e= e||window.event;
        alert('你点击了btn1');
    },false);
div1.addEventListener('click',function(e){

alert('你点击了div1');
},false);
 

这样的写法,当你点击btn1的时候,先弹出“你点击了btn1”,然后弹出“你点击了div1”;

二、事件捕获

事件捕获就是在事件发生过程中,先从document开始执行相同的事件,依次一层一层查找到目标节点,然后执行相同的事件。

btn1.addEventListener('click',function(e){
        //true 为事件捕获,false 为事件冒泡
        //false为默认方式,冒泡方式执行
        //点击btn1时,如果是事件冒泡,则先执行btn1上的click事件,然后执行父元素上的click事件
        //如果是事件捕获,则先执行父元素上的click事件,然后执行btn1上的click事件
        var e= e||window.event;
        alert('你点击了btn1');
    },true);


    div1.addEventListener('click',function(e){

        alert('你点击了div1');
    },true);

这样的写法,当你点击btn1的时候,先弹出“你点击了div1”,然后弹出“你点击了btn1”;

三、阻止事件冒泡和事件捕获

在阻止事件冒泡和捕获方式上,IE和其他浏览器不同;

首先是event的不同;

Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。

事件通常与函数结合使用,函数不会在事件发生前被执行!

在IE中输出的event 为 event;event在IE中为全局函数,可以在任何地方调用。

在FF中输出的为event; 在FF中只能在实践中调用,把event作为参数传进函数内

其他浏览器  则为二者都可以;

所以在确定event的时候需要进行浏览器兼容

 var e = event||window.event;

等同于 e = e?event:window.event;

通过这种方法,IE识别event,其他浏览器识别window.event; 

在阻止事件方法上也有不同

IE:e.cancelBubble = true; 通过把e.cancelBubble设置为true,来阻止事件分发;

标准浏览器:e.stopPropagation();  标准浏览器的stopPropagation 方法可以设置不再派发事件。

兼容代码如下:

    var e = event||window.event;
        if(e.stopPropagation){
            e.stopPropagation();//标准浏览器
        }else{
            e.cancelBubble = true;//IE浏览器
        }

四、事件委托方法依托事件冒泡机制

传统事件绑定

我们给每一个li绑定点击之后背景颜色变红的事件;

var uli = document.getElementById('uli');
    var lis = uli.getElementsByTagName('li');
    for (var i = 0;i<lis.length;i++){
        lis[i].onclick = function(){
           this.style.backgroundColor = 'red';
        }
    }
    //这样我们就可以做到li上面添加鼠标事件。
    //但是如果说我们可能有很多个li用for循环的话就比较影响性能。

一个事件委托实例

html不变,只更改事件绑定的方法

 var uli = document.getElementById('uli');
    uli.addEventListener('click',function(event){
        var e = event||window.event;

        var target = e.target||e.srcElement;//该方法用于查询发生event事件的具体节点。
        //e.target  是标准浏览器的方法
        //e.srcElement 是IE中的方法
        if (target.nodeName.toUpperCase()=='LI'){
            target.style.backgroundColor = 'red';
        }
    });

标准浏览器查询event节点的方法是:window.event.target;

IE浏览器查询event节点的方法是:event.srcElement;

这样的写法可以在点击li的时候向上冒泡至ul,然后执行ul上的绑定事件,这样就不用给每个li都绑定一个点击事件.

而且新添加的li元素也可以绑定这样的事件,不用重新绑定

可以用removeElementListener 来取消绑定的事件函数

五、绑定事件监听方法

传统绑定事件

on + click、mouseover、keyup 等

传统绑定的

优点

  • 非常简单和稳定,可以确保它在你使用的不同浏览器中运作一致
  • 处理事件时,this关键字引用的是当前元素,这很有帮助

缺点

     绑定同样事件的多个函数会覆盖,只能触发最后一种。

uli.onclick = function(){

  alert('1');

uli.onclick = function(){

  alert('2');

}

这样的写法执行时只能执行alert('2');   解除绑定用 uli.onclick = null;

W3C绑定事件

uli.addEventListener('click',function(){.........},false);

  1. W3C绑定的优点
    • 该方法同时支持事件处理的捕获和冒泡阶段。事件阶段取决于addEventListener最后的参数设置:false (冒泡) 或 true (捕获)。
    • 在事件处理函数内部,this关键字引用当前元素。
    • 事件对象总是可以通过处理函数的第一个参数(e)捕获。
    • 可以为同一个元素绑定你所希望的多个事件,同时并不会覆盖先前绑定的事件
  2. W3C绑定的缺点
    • IE不支持,你必须使用IE的attachEvent函数替代。

解除绑定用 removeEventListener('click',fucntion(){.........});

IE绑定事件

IE用attachEvent方法绑定事件

element.attachEvent('onclick', function(){
        // ...
    });
  1. IE方式的优点
    • 可以为同一个元素绑定你所希望的多个事件,同时并不会覆盖先前绑定的事件。
  2. IE方式的缺点
    • IE仅支持事件捕获的冒泡阶段
    • 事件监听函数内的this关键字指向了window对象,而不是当前元素(IE的一个巨大缺点)
    • 事件对象仅存在与window.event参数中
    • 事件必须以ontype的形式命名,比如,onclick而非click
    • 仅IE可用。你必须在非IE浏览器中使用W3C的addEventListene

解除绑定函数用 detachEvent('onclick',fucntion(){})

原文地址:https://www.cnblogs.com/RoadAspenBK/p/7397784.html