Різниця між $ (цією) та цільовою подією?


157

Я новачок у 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?

Ось мій код у випадку, якщо він вам знадобився:

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- посилання на елемент JavaScript DOM. $()- це формат, наданий jQuery для перетворення елемента DOM в об'єкт jQuery. використовуючи evt.targetпосилання на елемент, тоді як $(this)ви посилаєтесь на об'єкт із параметрами, до яких ми маємо доступ.
Ohgodwhy

2
ви могли б зробити $(evt.target)і (в даному випадку) також отримати ті самі результати. .attr()Забезпечується спосіб, з допомогою JQuery об'єкта, а не саме елемент
BLSully

Відповіді:


294

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

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

і приєднайте слухача кліків до зовнішнього діва

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

тоді handlerвиклик буде, коли ви клацнете всередині зовнішнього діва, а також внутрішнього (якщо у вас немає іншого коду, який обробляє подію на внутрішньому діві та зупиняє розповсюдження).

У цьому прикладі, клацнувши всередині внутрішнього діва, потім у 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дасть вам те, що ви хочете.


Вони не обов'язково обидва посилання на один і той же елемент. Дивіться відповідь Петра.
кралик

1
Щоправда, дякую, що вказали на це. Завжди цікаво перечитати мої старі відповіді ...
nbrooks

8

Існує суттєве відмінність у тому, як 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, використовуйте $ (це).

Якщо у нас є

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


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

У межах функції обробника подій або методу об'єкта одним із способів отримати доступ до властивостей "містять елемента" є використання спеціального цього ключового слова. Це ключове слово представляє власника функції або методу, який зараз обробляється. Так:

  • Для глобальної функції це відображає вікно.

  • Для об'єктного методу це являє собою об'єкт об'єкта.

  • А в обробнику події це представляє елемент, який отримав подію.

Наприклад:

<!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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.