Sự khác biệt giữa $ (này) và event.target?


157

Tôi mới sử dụng jQuery và đã tạo các bảng theo thẻ, theo hướng dẫn trong JavaScript và jQuery: Hướng dẫn thiếu , có dòng đầu tiên khi tác giả thực hiện việc này:

   var target = $(this);

Nhưng tôi đã cố gắng làm theo cách đó

   var target = evt.target;

và tôi đã nhận được lỗi đó:

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

Và khi tôi đổi evt.targetlại $(this), nó hoạt động như một lá bùa.

Tôi muốn biết sự khác biệt giữa $(this)evt.target?

Đây là mã của tôi trong trường hợp bạn cần nó:

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
thislà một tham chiếu đến phần tử DOM DOM. $()là định dạng do jQuery cung cấp để biến phần tử DOM thành Đối tượng jQuery. sử dụng evt.targetbạn đang tham chiếu một phần tử, trong khi với $(this)bạn đang tham chiếu một đối tượng có tham số mà chúng ta có quyền truy cập.
Ohgodwhy

2
bạn có thể làm $(evt.target)và (trong trường hợp này) cũng có kết quả tương tự. Các .attr()phương pháp được cung cấp bởi các đối tượng jQuery, không phải là yếu tố chính
BLSully

Câu trả lời:


294

một sự khác biệt giữa $(this)event.target, và một trong khá đáng kể. Trong khi this(hoặc event.currentTarget, xem bên dưới) luôn đề cập đến phần tử DOM mà trình nghe được đính kèm, event.targetlà phần tử DOM thực tế đã được nhấp. Hãy nhớ rằng do sự kiện sủi bọt, nếu bạn có

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

và đính kèm người nghe nhấp vào div bên ngoài

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

sau đó handlersẽ được gọi khi bạn nhấp vào bên trong div bên ngoài cũng như bên trong (trừ khi bạn có mã khác xử lý sự kiện trên div bên trong và dừng lan truyền).

Trong ví dụ này, khi bạn nhấp vào bên trong div bên trong, thì trong handler:

  • thisđề cập đến .outerphần tử DOM (vì đó là đối tượng mà trình xử lý được đính kèm)
  • event.currentTargetcũng đề cập đến .outerphần tử (vì đó là phần tử mục tiêu hiện tại xử lý sự kiện)
  • event.targetđề cập đến .innerphần tử (phần này cung cấp cho bạn phần tử bắt nguồn từ sự kiện)

Trình bao bọc jQuery $(this)chỉ bao bọc phần tử DOM trong một đối tượng jQuery để bạn có thể gọi các hàm jQuery trên nó. Bạn có thể làm tương tự với $(event.target).

Cũng lưu ý rằng nếu bạn khởi động lại bối cảnh của this(ví dụ: nếu bạn sử dụng Backbone, nó sẽ được thực hiện tự động), nó sẽ trỏ đến một thứ khác. Bạn luôn có thể lấy phần tử DOM thực tế từ event.currentTarget.


Với ví dụ này, nếu bạn nhấp vào phần tử bên trong và sử dụng event.cienTarget, bạn có nhận được phần tử bên trong hoặc phần tử bên ngoài không?
merlinpatt

3
currentTargetluôn luôn là người có xử lý, tức là. cái bên ngoài
Petr bela

Bởi "trong trường hợp như vậy", bạn có nghĩa là '.inner', chứ không phải '.outer' đã được nhấp và event.target sau đó sẽ đề cập đến yếu tố bên trong? Ví dụ của bạn không nêu rõ những gì thực sự được nhấp vào, nhưng tôi muốn chắc chắn trước khi chỉnh sửa. :)
Nils Sens

@NilsSens Có, điều đó có nghĩa là khi bạn nhấp vào 'bên trong'. Tôi sẽ làm rõ điều đó.
Petr bela

39

thislà một tham chiếu cho phần tử DOM mà sự kiện đang được xử lý (mục tiêu hiện tại). event.targetđề cập đến yếu tố khởi xướng sự kiện. Chúng giống nhau trong trường hợp này và thường có thể như vậy, nhưng chúng không nhất thiết phải luôn như vậy.

Bạn có thể hiểu rõ điều này bằng cách xem xét các tài liệu sự kiện jQuery , nhưng tóm lại:

event.cienTarget

Phần tử DOM hiện tại trong giai đoạn sủi bọt sự kiện.

event.delegateTarget

Phần tử nơi trình xử lý sự kiện jQuery hiện được gọi là đã được đính kèm.

event.relatedTarget

Phần tử DOM khác có liên quan đến sự kiện này, nếu có.

event.target

Phần tử DOM đã khởi tạo sự kiện.

Để có được chức năng mong muốn bằng jQuery, bạn phải bọc nó trong một đối tượng jQuery bằng cách sử dụng: $(this)hoặc $(evt.target).

Các .attr()phương pháp duy nhất hoạt động trên một đối tượng jQuery, không phải trên một phần tử DOM. $(evt.target).attr('href')hoặc đơn giản là evt.target.hrefsẽ cung cấp cho bạn những gì bạn muốn.


Chúng không nhất thiết là cả hai tham chiếu đến cùng một yếu tố. Xem câu trả lời của Petr.
kralyk

1
Đúng vậy, cảm ơn vì đã chỉ ra điều đó. Luôn luôn thú vị khi đọc lại câu trả lời cũ của tôi ...
nbrooks

8

Có một sự khác biệt đáng kể trong cách jQuery xử lý biến này bằng phương thức "bật"

$("outer DOM element").on('click',"inner DOM element",function(){
  $(this) // refers to the "inner DOM element"
})

Nếu bạn so sánh điều này với: -

$("outer DOM element").click(function(){
  $(this) // refers to the "outer DOM element"
})

4

http://api.jquery.com/on/ bang:

Khi jQuery gọi một trình xử lý, thistừ khóa là một tham chiếu đến phần tử nơi sự kiện đang được phân phối ; đối với các sự kiện bị ràng buộc trực tiếp thislà phần tử trong đó sự kiện được đính kèm và đối với các sự kiện thisđược ủy nhiệm là một bộ chọn khớp phần tử. (Lưu ý rằng thiscó thể không bằng event.targetnếu sự kiện đã nổi lên từ một yếu tố hậu duệ.)

Để tạo một đối tượng jQuery từ phần tử để có thể sử dụng nó với các phương thức jQuery, hãy sử dụng $ (this).

Nếu chúng ta có

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

Kiểm tra đầu ra dưới đây:

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

Lưu ý rằng tôi sử dụng $để bọc phần tử dom để tạo đối tượng jQuery, đó là cách chúng tôi luôn làm.

Bạn sẽ thấy rằng đối với trường hợp đầu tiên, this, event.currentTarget, event.targettất cả đều tham chiếu đến cùng một nguyên tố.

Trong trường hợp thứ hai, khi sự kiện ủy nhiệm cho một số phần tử được bao bọc được kích hoạt, event.targetsẽ được tham chiếu đến phần tử được kích hoạt, trong khi thisevent.currentTargetđược tham chiếu đến nơi sự kiện được phân phối.

Đối với thisevent.currentTarget, chúng hoàn toàn giống nhau theo http://api.jquery.com/event.c hiệntarget/


3

Có vấn đề trình duyệt chéo ở đây.

Một trình xử lý sự kiện không phải là jQuery điển hình sẽ giống như thế này:

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 bình thường hóa evtvà làm cho mục tiêu khả dụng như thistrong các trình xử lý sự kiện, do đó, một trình xử lý sự kiện jQuery điển hình sẽ giống như thế này:

function doSomething(evt) {
    var $target = $(this);
    //do stuff here
}

Trình xử lý sự kiện lai sử dụng chuẩn hóa của jQuery evtvà mục tiêu POJS sẽ giống như thế này:

function doSomething(evt) {
    var target = evt.target || evt.srcElement;
    if (target.nodeType == 3) // defeat Safari bug
        target = target.parentNode;
    //do stuff here
}

0

Trong hàm xử lý sự kiện hoặc phương thức đối tượng, một cách để truy cập các thuộc tính của "phần tử chứa" là sử dụng từ khóa đặc biệt này. Từ khóa này đại diện cho chủ sở hữu của chức năng hoặc phương thức hiện đang được xử lý. Vì thế:

  • Đối với một chức năng toàn cầu, điều này đại diện cho cửa sổ.

  • Đối với một phương thức đối tượng, điều này thể hiện thể hiện đối tượng.

  • Và trong một trình xử lý sự kiện, điều này thể hiện yếu tố đã nhận sự kiện.

Ví dụ:

<!DOCTYPE html>
<html>
    <head>
        <script>
        function mouseDown() {
            alert(this);
        }
        </script>
    </head>
    <body>
        <p onmouseup="mouseDown();alert(this);">Hi</p>
    </body>
</html>

Nội dung của các cửa sổ cảnh báo sau khi hiển thị html này tương ứng là:

object Window
object HTMLParagraphElement

Một đối tượng Sự kiện được liên kết với tất cả các sự kiện. Nó có các thuộc tính cung cấp thông tin "về sự kiện", chẳng hạn như vị trí nhấp chuột trong trang web.

Ví dụ:

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

Nội dung của các cửa sổ cảnh báo sau khi hiển thị html này tương ứng là:

object MouseEvent
X = 982 Y = 329
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.