$(this)和event.target之间的区别?


157

我是jQuery的新手,并且按照JavaScript和jQuery的教程:缺少的手册制作选项卡式面板,当作者这样做时,第一行是:

   var target = $(this);

但是我试图那样做

   var target = evt.target;

我得到了这个错误:

Uncaught TypeError: Object http://localhost/tabbedPanels/#panel1 has no method 'attr'

当我改evt.target回时$(this),它就像一种魅力。

我想知道$(this)和之间有什么区别evt.target

如果您需要,这是我的代码:

index.html:

<!DOCTYPE html>
<html>
    <head>
        <title>Tabbed Panel</title>
        <style>
            body {
               width : 100%;
               height: 100%;
            }

            #wrapper {
                margin : auto;
                width : 800px;                
            }

            #tabsContainer {
                overflow: hidden;
            }

            #tabs {                
                padding:0;
                margin:0;
            }                

            #tabs li {
                float : left;
                list-style:none;
            }

            #tabs a {
                text-decoration:none;
                padding : 3px 5px;                
                display : block;                
            }

            #tabs a.active {
                background-color : grey;                
            }            
            #panelsContainer {
                clear: left;
            }            
            #panel1 {
                color : blue;
            }            
            #panel2 {
                color : yellow;
            }
            #panel3 {
                color: green;
            }
            #panel4 {
                color : black;
            }         

        </style>
        <script type="text/javascript" src="jquery-1.8.0.min.js"></script>
        <script type="text/javascript" src="script.js"></script>        
    </head>

    <body>
        <div id="wrapper">
            <div id="tabsContainer">
                <ul id="tabs">
                    <li><a href="#panel1">Panel1</a></li>
                    <li><a href="#panel2">Panel2</a></li>
                    <li><a href="#panel3">Panel3</a></li>
                    <li><a href="#panel4">Panel4</a></li>
                </ul>
            </div>
            <div id="panelsContainer">
                <div id="panel1" class="panel">
                    this is panel1
                </div>
                <div id="panel2" class="panel">
                    this is panel2
                </div>
                <div id="panel3" class="panel">
                    this is panel3
                </div>
                <div id="panel4" class="panel">
                    this is panel4
                </div>                
            </div>
        </div>

    </body>

</html>

script.js:

$(function(){
    $("#tabs a").click(function(evt){
       var target = evt.target,
           targetPanel = target.attr("href");
       $(".panel").hide();
       $("#tabs a.active").removeClass("active");
       target.addClass("active").blur();
       $(targetPanel).fadeIn(300);
       evt.preventDefault();
    });

    $("#tabs a:first").click();
})

7
this是对JavaScript DOM元素的引用。$()是jQuery提供的将DOM元素转换为jQuery对象的格式。使用evt.target您引用一个元素,而使用$(this)您引用具有我们可以访问的参数的对象。
Ohgodwhy 2012年

2
您可以这样做,$(evt.target)并且(在这种情况下)最终也会得到相同的结果。该.attr()方法由jQuery对象,而不是元件本身提供
BLSully

Answers:


294

和之间存在差异,这一个很大的差异。尽管(或参见下文)始终是指侦听器附加到的DOM元素,但实际上是被单击的DOM元素。请记住,由于事件冒泡,如果您有$(this)event.targetthisevent.currentTargetevent.target

<div class="outer">
  <div class="inner"></div>
</div>

并将点击侦听器附加到外部div

$('.outer').click( handler );

那么handler当您在外部div以及内部div内单击时,将调用(除非您有其他代码可以处理内部div上的事件并停止传播)。

在此示例中,当您在内部div中单击时,然后在中handler

  • this引用.outerDOM元素(因为这是处理程序所附加的对象)
  • event.currentTarget也指.outer元素(因为这是处理事件的当前目标元素)
  • event.target引用.inner元素(这为您提供了事件起源的元素)

jQuery包装器$(this)仅将DOM元素包装在jQuery对象中,因此您可以在其上调用jQuery函数。您可以使用进行相同的操作$(event.target)

还要注意,如果您重新绑定的上下文this(例如,如果您使用Backbone,它将自动完成),则它将指向其他内容。您始终可以从获取实际的DOM元素event.currentTarget


在此示例中,如果您单击内部元素并使用event.currentTarget,您是获得内部元素还是外部元素?
merlinpatt 2015年

3
currentTarget总是与处理程序一起使用,即。最外面的一个
Petr Bela 2015年

“在这种情况下”是指单击“ .inner”而不是单击“ .outer”,然后event.target会引用内部元素吗?您的示例没有说明实际单击的内容,但我想确定在编辑之前。:)
Nils Sens

@NilsSens是的,这意味着您单击“内部”。我会说清楚。
彼得·贝拉

39

this是要为其处理事件的DOM元素(当前目标)的引用。event.target指发起事件的元素。在这种情况下,它们是相同的,并且通常可以,但是不一定总是如此。

通过回顾jQuery event docs可以很好地了解这一点,但总而言之:

event.currentTarget

事件冒泡阶段中的当前DOM元素。

event.delegateTarget

当前调用的jQuery事件处理程序所附加的元素。

event.relatedTarget

事件中涉及的另一个DOM元素(如果有)。

事件目标

启动事件的DOM元素。

要获得使用jQuery所需的功能,你都必须用它包装在一个jQuery对象:$(this)或者$(evt.target)

.attr()方法仅适用于jQuery对象,不适用于DOM元素。$(evt.target).attr('href')或只是evt.target.href会给你你想要的。


他们并不一定要相同的元素都引用。请参阅彼得的答案。
kralyk 2014年

1
确实如此,感谢您指出这一点。重读我的旧答案总是很有趣的……
nbrooks,2014年

8

jQuery使用“ on”方法处理此变量的方式有很大不同

$("outer DOM element").on('click',"inner DOM element",function(){
  $(this) // refers to the "inner DOM element"
})

如果将此与:-

$("outer DOM element").click(function(){
  $(this) // refers to the "outer DOM element"
})

4

http://api.jquery.com/on/指出:

当jQuery调用处理程序时,this关键字是对传递事件的元素的引用;对于直接绑定的事件 this,元素是附加事件this的元素;对于委托的事件,元素是匹配选择器的元素。(请注意,这this可能不等于event.target事件是从后代元素冒泡的。)

要从该元素创建一个jQuery对象,使其可以与jQuery方法一起使用,请使用$(this)。

如果我们有

<input type="button" class="btn" value ="btn1">
<input type="button" class="btn" value ="btn2">
<input type="button" class="btn" value ="btn3">

<div id="outer">
    <input type="button"  value ="OuterB" id ="OuterB">
    <div id="inner">
        <input type="button" class="btn" value ="InnerB" id ="InnerB">
    </div>
</div>

检查以下输出:

<script>
    $(function(){
        $(".btn").on("click",function(event){
            console.log($(this));
            console.log($(event.currentTarget));
            console.log($(event.target));
        });


        $("#outer").on("click",function(event){
            console.log($(this));
            console.log($(event.currentTarget));
            console.log($(event.target));
        })
    })
</script>

请注意,我$通常使用包裹dom元素来创建jQuery对象,这是我们一直以来的工作方式。

你会发现,对于第一种情况,thisevent.currentTargetevent.target都参照相同的元素。

在第二种情况下,当触发某个包装元素的事件委托时,event.target将引用该触发元素,而thisevent.currentTarget引用该事件的传递位置。

对于thisevent.currentTarget,根据http://api.jquery.com/event.currenttarget/,它们是完全一样的


3

这里有跨浏览器的问题。

典型的非jQuery事件处理程序如下所示:

function doSomething(evt) {
    evt = evt || window.event;
    var target = evt.target || evt.srcElement;
    if (target.nodeType == 3) // defeat Safari bug
        target = target.parentNode;
    //do stuff here
}

jQuery规范化evt了目标并使其可以this在事件处理程序中使用,因此典型的jQuery事件处理程序将如下所示:

function doSomething(evt) {
    var $target = $(this);
    //do stuff here
}

使用jQuery的规范化对象evt和POJS目标的混合事件处理程序将如下所示:

function doSomething(evt) {
    var target = evt.target || evt.srcElement;
    if (target.nodeType == 3) // defeat Safari bug
        target = target.parentNode;
    //do stuff here
}

0

在事件处理函数或对象方法中,访问“包含元素”的属性的一种方法是使用特殊的this关键字。this关键字表示当前正在处理的函数或方法的所有者。所以:

  • 对于全局函数,这表示窗口。

  • 对于对象方法,这表示对象实例。

  • 在事件处理程序中,这表示接收事件的元素。

例如:

<!DOCTYPE html>
<html>
    <head>
        <script>
        function mouseDown() {
            alert(this);
        }
        </script>
    </head>
    <body>
        <p onmouseup="mouseDown();alert(this);">Hi</p>
    </body>
</html>

呈现此html后的警报窗口的内容分别为:

object Window
object HTMLParagraphElement

事件对象与所有事件关联。它具有提供“有关事件”信息的属性,例如在网页中单击鼠标的位置。

例如:

<!DOCTYPE html>
<html>
    <head>
        <script>
        function mouseDown(event) {
            var theEvent = event ? event : window.event;
            var locString = "X = " + theEvent.screenX + " Y = " + theEvent.screenY;
            alert(event);
                    alert(locString);
        }
        </script>
    </head>
    <body>
        <p onmouseup="mouseDown(event);">Hi</p>
    </body>
</html>

呈现此html后的警报窗口的内容分别为:

object MouseEvent
X = 982 Y = 329
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.