2017-06-29 63 views
3

http://jsbin.com/xaguxuhiwu/1/edit?html,js,console,output爲什麼e.currentTarget會隨着jQuery的事件委託而改變?

<div id="container"> 
    <button id="foo">Foo button</button> 
    <button id="bar">Bar button</button> 
    </div> 

$('#container').on('click', function(e) { 
    var targetId = e.target.getAttribute('id'); 
    // Manually do event delegation 
    if (targetId === 'foo') { 
    var currentId = e.currentTarget.getAttribute('id'); 
    console.log('without delegation, currentTarget is: ' + currentId); 
    } 
}); 

$('#container').on('click', '#foo', function(e) { 
    var currentId = e.currentTarget.getAttribute('id'); 
    console.log('with delegation, currentTarget is: ' + currentId); 
}); 

基本上,我對事件e.currentTarget的理解是,它反映了該事件已冒泡的地步。由於我在#container元素上有一個事件監聽器,我預計在這兩種情況下currentTarget都是container

對於標準on處理程序,這是正確的,如第一個示例所示。但是,使用事件委託(第二次單擊時參數#foo)時,currentTarget將更改爲內部按鈕。

爲什麼e.currentTarget在兩種情況之間改變? 具體而言,在後一種情況下,這是否意味着jQuery不會將事件偵聽器放在父元素(#container)元素上?

+0

在第二個函數中,當你點擊一個id =「foo」的元素時,你就會告訴jquery「Fire事件,它嵌套在id =」container「元素的某處。加載你的html元素,而不是在DOM加載後插入,你在技術上不需要'.on',而在第二個函數中,你可以訪問元素'#foo',而不必首先引用元素'#容器' –

+0

另外,不用'e.currentTarget',你可以使用'this'。用vanilla JS你可以把'e.currentTarget.getAttribute('id')'改成'this.id'和'$(this).attr ('id')'在jQuery中。 –

+0

@AaronEveleth:這不是我對jQuery中'.on'的理解。 '.on()'應該將一個監聽器添加到前一個選擇器中的任何元素。 當你添加第二個參數(又名使用事件委託)時,我的理解是jQuery不會調用回調函數,除非'event.target'匹配選擇器。 – AnilRedshift

回答

5

基本上是因爲jQuery魔法幕後。包裝本地事件的jQuery事件對象正在改變currentTarget,這可能更方便。

要訪問通常由currentTarget指向的值,jQuery事件有delegateTarget

此屬性是最經常是有用的由.delegate().on(),其中所述事件處理程序被安裝在正被處理的元素的祖先附委派事件。例如,它可用於在代表點識別和刪除事件處理程序。

對於直接附加到元素的非委託事件處理程序,event.delegateTarget將始終等於event.currentTarget

你可以看到在originalEvent,currentTarget有您所期望的值。

$('#container').on('click', function(e) { 
 
    console.log('without delegation:'); 
 
    console.log('target: ' + e.target.getAttribute('id')); 
 
    console.log('currentTarget: ' + e.currentTarget.getAttribute('id')); 
 
    console.log('originalEvent.currentTarget: ' + e.originalEvent.currentTarget.getAttribute('id')); 
 
    console.log('delegateTarget: ' + e.delegateTarget.getAttribute('id')); 
 
    console.log('--'); 
 
}); 
 
$('#container').on('click', '#foo', function(e) { 
 
    console.log('with delegation:'); 
 
    console.log('target: ' + e.target.getAttribute('id')); 
 
    console.log('currentTarget: ' + e.currentTarget.getAttribute('id')); 
 
    console.log('originalEvent.currentTarget: ' + e.originalEvent.currentTarget.getAttribute('id')); 
 
    console.log('delegateTarget: ' + e.delegateTarget.getAttribute('id')); 
 
    console.log('--'); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
<div id="container"> 
 
    <button id="foo">Foo button</button> 
 
    <button id="bar">Bar button</button> 
 
</div>

+1

如果你像我這樣的書呆子,想看看jQuery在做什麼[源代碼在event.js的'dispatch'部分](https://github.com/jquery/jquery/blob/master /src/event.js#L324)。 –

+0

謝謝,這有助於。我想知道爲什麼這是由框架完成的?這不會總是使得'e.target' ==='e.currentTarget'? – AnilRedshift

+0

哦,我橡膠鴨子我自己的解決方案。假設您有三個div的層次結構:祖父母,父母和孩子。如果你在$('#grandparent')。on('click','#parent',...),那麼e.target應該是子對象,e.currentTarget(jQuery對象)就是父對象。 – AnilRedshift

0

簡單地說,在 「#foo」 是當前的DOM元素,因爲這是你點擊了什麼。它僅僅是父母(或父母的父母等)恰好是「#container」的DOM元素。

的回答你的問題,因此是「事件冒泡階段內的當前 DOM元素。」 [按照jQuery文檔)是「#foo」。

同樣,如果你叫$(document).on("click","#foo",...你的currentTarget也是「#foo」。

相關問題