Разница между $ (this) и event.target?

157

Я новичок в jQuery, и делал панели с вкладками, следуя учебному пособию по JavaScript и jQuery: The Missing Manual , есть первая строка, когда автор делает это:

   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является ссылкой на элемент DOM JavaScript. $()это формат, предоставляемый jQuery для превращения элемента DOM в объект jQuery. используя evt.targetвы ссылаетесь на элемент, тогда как $(this)вы ссылаетесь на объект с параметрами, к которым у нас есть доступ.
Ohgodwhy
2
Вы могли бы сделать $(evt.target)и (в этом случае) в конечном итоге с теми же результатами. .attr()Обеспечивается способ, с помощью JQuery объекта, а не сам элемент
BLSully

Ответы:

295

Там является разница между $(this)и event.target, и довольно значительным. Хотя this(или event.currentTarget, см. Ниже) всегда относится к элементу event.targetDOM, к которому был присоединен слушатель, это фактический элемент DOM, по которому был выполнен щелчок. Помните, что из-за пузыря события, если у вас есть

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

и прикрепить прослушиватель кликов к внешнему div

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

тогда handlerбудет вызвано, когда вы щелкнете как по внешнему div, так и по внутреннему (если у вас нет другого кода, который обрабатывает событие на внутреннем div и останавливает распространение).

В этом примере, когда вы нажимаете внутри внутреннего div, то в handler:

  • thisссылается на .outerэлемент DOM (потому что это объект, к которому был прикреплен обработчик)
  • event.currentTargetтакже относится к .outerэлементу (потому что это текущий целевой элемент, обрабатывающий событие)
  • event.targetссылается на .innerэлемент (это дает вам элемент, где произошло событие)

Оболочка jQuery $(this)только оборачивает элемент DOM в объект jQuery, поэтому вы можете вызывать на нем функции jQuery. Вы можете сделать то же самое с $(event.target).

Также обратите внимание, что если вы перепривязываете контекст this(например, если вы используете Backbone, это делается автоматически), это будет указывать на что-то еще. Вы всегда можете получить фактический элемент DOM от event.currentTarget.

Петр Бела
источник
В этом примере, если вы щелкнете по внутреннему элементу и будете использовать event.currentTarget, получите ли вы внутренний или внешний элемент?
merlinpatt
3
currentTargetвсегда тот, с обработчиком, т.е. внешний
Петр Бела
Под «в таком случае» вы подразумевали «.inner», а не «.outer», и в этом случае event.target ссылался на внутренний элемент? В вашем примере не указано, на что на самом деле кликнули, но я хотел убедиться перед редактированием. :)
Nils Sens
@NilsSens Да, это означает, когда вы нажимаете «внутренний». Я сделаю это ясно.
Петр Бела
39

thisявляется ссылкой на элемент DOM, для которого обрабатывается событие (текущая цель). event.targetотносится к элементу, который инициировал событие. Они были одинаковыми в этом случае, и часто могут быть, но это не всегда так.

Вы можете получить представление об этом, просмотрев документацию по событиям jQuery , но вкратце:

event.currentTarget

Текущий элемент DOM в фазе всплытия событий.

event.delegateTarget

Элемент, к которому был прикреплен вызываемый в данный момент обработчик события jQuery.

event.relatedTarget

Другой элемент DOM, участвующий в событии, если таковой имеется.

event.target

Элемент DOM, который инициировал событие.

Чтобы получить желаемую функциональность с помощью jQuery, вы должны обернуть его в объект jQuery, используя: $(this)или $(evt.target).

.attr()Метод работает только на объект JQuery, а не на DOM элемента. $(evt.target).attr('href')или просто evt.target.hrefдаст вам то, что вы хотите.

nbrooks
источник
Они не обязательно являются ссылками на один и тот же элемент. Смотрите ответ Петра.
кралык
1
Правда, спасибо, что указали на это. Всегда интересно перечитывать мои старые ответы ...
nbrooks
8

Существует значительное различие в том, как jQuery обрабатывает переменную this методом 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"
})
natureshop
источник
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, как мы всегда делаем.

Вы обнаружите , что в первом случае this, event.currentTarget, event.targetвсе привязаны к одному элементу.

В то время как во втором случае, когда делегат события для какого-либо обернутого элемента сработал, event.targetбудет указана ссылка на сработавший элемент, а на thisи event.currentTargetбудет указано, куда доставлено событие.

Для thisи event.currentTargetони абсолютно одинаковы, согласно http://api.jquery.com/event.currenttarget/

Jaskey
источник
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

Объект Event связан со всеми событиями. У него есть свойства, предоставляющие информацию «о событии», например, местоположение щелчка мыши на веб-странице.

Например:

<!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
MMKarami
источник