1

我需要使用事件委託來捕獲帶有圖像的錨節點。使用javascript冒泡/捕獲檢測中間節點

document.addEventListener(
 
    'click', 
 
    function(event) { 
 
    console.log(event.target); 
 
    return true; 
 
    }, 
 
    false 
 
);
<a href="#" class="link"> 
 
    <img src="http://placehold.it/100x100" alt=""> 
 
</a>

event.target總是IMG

如何檢查點擊是否在類爲.link的節點上進行?

UPDATE:要清楚這裏是an example with jQuery

當我使用jQuery.on()有a節點this財產回調溫控功能,不img節點。使用純JS,我只能確定初始目標。

+0

[什麼是事件冒泡和捕獲?](http:// stackoverflow。com/questions/4616694/what-is-event-bubbling-and-capturing) – Christoph

+0

@Christoph這個問題的範圍比這個範圍窄得多,它引用了一個特定的問題,而不是比較兩個方法。 – freginold

+1

@freginold我意識到這一點,但我認爲答案非常徹底,可能有助於OP更好地理解這個概念。 OPs問題的簡短回答就是:「事件目標始終是您點擊的實際元素。」 ;) – Christoph

回答

1

你可以通過調用檢查元素是否有一個類:

element.classList.contains('link'); 

你想現在什麼是<a class="link">內的<img>被點擊時做一些事情。要確定點擊的<img>是否有家長<a class="link">,我們必須遍歷其父樹並進行檢查。

這是行爲你有jQuery的例子非常相似,即

$('body').on('click', '.link', callback) 

除了jQuery的一個整體的查詢,而不僅僅是一個類相匹配。

這裏是你如何能做到這一點:

// function to determine if the element has the link class 
 
const hasLinkClass = element => element 
 
    ? element.classList && element.classList.contains('link') 
 
    : false; 
 

 
// function that accepts an event handler and returns 
 
// a wrapper function arround it. 
 
// The wrapper is called it if the passed in event 
 
// object contains as its target an <img> with a parent 
 
// with .link class 
 
function filterImagesWithinLinks(handler) { 
 
    return function(event) { 
 
    let elem = event.target; 
 

 
    // ignore clicks that are not on an image (it might be better to be more specific here) 
 
    if (elem.tagName === 'IMG') { 
 
    
 
     // filter until we find the parent with .link class 
 
     while (elem && !hasLinkClass(elem)) { 
 
     elem = elem.parentNode; 
 
     } 
 

 
     // if a parent with .link class was found, 
 
     // call the original handler and set its `this` 
 
     // to the parent. 
 
     if (elem) { 
 
     handler.call(elem, event); 
 
     } 
 
    } 
 
    }; 
 
} 
 

 
// function handler that fires when 
 
// an <img> that has a parent with 
 
// class 'link' was clicked 
 
function handler(event) { 
 
    console.log('target : ', event.target); 
 
    console.log('this : ', this); 
 
} 
 

 
document.addEventListener(
 
    'click', 
 
    filterImagesWithinLinks(handler), 
 
    false 
 
);
a.link { 
 
    display: block; 
 
    padding: 10px; 
 
    background: #018bbc; 
 
} 
 

 
.middle { 
 
    background: salmon; 
 
    padding: 10px; 
 
    text-align: center; 
 
}
<a href="#" class="link"> 
 
    <p class="middle"> 
 
    <img src="http://placehold.it/100x100" alt="" /> 
 
    </p> 
 
</a>

+0

值得注意的是,箭頭功能本身不會在IE中工作。 – freginold

+1

當然,但箭頭功能只是爲了簡單和可讀性。重寫爲普通函數是微不足道的。 – nem035

+0

是的,沒有意見分歧...只是注意到,如果其他人被卡住使用IE瀏覽器(像我一樣)。 – freginold

0

如果你添加一些文字或其他內容的錨標記,它會更容易看到a和之間的區別img。查看的jsfiddle這個例子 - 它顯示是否被點擊類link的元素:

https://jsfiddle.net/Lppt4hyk/4/

下面的代碼(從你只是略有修改):

<a href="#" class="link"> Anchor 
    <img src="http://placehold.it/100x100" alt=""> 
</a> 
document.addEventListener(
    'click', 
    function(event) { 
      var patt = /(?:^link | link$|^link$| link)/g; 
      if (patt.test(event.target.className)) { 
     alert('link class was clicked'); 
     } 
     else { alert('link class was not clicked'); } 
    return true; 
    }, 
    false 
); 
div { 
    background: red; 
    display: block; 
    height: 90%; 
    width: 90%; 
} 

.n1 { 
    background: yellow; 
} 

.n2 { 
    background: green; 
} 

更新:增加了對的檢查類名(如果它不是唯一指定給該元素的類)。

更新:增加了正則表達式檢查來清除link作爲較大單詞的一部分。

+0

'event.target.className ==「link」'只適用於元素類屬性的特殊情況** ** ** **等於字符串'「link」'。它會打破任何空白或多個類。另外主要的問題是''的父母''具有類「link」。 – nem035

+0

@ nem035關於類名的好處,我會更新。 OP的問題最初有'a'和'link'類的分配;你爲什麼要刪除它? – freginold

+0

當我從jsfiddle鏈接複製了他/她的代碼時,我沒有在''上沒有''link''類。加回來了。 – nem035