2017-06-29 145 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”。

相关问题