1. 程式人生 > >事件冒泡 以及onmouseenter 、 onmouseover(冒泡) 、onmousemove(冒泡)的區別

事件冒泡 以及onmouseenter 、 onmouseover(冒泡) 、onmousemove(冒泡)的區別

一. onmouseenter、onmouseover

onmouseenter 事件在滑鼠指標進入到繫結事件的那個元素上時觸發。
該事件通常與 onmouseleave(在滑鼠指標離開繫結事件的那個元素上時觸發) 事件一同使用。
onmouseenter 事件類似於 onmouseover 事件。 唯一的區別是 onmouseenter 事件不支援冒泡

二. 例項演示onmousemove, onmouseenter 和 mouseover 事件的不同

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        div {
            width: 100px;
            height: 100px;
            border: 1px solid black;
            margin: 10px;
            float: left;
            padding: 30px;
            text-align: center;
            background-color: lightgray;
        }
        p {
            background-color: white;
        }
    </style>
</head>
<body>
    <h3>該例項演示了 onmousemove, onmouseenter 和 onmouseover 的不同。</h3> 
    <p> onmousemove 事件在滑鼠移動到 div 元素上就開始時觸發,在這個div上移動一直觸發(冒泡)。</p> 
    <p> mouseenter 事件中有在滑鼠指標進入 div 元素時觸發(不冒泡)。 </p> 
    <p> onmouseover 事件在滑鼠指標進入 div 元素時觸發,在子元素上也會觸發(p 和 span)(冒泡)。</p> 
    <hr>
    <div onmousemove="myMoveFunction()"> 
    <p>onmousemove: <br> <span id="demo">滑鼠移動到我這!</span></p> </div> 
    <div onmouseenter="myEnterFunction()"> <p>onmouseenter: <br> <span id="demo2">標移動到我這!</span></p> </div> 
    <div onmouseover="myOverFunction()"> <p>onmouseover: <br> <span id="demo3">標移動到我這!</span></p> </div> 
</body>
<script>
    var x = 0,y = 0,z = 0;
    
    function myMoveFunction() {
        document.getElementById("demo").innerHTML = z+=1;
    }
    
    function myEnterFunction() {
        document.getElementById("demo2").innerHTML = x+=1;
    }
    
    function myOverFunction() {
        document.getElementById("demo3").innerHTML = y+=1;
    }
</script>
</html>
<!DOCTYPE html> 

其中:
1. onmousemove 事件在滑鼠移動到 div 元素上時觸發,滑鼠在div、p、span元素內移動(即白框內也會觸發,事件冒泡到父級div);
2. mouseenter 事件中有在滑鼠指標進入 div 元素時觸發,滑鼠進入p、span元素內不會觸發,因為不支援事件冒泡;
3. onmouseover 事件在滑鼠指標進入 div 元素時觸發,在子元素上也會觸發(p 和 span),因為事件冒泡到父級div。

三. 事件冒泡

比如說父元素添加了onclick事件,當子元素髮生onclick事件時,父元素的onclick事件也會觸發。

四. 終止事件冒泡

方式一:   

    event.stopPropagation()
    在子元素相應的處理函式內,加入 event.stopPropagation() ,終止事件的廣播分發,這樣事件停留在本節點,不會再往外傳播了。

方式二:
    if(event.target == event.currentTarget) {    ……}
    事件包含最初觸發事件的節點引用 和 當前處理事件節點的引用,那如果節點只處理自己觸發的事件即可,不是自己產生的事件不處理。event.target 引用了產生此event物件的dom 節點,而event.currrentTarget 則引用了當前處理節點,我們可以通過這 兩個target 是否相等。event.target永遠是直接接受事件的目標DOM元素。

document.getElementById("box1").addEventListener("click",function(event){ 
    if(event.target == event.currentTarget) { 
        alert("您好,我是最外層div。"); 
    }
}); 

比較:
從事件傳遞上看:方法一在於取消事件冒泡,即當某些節點取消冒泡後,事件不會再向上傳遞;方法二在於不阻止冒泡,過濾需要處理的事件,事件處理後還會繼續傳遞;
分析方法二,既然事件是冒泡傳遞的,那可不可以讓某個父節點統一處理事件,通過判斷事件的發生地(即事件產生的節點),然後做出相應的處理呢?答案是可以的,下面通過給body 元素新增事件監聽,然後通過判斷event.target 然後對不同的target產生不同的行為。
 

window.onload = function() { 
    document.getElementById("body").addEventListener("click",eventPerformed()); } 
    function eventPerformed(event) { 
        var target = event.target; 
        switch (target.id) { 
            case "span": 
            alert("您好,我是span。"); 
            break; 
            case "box2": 
            alert("您好,我是第二層div。"); 
            break; 
            case "box1": 
            alert("您好,我是最外層div。"); 
            break; 
        } 
    } 
}

即將每一個元素都處理事件的模式改成有上層節點統一處理事件,通過事件發生的不同節點執行不同行為。這個模式,就是所謂的事件委託