ความแตกต่างระหว่าง $ (นี้) กับ 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เป็นการอ้างอิงถึงองค์ประกอบ 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>

และแนบ listener การคลิกไปยัง div ภายนอก

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

จากนั้นhandlerจะถูกเรียกใช้เมื่อคุณคลิกภายใน div ด้านนอกรวมถึงโค้ดด้านใน (เว้นแต่คุณจะมีรหัสอื่นที่จัดการกับเหตุการณ์ใน div ด้านในและหยุดการแพร่กระจาย)

ในตัวอย่างนี้เมื่อคุณคลิกภายใน div ภายในจากนั้นในhandler:

  • thisอ้างถึง.outerองค์ประกอบ DOM (เนื่องจากเป็นวัตถุที่ติดตั้งตัวจัดการ)
  • event.currentTargetยังหมายถึง.outerองค์ประกอบ (เพราะเป็นองค์ประกอบเป้าหมายปัจจุบันที่จัดการกับเหตุการณ์)
  • event.targetหมายถึง.innerองค์ประกอบ (สิ่งนี้จะช่วยให้คุณองค์ประกอบที่เหตุการณ์มา)

wrapper jQuery $(this)ล้อมรอบองค์ประกอบ DOM ในวัตถุ jQuery เท่านั้นดังนั้นคุณสามารถเรียกใช้ฟังก์ชัน jQuery ได้ $(event.target)คุณสามารถทำเช่นเดียวกันกับ

โปรดทราบด้วยว่าหากคุณเชื่อมโยงบริบทของthis(เช่นถ้าคุณใช้ Backbone โดยอัตโนมัติ) มันจะชี้ไปที่สิ่งอื่น คุณสามารถได้รับองค์ประกอบ DOM event.currentTargetที่เกิดขึ้นจริงจาก


ด้วยตัวอย่างนี้ถ้าคุณคลิกองค์ประกอบภายในและใช้ event.currentTarget คุณจะได้รับองค์ประกอบภายในหรือภายนอก?
merlinpatt

3
currentTargetมักจะเป็นคนที่มีตัวจัดการเช่น ตัวนอก
Petr Bela

โดย "ในกรณีเช่นนี้" คุณหมายถึง '.inner' ไม่ใช่ '.outer' ถูกคลิกแล้ว event.target จะอ้างถึงองค์ประกอบภายในหรือไม่ ตัวอย่างของคุณไม่ได้ระบุสิ่งที่คลิกจริง แต่ฉันต้องการตรวจสอบให้แน่ใจก่อนทำการแก้ไข :)
Nils Sens

@NilsSens ใช่มันหมายถึงเมื่อคุณคลิก 'Inner' ฉันจะทำให้ชัดเจน
Petr Bela

39

thisเป็นการอ้างอิงสำหรับองค์ประกอบ DOM ที่จัดการเหตุการณ์ (เป้าหมายปัจจุบัน) event.targetหมายถึงองค์ประกอบที่ริเริ่มเหตุการณ์ พวกเขาเหมือนกันในกรณีนี้และมักจะเป็นได้ แต่ไม่จำเป็นเสมอไป

คุณสามารถเข้าใจสิ่งนี้ได้โดยการทบทวนเอกสารเหตุการณ์ jQueryแต่โดยสรุป:

event.currentTarget

องค์ประกอบ DOM ปัจจุบันภายในเฟสการทำให้เกิดเหตุการณ์

event.delegateTarget

องค์ประกอบที่แนบ jQuery event handler

event.relatedTarget

องค์ประกอบ DOM อื่น ๆ ที่เกี่ยวข้องในเหตุการณ์หากมี

event.target

องค์ประกอบ DOM ที่เริ่มต้นเหตุการณ์

ที่จะได้รับการทำงานที่ต้องการใช้ jQuery คุณต้องห่อไว้ในวัตถุ jQuery ใช้อย่างใดอย่างหนึ่งหรือ$(this)$(evt.target)

.attr()วิธีการทำงานเฉพาะบนวัตถุ jQuery ที่ไม่ได้อยู่ในองค์ประกอบ DOM $(evt.target).attr('href')หรือเพียงแค่evt.target.hrefจะให้สิ่งที่คุณต้องการ


พวกเขาไม่จำเป็นต้องอ้างอิงทั้งสององค์ประกอบเดียวกัน ดูคำตอบของ Petr
kralyk

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 normalises 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.