Diferença entre $ (this) e event.target?

157

Eu sou novo no jQuery e estava criando painéis com guias, seguindo o tutorial em JavaScript e jQuery: The Missing Manual , existe a primeira linha quando o autor faz isso:

   var target = $(this);

Mas eu tentei fazer dessa maneira

   var target = evt.target;

e eu recebi esse erro:

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

E quando eu mudei de evt.targetvolta $(this), funcionou como um encanto.

Eu quero saber qual é a diferença entre $(this)e evt.target?

Aqui está o meu código, caso você precise:

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();
})
Rafael Adel
fonte
7
thisé uma referência ao elemento DOM do JavaScript. $()é o formato fornecido pelo jQuery para transformar o elemento DOM em um objeto jQuery. usando evt.targetvocê está fazendo referência a um elemento, enquanto que $(this)você está fazendo referência a um objeto com parâmetros aos quais temos acesso.
precisa saber é o seguinte
2
você poderia fazer $(evt.target)e (neste caso) também obter os mesmos resultados. O .attr()método é fornecido pelo objeto jQuery, não o próprio elemento
BLSully

Respostas:

294

Não é uma diferença entre $(this)e event.target, e bastante significativa. Embora this(ou event.currentTargetveja abaixo) sempre se refira ao elemento DOM ao qual o ouvinte foi anexado, event.targeté o elemento DOM real que foi clicado. Lembre-se de que, devido ao borbulhamento do evento, se você tiver

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

e anexar o ouvinte de clique à div externa

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

então handler, será invocado quando você clicar dentro da div externa e na interna (a menos que você tenha outro código que lide com o evento na div interna e interrompa a propagação).

Neste exemplo, quando você clica dentro da div interna, em handler:

  • thisrefere-se ao .outerelemento DOM (porque esse é o objeto ao qual o manipulador foi anexado)
  • event.currentTargettambém se refere ao .outerelemento (porque esse é o elemento de destino atual que manipula o evento)
  • event.targetrefere-se ao .innerelemento (isso fornece o elemento onde o evento se originou)

O wrapper jQuery $(this)envolve apenas o elemento DOM em um objeto jQuery para que você possa chamar funções jQuery nele. Você pode fazer o mesmo com $(event.target).

Observe também que, se você religar o contexto de this(por exemplo, se você usar o Backbone, ele será feito automaticamente), ele apontará para outra coisa. Você sempre pode obter o elemento DOM real event.currentTarget.

Petr Bela
fonte
Neste exemplo, se você clicar no elemento interno e usar event.currentTarget, obterá o elemento interno ou o externo?
merlinpatt
3
currentTargeté sempre aquele com o manipulador, ie. o externo
Petr Bela
Por "nesse caso" você quis dizer '.inner', não '.outer' foi clicado e event.target se referiria ao elemento interno? Seu exemplo não indicava o que realmente foi clicado, mas eu queria ter certeza antes de editar. :)
Nils Sens
@NilsSens Sim, significa quando você clica em 'interior'. Vou deixar isso claro.
Petr Bela
39

thisé uma referência para o elemento DOM para o qual o evento está sendo tratado (o destino atual). event.targetrefere-se ao elemento que iniciou o evento. Eles eram os mesmos nesse caso e geralmente podem ser, mas nem sempre são necessariamente assim.

Você pode ter uma boa noção disso revisando os documentos do evento jQuery , mas em resumo:

event.currentTarget

O elemento DOM atual na fase de bolhas do evento.

event.delegateTarget

O elemento ao qual o manipulador de eventos jQuery atualmente chamado foi anexado.

event.relatedTarget

O outro elemento DOM envolvido no evento, se houver.

event.target

O elemento DOM que iniciou o evento.

Para obter a funcionalidade desejada usando o jQuery, você deve envolvê-lo em um objeto jQuery usando: $(this)ou $(evt.target).

O .attr()método funciona apenas em um objeto jQuery, não em um elemento DOM. $(evt.target).attr('href')ou simplesmente evt.target.hreflhe dará o que você deseja.

Nbrooks
fonte
Elas não são necessariamente as duas referências ao mesmo elemento. Veja a resposta de Petr.
Kralyk
1
É verdade, obrigado por apontar isso. É sempre interessante reler meus antigos respostas ...
nbrooks
8

Existe uma diferença significativa na maneira como o jQuery lida com essa variável com um método "on"

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

Se você comparar isso com: -

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

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

Quando o jQuery chama um manipulador, a thispalavra-chave é uma referência ao elemento em que o evento está sendo entregue ; para eventos diretamente ligados thisé o elemento em que o evento foi anexado e, para eventos delegados, thisé um seletor de correspondência de elemento. (Observe que thispode não ser igual aevent.target se o evento tiver sido borbulhado a partir de um elemento descendente.)

Para criar um objeto jQuery a partir do elemento para que ele possa ser usado com os métodos jQuery, use $ (this).

Se tiver-mos

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

Verifique a saída abaixo:

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

Observe que eu uso $para envolver o elemento dom para criar um objeto jQuery, que é como sempre fazemos.

Você teria que encontrar para o primeiro caso, this, event.currentTarget, event.targetestão todos referenciados ao mesmo elemento.

Enquanto no segundo caso, quando o delegado do evento para algum elemento encapsulado for acionado, event.targetele será referenciado ao elemento acionado, enquanto thiseevent.currentTarget são referenciados ao local onde o evento seja entregue.

Para thise event.currentTarget, eles são exatamente a mesma coisa de acordo com http://api.jquery.com/event.currenttarget/

Jaskey
fonte
3

Há problemas entre navegadores aqui.

Um manipulador de eventos não-jQuery típico seria algo assim:

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
}

O jQuery normaliza evte disponibiliza o destino como thisnos manipuladores de eventos; portanto, um manipulador de eventos típico do jQuery seria algo como isto:

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

Um manipulador de eventos híbrido que usa o evtalvo normalizado e um POJS do jQuery seria algo como isto:

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

Dentro de uma função de manipulador de eventos ou método de objeto, uma maneira de acessar as propriedades "do elemento que contém" é usar a palavra-chave especial this. A palavra-chave this representa o proprietário da função ou método atualmente sendo processado. Assim:

  • Para uma função global, isso representa a janela.

  • Para um método de objeto, isso representa a instância do objeto.

  • E em um manipulador de eventos, isso representa o elemento que recebeu o evento.

Por exemplo:

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

O conteúdo das janelas de alerta após renderizar este html, respectivamente, é:

object Window
object HTMLParagraphElement

Um objeto Event está associado a todos os eventos. Possui propriedades que fornecem informações "sobre o evento", como a localização de um clique do mouse na página da web.

Por exemplo:

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

O conteúdo das janelas de alerta após renderizar este html, respectivamente, é:

object MouseEvent
X = 982 Y = 329
MMKarami
fonte