记一次事件对象,捕获,冒泡

479 阅读4分钟

事件的三个要素:事件源,事件类型,事件处理程序。

事件分为三个阶段:事件捕获->事件目标->事件冒泡

事件捕获:

事件发生时,首先会发生在document对象上,然后依次向下传递,最后到达目标节点。

冒泡事件:

事件到达目标后节点后不会结束的,而是依次向上传递,直至document对象,在向上传递过程中,父节点中有和自己绑定了同样的事件,父节点的事件也会触发。

addEventListener

通过使用addEventListener对事件进行绑定,他有三个参数,第一个是事件类型,第二个是执行函数,第三个是一个boolean值,默认是false,表示事件冒泡触发,设置为true是捕获触发。只执行一次,事件类型不加on。 通过event事件对象中的,event.stopPropagation()方法来阻止事件冒泡和捕获。

通过事件对象event中event.preventDefault( ),阻止默认事件,比如a标签和表单的submit事件。

removeEventListener

removeEventListener解绑事件,参数和addEventListener一样。

IE浏览器使用:attachEvent

attachEvent对事件进行绑定的,它只支持冒泡触发,事件类型要加on。 通过event事件对象中的,event.cancelBubble设置为true来阻止事件冒泡。

设置event事件对象中event.returnValue 为 false来阻止默认事件;

IE浏览器使用:detachEvent

detachEvent解绑事件

事件委托:

利用事件冒泡的特性,将里层的事件委托给外层事件,使用事件委托能够避免对特定的每个节点添加事件监听器;事件监听器是被添加到它们的父元素上。事件监听器会分析从子元素冒泡上来的事件,找到是哪个子元素的事件。

<table id="out" border="1" style="cursor: pointer;">
    <tr>
    &emsp;&emsp;<td>table01</td>
    &emsp;&emsp;<td>table02</td>
    &emsp;&emsp;<td>table03</td>
    &emsp;&emsp;<td>table04</td>
    &emsp;&emsp;<td>table05</td>
    &emsp;&emsp;<td>table06</td>
    &emsp;&emsp;<td>table07</td>
    &emsp;&emsp;<td>table08</td>
    &emsp;&emsp;<td>table09</td>
    &emsp;&emsp;<td>table10</td>
    </tr>
</table>
var out = document.getElementById("out");
 2     if(out.addEventListener){
 3         out.addEventListener("click",function(e)   {
 4             var e = e||window.event;
 5             //IE没有e.target,有e.srcElement
 6             var target = e.target||e.srcElement;
 7             //判断事件目标是否是td,是的话target即为目标节点td
 8             if(target.tagName.toLowerCase()=="td"){
 9                 changeStyle(target);
10                 console.log(target.innerHTML);
11             }
12         },false);
13     }else{
14         out.attachEvent("onclick",function(e){
15             var e = e||window.event;
16             //IE没有e.target,有e.srcElement
17             var target = e.target||e.srcElement;
18             //判断事件目标是否是td,是的话target即为目标节点td
19             if(target.tagName.toLowerCase()=="td"){
20                 changeStyle(target);
21                 console.log(target.innerHTML);
22             }
23         });
24     };
25 };
26 function changeStyle(ele){
27     ele.innerHTML = "已点击"
28     ele.style.background="#900";
29     ele.style.color = "#fff"; }   

事件绑定以及事件解绑封装成为一个函数,兼容浏览器,包括IE6及以上

function addEvent(element, eType, handle, bol) {
    if(element.addEventListener){           //如果支持addEventListener
        element.addEventListener(eType, handle, bol);
    }else if(element.attachEvent){          //如果支持attachEvent
        element.attachEvent("on"+eType, handle);
    }else{                                  //否则使用兼容的onclick绑定
        element["on"+eType] = handle;
    }
}

事件解绑

function removeEvent(element, eType, handle, bol) {
    if(element.addEventListener){
        element.removeEventListener(eType, handle, bol);
    }else if(element.attachEvent){
        element.detachEvent("on"+eType, handle);
    }else{
        element["on"+eType] = null;
    }
}

事件对象兼容写法:

获得event对象兼容性写法 
event || (event = window.event);
获得target兼容型写法 
event.target||event.srcElement
阻止浏览器默认行为兼容性写法 
event.preventDefault ? event.preventDefault() : (event.returnValue = false);
阻止冒泡和捕获写法 
event.stopPropagation ? event.stopPropagation() : (event.cancelBubble = true);

事件-行内和动态绑定的区别

1.行内绑定

没有事件对象event,this的指向window, 不利于后期维护

<body>
    <div id="div1" onclick="div1()">
        <div id="div2" onclick="div2()">
            <div id="div3" onclick="div3()"></div>
        </div>
    </div>
    <script>
        function div1() {
            console.log(1)
        }
        function div2() {
            console.log(2)
        }
    
        function div3() {
            console.log('3')
        }
    </script>
</body>
2.动态绑定

有事件对象event,动态绑定this指向了当前正在操作的DOM元素;

<body>
    <div id="div1" onclick="div1()">
        <div id="div2" onclick="div2()">
            <div id="div3" onclick="div3()"></div>
        </div>
    </div>
    <script>
        var div1 = document.getElementById('div1');
        var div2 = document.getElementById('div2');
        var div3 = document.getElementById('div3');

        div1.onclick = function(e) {
            e.cancelBubble = true || e.stopPropagation()
            console.log('1', e)
        }
        div2.onclick = function(e) {
            e.cancelBubble = true || e.stopPropagation()
            console.log('2', e)
        }
        div3.onclick = function(e) {
            e.cancelBubble = true || e.stopPropagation()
            console.log('3', e)
        }
    </script>
</body>

封装一个函数,用于获取指定id的Dom元素

function getDomId(eleId) {
    return document.getElementById(eleId)
}

getDomId('div1').onclick = function(e) {
    e.cancelBubble = true || e.stopPropagation()
    console.log('1', e)
}
getDomId('div2').onclick = function(e) {
    e.cancelBubble = true || e.stopPropagation()
    console.log('2', e)
}
getDomId('div3').onclick = function(e) {
    // e.cancelBubble = true || e.stopPropagation()
    console.log('3', e)
}