Разница между $(this) и событием.цель?


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

   var target = $(this);

но я пытался сделать это таким образом

   var target = evt.target;

и я получил эту ошибку :

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

и когда я изменил evt.target на $(this), он работал как шарм.

Я хочу знать, в чем разница между $(this) и evt.target ?

вот мой код на случай, если вам это нужно :

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

сценарий.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();
})
6 117

6 ответов:

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

<div class="outer">
  <div class="inner"></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 docs, но вкратце:

событие.currentTarget

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

событие.delegateTarget

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

событие.relatedTarget

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

событие.элемент

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

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

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

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

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. Ключевое слово 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

объект события связан со всеми событиями. Он имеет свойства, которые содержат информацию "о событии", такие как расположение мыши на веб-странице.

например:

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