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

Я новичок в 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) а также event.target и довольно значительный. В то время как this (или же event.currentTarget см. ниже) всегда относится к элементу DOM, к которому был присоединен слушатель, event.target это фактический элемент 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,

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 даст вам то, что вы хотите.

Существует значительное различие в том, как 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"
})

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/ это одно и то же

Здесь есть кросс-браузерные проблемы.

Типичный не-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
}

'this' относится к объекту DOM, к которому был присоединен прослушиватель событий. ' event.target' относится к объекту DOM, для которого сработал прослушиватель событий. Возникает естественный вопрос, почему прослушиватель событий срабатывает для других объектов DOM. Это связано с тем, что прослушиватель событий присоединил родительские триггеры и к дочернему объекту.

В функции-обработчике события или методе объекта одним из способов доступа к свойствам "содержащего элемента" является использование специального ключевого слова 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
Другие вопросы по тегам