Разница между $(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();
})

Ответ 1

Существует разница между $(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 .outer (поскольку тот объект, к которому был прикреплен обработчик)
  • event.currentTarget также относится к элементу .outer (потому что текущий целевой элемент обрабатывает событие)
  • event.target ссылается на элемент .inner (это дает вам элемент, в котором произошло событие)

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

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

Ответ 2

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

Вы можете получить хорошее представление об этом, просмотрев jQuery event docs, но в целом:

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

Ответ 3

В jQuery существует значительная разница в том, как обрабатывает эту переменную с помощью метода "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"
})

Ответ 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/

Ответ 5

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

Типичным обработчиком событий, отличным от 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
}

Ответ 6

Внутри функции обработчика события или метода объекта одним из способов доступа к свойствам "содержащего элемента" является использование специального этого ключевого слова. Это ключевое слово представляет владельца текущей функции или метода. Итак:

  • Для глобальной функции это представляет окно.

  • Для объектного метода это представляет экземпляр объекта.

  • И в обработчике события это представляет элемент, который получил событие.

Например:

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