2015-12-06 15 views
2

我有三個格箱Click事件儘管點擊處理程序使用addEventListener(事件冒泡被禁用))

對父母設定的第一個div主要有"main" ID和包含其他兩個箱用ID "menu_header""menu_options"

這是我的HTML

<div id="main"> 
<div id="menu_header"> 
    </div> 
    <div id="menu_options"> 
    </div> 
</div> 
<span>Something here</span> 

這是我的CSS

#main{ 
    display:table-cell; 
    position:relative; 
    top:100px; 
    border:solid purple; 
} 
#menu_header{ 
    position:relative; 
    border:solid black; 
    background:red; 
    width:100px; 
    top:200px; 
    height:100px; 
/* -moz-transition-property:bottom; 
    -moz-transition-duration:2s; 
    transition-property:top; 
    transition-duration:1s;*/ 
} 
#menu_options{ 
    background:blue; 
    position:absolute; 
    bottom:0%; 
    border:solid black; 
    width:100px; 
    height:100px; 
} 
/*#menu_header:active{ 
    top:100px; 
}*/ 

(忽略CSS過渡,因爲它被註釋掉)

這是我的javascript

function test(e){ 
//if(e.target.id=="menu_options"){return}; 
$('#menu_header').animate({top:'-10'},1000); 
    //var t=document.getElementById('menu_header') 
// t.setAttribute('top','40px'); 
    t.style="position:relative;border:solid black;background:red;width:100px;top:60px;height:100px;" 
} 
document.getElementById('main').addEventListener('click',test,false) 

終於這是我的實驗室老鼠的jsfiddle鏈接 http://jsfiddle.net/repzeroworld/ev7k688s/

在這種情況下, n個I設置單擊事件處理我的父容器上的ID爲"main"一切完美,只是每當點擊此父的容器中的子DIV ID爲"menu_options"這也引發

我發現下面的鏈接,但不知何故這裏event.propogation()解決方案的處理程序似乎不適用於我的情況。

clicking on child element also triggers click event on it parent

一個討厭的黑客,防止任何行動執行如果孩子的div捕獲的事件是

if(e.target.id=="menu_header"){return}; 

上面我在javascript代碼註釋掉。

問: 爲什麼id爲"menu_options"從父容器的id "main"捕捉事件,儘管我對設置add EventListenerfalse孩子div來阻止事件冒泡?

+2

這是'event.stopPropagation()','不event.propagation()'。用'addEventListener()'設置'false'不會禁止冒泡。 –

回答

3

原因

傳遞false.addEventListener()不會禁用冒泡。它只是讓事件在冒泡階段而不是捕獲階段觸發。

當事件發生時,它從DOM的根開始並進入「捕獲」階段。這意味着該事件從documentevent.target的運行方式,發射出沿途發現的任何「捕獲」處理程序。

一旦到達event.target,它就會逆轉過程,並且返回到document,調用它找到的任何「冒泡」處理程序。

因此,因爲您通過了false作爲第三個參數,處理程序將在最後一個「冒泡」階段被調用。

所以你看,這沒有做任何事情來防止嵌套元素調用處理程序。


解決方案

如果要調用的實際元素上點擊時的處理程序,並沒有它的孩子,只是暫停處理,如果this不等於e.target

function test(e){ 
    if (this != e.target) 
     return; 

    $('#menu_header').animate({top:'-10'},1000); 
    var t=document.getElementById('menu_header') 
    t.setAttribute('top','40px'); 
    t.style="position:relative;border:solid black;background:red;width:100px;top:60px;height:100px;" 
} 
document.getElementById('main').addEventListener('click',test,false) 
+0

這是非常可以理解的!我嘗試使用if(this!= e.target); return「...但沒有任何反應......任何建議? – repzero

+0

我將「this!= e.target」替換爲「document.getElementById('menu_options')!= e.target」......堅持我的問​​題,即要求解釋爲什麼我遇到這個問題..我將接受這個答案......:D – repzero

1

您可以通過2場景限制事件冒泡。 1.將Click事件放在每個DOM對象上,意思是將子對象放在父對象上並放入event.stropPropagation()。 2.使用e.target.id識別DOM對象,並返回「假」。[我們正在使用這種]下面

<script> 
     function test(e) { 
      if (e.target.id == "menu_header") { return } 
      else if (e.target.id == "menu_options") { return } 
      $('#menu_header').animate({ top: '-10' }, 1000); 
      var t = document.getElementById('menu_header') 
      t.setAttribute('top','40px'); 
      t.style = "position:relative;border:solid black;background:red;width:100px;top:60px;height:100px;" 
     } 
     window.onload = function() { 
     document.getElementById('main').addEventListener('click', test, false); 
    } 
</script> 
+0

這也不錯 – repzero

+0

謝謝repzero。 –

1

嘗試

代碼停在子元素傳播。請參閱here

function test(){ 
$('#menu_header').animate({top:'10'},1000); 
    //var t=document.getElementById('menu_header') 
// t.setAttribute('top','40px'); 
    //t.style="position:relative;border:solid black;background:red;width:100px;top:60px;height:100px;" 
} 

function stopPropagation(e){ 
    e.stopPropagation(); 
} 

document.getElementById('main').addEventListener('click',test,false); 

document.getElementById('menu_header').addEventListener('click',stopPropagation,false); 
+0

這真的很聰明...和可笑的美麗! – repzero

+0

謝謝,如果這是您尋找的解決方案,請將其標記爲已接受的答案。 – Raman