2012-03-28 115 views
14

http://jsfiddle.net/walkerneo/QqkkA/Javascript事件代表團,處理點擊元素的父母?

我見過這裏的許多問題提出詢問或與JavaScript事件被授權回答,但我還沒有看到,但是,如何使用事件代表團未將是元素點擊事件的目標。

例如:

HTML:

<ul> 
    <li><div class="d"></div></li> 
    <li><div class="d"></div></li> 
    <li><div class="d"></div></li> 
    <li><div class="d"></div></li> 
    <li><div class="d"></div></li> 
    <li><div class="d"></div></li> 
</ul>​ 

CSS:

ul{ 
    padding:20px; 
} 
li{ 
    margin-left:30px; 
    margin-bottom:10px; 
    border:1px solid black; 

} 
.d{ 
    padding:10px; 
    background:gray; 
} 
​ 

如果我想添加一個click事件處理li元素正在被點擊時他們?如果我將事件處理程序附加到ul元素,則div將始終是目標元素。除了在點擊函數中檢查目標元素的每個父元素之外,我該如何實現這一點?

編輯:

我想使用事件委派代替:

var lis = document.getElementsByTagName('li'); 
for(var i=0;i<lis.length;i++){ 
    lis[i].onclick = function(){}; 
} 

但是,如果我做的:

document.getElementsByTagName('ul')[0].addEventListener('click',function(e){ 

    // e.target is going to be the div, not the li 
    if(e.target.tagName=='LI'){ 

    } 
},false); 

編輯:我沒有興趣在如何使用爲這個的Javascript庫,我感興趣的是他們是如何做到這一點以及如何用純j完成的。

+0

實際上對你的問題感到困惑,不明白你想達到什麼目的。 – 2012-03-28 19:51:34

+0

我總是搞砸了這個......這個鏈接可能有幫助:http://www.quirksmode.org/js/events_order.html – 2012-03-28 20:14:11

+1

@Michal,這似乎效率低下,我想知道這是否唯一的方法。 – mowwwalker 2012-03-29 01:11:15

回答

15

下面就來解決這個問題的一種方法:

var list = document.getElementsByTagName('ul')[0] 

list.addEventListener('click', function(e){ 
    var el = e.target 
    // walk up the tree until we find a LI item 
    while (el && el.tagName !== 'LI') { 
    el = el.parentNode 
    } 
    console.log('item clicked', el) 
}, false) 

這是過於簡化,循環將繼續向上樹甚至過去UL元素。有關更完整的示例,請參閱rye/events中的實現。

Element.matches,Node.containsNode.compareDocumentPosition方法可以幫助您實現這種類型的功能。

+0

我做了一些挖掘jQuery,這就是我發現的。 – mowwwalker 2012-03-29 00:00:04

+0

謝謝:)這就是我需要的。 – 2017-03-24 03:40:15

0

我不是一個JavaScript怪胎,但要回答你的問題(只爲好奇)我已經花了一些時間在線,幾分鐘後我發現你可以觸發一個父元素的事件也是這樣(作爲一種替代的想法,可以是我不適合)來處理點擊元素

var el=document.getElementsByTagName('ul')[0]; 
el.addEventListener('click',function(e){ 
    var elm=e.target.parentNode; 
    if(document.createEvent) 
    { 
     evt = document.createEvent('MouseEvents'); 
     evt.initMouseEvent("click", false, true, window, 
0, 0, 0, 0, 0, false, false, false, false, 0, null); 
     elm.dispatchEvent(evt); 
     liEventhandler(evt);   
    } 

}); 

function liEventhandler(e) 
{ 
    console.log(e); 
    console.log(e.target); 
    console.log(e.which); 
    alert(e.target.innerHTML); 
} 

一個例子是here的父母。

上面例子將不能在IE瀏覽使用createEventObjectfireEvent

if(document.createEventObject) 
{ 
    var evt = document.createEventObject(); 
    el.fireEvent('onclick', evt); 
    liEventhandler(evt); 
} 

也e.target是window.event。srcElement和addEventListener

el.attachEvent('onclick', function(){...}) 

ul和目標事件觸發是div我剛剛觸發的事件上li

一些參考:comp.lang.javascript2.MOZILLA DEVELOPER NETWORK3.this

0

現在有一種名爲closest的元素的方法,它正是這樣做的。它需要一個CSS選擇器作爲參數,並找到最接近的匹配祖先,它可以是元素本身。所有當前版本的桌面瀏覽器support它,但一般來說它還沒有準備好用於生產使用。上面鏈接的MDN頁面包含一個polyfill。