Differenza tra $ (questo) e event.target?


157

Sono nuovo di jQuery e ho realizzato pannelli a schede, seguendo il tutorial in JavaScript e jQuery: The Missing Manual , c'è quella prima riga quando l'autore fa questo:

   var target = $(this);

Ma ho provato a farlo in quel modo

   var target = evt.target;

e ho avuto quell'errore:

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

E quando sono evt.targettornato a $(this), ha funzionato come un fascino.

Voglio sapere qual è la differenza tra $(this)e evt.target?

Ecco il mio codice nel caso ne avessi bisogno:

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è un riferimento all'elemento DOM JavaScript. $()è il formato fornito da jQuery per trasformare l'elemento DOM in un oggetto jQuery. usando evt.targetstai facendo riferimento a un elemento, mentre $(this)stai facendo riferimento a un oggetto con parametri a cui abbiamo accesso.
Ohgodwhy,

2
potresti fare $(evt.target)e (in questo caso) finire con gli stessi risultati. Il .attr()metodo è fornito
dall'oggetto

Risposte:


294

V'è una differenza tra $(this)e event.target, e piuttosto significativo. Mentre this(o event.currentTarget, vedi sotto) si riferisce sempre all'elemento DOM a cui era collegato il listener, event.targetè l'elemento DOM effettivo a cui è stato fatto clic. Ricorda che a causa del gorgoglio degli eventi, se lo hai

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

e allega il listener di clic al div esterno

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

quindi handlerverrà invocato quando si fa clic all'interno del div esterno e in quello interno (a meno che non si disponga di altro codice che gestisca l'evento sul div interno e interrompa la propagazione).

In questo esempio, quando fai clic all'interno del div interno, quindi in handler:

  • thissi riferisce .outerall'elemento DOM (perché è l'oggetto a cui era collegato il gestore)
  • event.currentTargetfa riferimento anche .outerall'elemento (perché è l' elemento target corrente che gestisce l'evento)
  • event.targetsi riferisce .innerall'elemento (questo ti dà l'elemento da cui è nato l'evento)

Il wrapper jQuery $(this)avvolge solo l'elemento DOM in un oggetto jQuery in modo da poter chiamare le funzioni jQuery su di esso. Puoi fare lo stesso con $(event.target).

Si noti inoltre che se si ricollega il contesto di this(ad es. Se si utilizza Backbone viene eseguito automaticamente), punterà a qualcos'altro. Puoi sempre ottenere l'elemento DOM effettivo da event.currentTarget.


Con questo esempio, se fai clic sull'elemento interno e usi event.currentTarget, ottieni l'elemento interno o quello esterno?
merlinpatt,

3
currentTargetè sempre quello con il gestore, cioè. quello esterno
Petr Bela il

Con "in tal caso" intendevi ".inner", non ".outer" è stato cliccato e event.target si riferirà quindi all'elemento interno? Il tuo esempio non ha indicato cosa è stato effettivamente cliccato, ma volevo assicurarmi prima di modificarlo. :)
Nils Sens il

@NilsSens Sì, significa quando si fa clic su "interno". Lo chiarirò.
Petr Bela,

39

thisè un riferimento per l'elemento DOM per il quale viene gestito l'evento (la destinazione corrente). event.targetsi riferisce all'elemento che ha avviato l'evento. Erano gli stessi in questo caso e spesso possono esserlo, ma non sono necessariamente sempre così.

Puoi avere una buona idea di ciò esaminando i documenti dell'evento jQuery , ma in sintesi:

event.currentTarget

L'attuale elemento DOM nella fase di bubbling dell'evento.

event.delegateTarget

L'elemento a cui era associato il gestore eventi jQuery attualmente chiamato.

event.relatedTarget

L'altro elemento DOM coinvolto nell'evento, se presente.

event.target

L'elemento DOM che ha avviato l'evento.

Per ottenere la funzionalità desiderata utilizzando jQuery, è necessario racchiuderlo in un oggetto jQuery utilizzando: $(this)o $(evt.target).

Il .attr()metodo funziona solo su un oggetto jQuery, non su un elemento DOM. $(evt.target).attr('href')o semplicemente evt.target.hrefti darà quello che vuoi.


Essi sono non necessariamente entrambi i riferimenti allo stesso elemento. Vedi la risposta di Petr.
kralyk,

1
Abbastanza vero, grazie per averlo sottolineato. È sempre interessante rileggere le mie vecchie risposte ...
nbrooks

8

C'è una differenza significativa nel modo in cui jQuery gestisce questa variabile con un metodo "on"

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

Se lo confronti con: -

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

4

http://api.jquery.com/on/ afferma:

Quando jQuery chiama un gestore, la thisparola chiave è un riferimento all'elemento in cui viene consegnato l'evento ; per gli eventi associati direttamente thisè l'elemento a cui è stato associato l'evento e per gli eventi delegati thisè un selettore di corrispondenza degli elementi. (Si noti che thispotrebbe non essere uguale a event.targetse l'evento è stato gorgogliato da un elemento discendente.)

Per creare un oggetto jQuery dall'elemento in modo che possa essere utilizzato con i metodi jQuery, utilizzare $ (questo).

Se abbiamo

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

Controlla l'output seguente:

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

Nota che uso $per avvolgere l'elemento dom al fine di creare un oggetto jQuery, che è come facciamo sempre.

Si potrebbe scoprire che per il primo caso, this, event.currentTarget, event.targetsono tutti riferimento allo stesso elemento.

Mentre nel secondo caso, quando il delegato dell'evento a qualche elemento avvolto vengono attivati, event.targetverrebbe riferimento all'elemento innescata, mentre thise event.currentTargetsono riferiti a cui viene erogata l'evento.

Per thise event.currentTarget, sono esattamente la stessa cosa secondo http://api.jquery.com/event.currenttarget/


3

Ci sono problemi tra browser qui.

Un tipico gestore di eventi non jQuery sarebbe qualcosa del genere:

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 normalizza evte rende disponibile l'obiettivo come thisnei gestori di eventi, quindi un tipico gestore di eventi jQuery sarebbe qualcosa del genere:

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

Un gestore di eventi ibrido che utilizza jQuery è normalizzato evte un target POJS sarebbe qualcosa del genere:

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

0

All'interno di una funzione del gestore di eventi o di un metodo a oggetti, un modo per accedere alle proprietà dell '"elemento contenitore" è utilizzare la speciale parola chiave this. Questa parola chiave rappresenta il proprietario della funzione o del metodo attualmente in elaborazione. Così:

  • Per una funzione globale, questo rappresenta la finestra.

  • Per un metodo oggetto, rappresenta l'istanza dell'oggetto.

  • E in un gestore di eventi, questo rappresenta l'elemento che ha ricevuto l'evento.

Per esempio:

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

Il contenuto delle finestre di avviso dopo aver reso rispettivamente questo html sono:

object Window
object HTMLParagraphElement

Un oggetto Event è associato a tutti gli eventi. Ha proprietà che forniscono informazioni "sull'evento", come la posizione di un clic del mouse nella pagina Web.

Per esempio:

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

Il contenuto delle finestre di avviso dopo aver reso rispettivamente questo html sono:

object MouseEvent
X = 982 Y = 329
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.