Unterschied zwischen $ (this) und event.target?


157

Ich bin neu in jQuery und habe nach dem Tutorial in JavaScript und jQuery Registerkarten erstellt. Das fehlende Handbuch enthält die erste Zeile, wenn der Autor dies tut:

   var target = $(this);

Aber ich habe es so versucht

   var target = evt.target;

und ich habe diesen Fehler bekommen:

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

Und als ich evt.targetzurück zu $(this)wechselte, funktionierte es wie ein Zauber.

Ich möchte wissen, was der Unterschied zwischen $(this)und ist evt.target.

Hier ist mein Code, falls Sie ihn brauchen:

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
thisist eine Referenz auf das JavaScript-DOM-Element. $()ist das von jQuery bereitgestellte Format, um das DOM-Element in ein jQuery-Objekt umzuwandeln. Wenn evt.targetSie auf ein Element verweisen, $(this)verweisen Sie auf ein Objekt mit Parametern, auf die wir Zugriff haben.
Ohgodwhy

2
Sie könnten dies tun $(evt.target)und (in diesem Fall) auch die gleichen Ergebnisse erzielen. Die .attr()Methode wird vom jQuery-Objekt bereitgestellt, nicht vom Element selbst
BLSully

Antworten:


294

Es gibt einen Unterschied zwischen $(this)und event.targetund einen ziemlich bedeutenden. Während this(oder event.currentTargetsiehe unten) sich immer auf das DOM-Element bezieht, an das der Listener angehängt wurde, event.targethandelt es sich um das tatsächliche DOM-Element, auf das geklickt wurde. Denken Sie daran, dass aufgrund von Ereignisblasen, wenn Sie haben

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

und hängen Sie den Click-Listener an das äußere Div an

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

Dann handlerwird das aufgerufen, wenn Sie sowohl in das äußere als auch in das innere Div klicken (es sei denn, Sie haben einen anderen Code, der das Ereignis auf dem inneren Div behandelt und die Weitergabe stoppt).

Wenn Sie in diesem Beispiel in das innere Div klicken, klicken Sie auf handler:

  • thisbezieht sich auf das .outerDOM-Element (da dies das Objekt ist, an das der Handler angehängt wurde)
  • event.currentTargetbezieht sich auch auf das .outerElement (da dies das aktuelle Zielelement ist, das das Ereignis behandelt)
  • event.targetbezieht sich auf das .innerElement (dies gibt Ihnen das Element, von dem das Ereignis stammt)

Der jQuery-Wrapper umschließt $(this)nur das DOM-Element in einem jQuery-Objekt, sodass Sie darauf jQuery-Funktionen aufrufen können. Sie können das gleiche mit tun $(event.target).

Beachten Sie auch, dass wenn Sie den Kontext von neu binden this(z. B. wenn Sie Backbone verwenden, dies automatisch erfolgt), dies auf etwas anderes verweist . Sie können immer das eigentliche DOM-Element von abrufen event.currentTarget.


Wenn Sie in diesem Beispiel auf das innere Element klicken und event.currentTarget verwenden, erhalten Sie das innere oder das äußere Element?
Merlinpatt

3
currentTargetist immer derjenige mit dem Handler, dh. der äußere
Petr Bela

Mit "in einem solchen Fall" meinten Sie ".inner", nicht ".outer" wurde angeklickt, und event.target würde sich dann auf das innere Element beziehen? In Ihrem Beispiel wurde nicht angegeben, auf was tatsächlich geklickt wurde, aber ich wollte dies vor dem Bearbeiten sicherstellen. :) :)
Nils Sens

@NilsSens Ja, das heißt, wenn Sie auf "inner" klicken. Ich werde das klarstellen.
Petr Bela

39

thisist eine Referenz für das DOM-Element, für das das Ereignis behandelt wird (das aktuelle Ziel). event.targetbezieht sich auf das Element, das das Ereignis ausgelöst hat. Sie waren in diesem Fall die gleichen und können es oft sein, aber sie sind nicht unbedingt immer so.

Sie können sich ein gutes Bild davon machen , indem Sie die jQuery-Ereignisdokumente lesen , aber zusammenfassend:

event.currentTarget

Das aktuelle DOM-Element innerhalb der Ereignisblasenphase.

event.delegateTarget

Das Element, an das der aktuell aufgerufene jQuery-Ereignishandler angehängt wurde.

event.relatedTarget

Das andere an dem Ereignis beteiligte DOM-Element, falls vorhanden.

event.target

Das DOM-Element, das das Ereignis ausgelöst hat.

Um die gewünschte Funktionalität mit jQuery zu erhalten, müssen Sie sie mit: $(this)oder in ein jQuery-Objekt einschließen $(evt.target).

Die .attr()Methode funktioniert nur mit einem jQuery-Objekt, nicht mit einem DOM-Element. $(evt.target).attr('href')oder evt.target.hrefgeben Sie einfach , was Sie wollen.


Sie sind nicht unbedingt beide Verweise auf dasselbe Element. Siehe Petrs Antwort.
Kralyk

1
Richtig, danke, dass Sie darauf hingewiesen haben. Es ist immer interessant, meine alten Antworten noch einmal zu lesen ...
nbrooks

8

Es gibt einen signifikanten Unterschied darin, wie jQuery diese Variable mit einer "on" -Methode behandelt

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

Wenn Sie dies vergleichen mit: -

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

4

http://api.jquery.com/on/ heißt es:

Wenn jQuery einen Handler aufruft, thisverweist das Schlüsselwort auf das Element, an das das Ereignis gesendet wird . Für direkt gebundene Ereignisse thisist das Element, an das das Ereignis angehängt wurde, und für delegierte Ereignisse thisein Element-Matching-Selektor. (Beachten Sie, dass dies thismöglicherweise nicht gleich istevent.target wenn das Ereignis von einem untergeordneten Element übertragen wurde.)

Verwenden Sie $ (this), um ein jQuery-Objekt aus dem Element zu erstellen, damit es mit jQuery-Methoden verwendet werden kann.

Wenn wir haben

<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>

Überprüfen Sie die folgende Ausgabe:

<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>

Beachten Sie, dass ich benutze $ das dom-Element umschließe, um ein jQuery-Objekt zu erstellen, wie wir es immer tun.

Sie würden das für den ersten Fall thisfinden event.currentTarget.event.target sind alle auf das gleiche Element verwiesen.

Während im zweiten Fall, wenn der Ereignisdelegierte an ein umschlossenes Element ausgelöst wird, event.targetauf das ausgelöste Element verwiesen wird, während thisundevent.currentTarget nach verwiesen werden , wo das Ereignis geliefert wird.

Für thisund event.currentTargetsind sie laut http://api.jquery.com/event.currenttarget/ genau dasselbe.


3

Hier gibt es browserübergreifende Probleme.

Ein typischer Nicht-jQuery-Ereignishandler wäre ungefähr so:

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 normalisiert evtund stellt das Ziel wie thisin Ereignishandlern zur Verfügung. Ein typischer jQuery-Ereignishandler wäre also ungefähr so:

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

Ein hybrider Ereignishandler, der evtjQuerys normalisiertes und ein POJS-Ziel verwendet, wäre ungefähr so:

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

0

Innerhalb einer Ereignishandlerfunktion oder Objektmethode besteht eine Möglichkeit, auf die Eigenschaften des "enthaltenden Elements" zuzugreifen, darin, das spezielle Schlüsselwort this zu verwenden. Das Schlüsselwort this repräsentiert den Eigentümer der Funktion oder Methode, die gerade verarbeitet wird. So:

  • Für eine globale Funktion repräsentiert dies das Fenster.

  • Bei einer Objektmethode repräsentiert dies die Objektinstanz.

  • In einem Ereignishandler stellt dies das Element dar, das das Ereignis empfangen hat.

Beispielsweise:

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

Der Inhalt der Warnfenster nach dem Rendern dieses HTML-Codes lautet:

object Window
object HTMLParagraphElement

Ein Ereignisobjekt ist allen Ereignissen zugeordnet. Es verfügt über Eigenschaften, die Informationen "über das Ereignis" bereitstellen, z. B. die Position eines Mausklicks auf der Webseite.

Beispielsweise:

<!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>

Der Inhalt der Warnfenster nach dem Rendern dieses HTML-Codes lautet:

object MouseEvent
X = 982 Y = 329
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.