$ (document) .on (“click”… không hoạt động?


82

Có một sai lầm nổi tiếng mà tôi có thể mắc phải ở đây không?

Tôi có một tập lệnh đang sử dụng .on () vì một phần tử được tạo động và nó không hoạt động. Chỉ để kiểm tra, tôi đã thay thế bộ chọn bằng bọc của phần tử động, là phần tử tĩnh, và nó vẫn không hoạt động! Tuy nhiên, khi tôi chuyển sang .click cũ đơn giản để bọc nó hoạt động.
(Điều này rõ ràng sẽ không hoạt động đối với phần tử động, phần tử quan trọng.)

Những công việc này:

$("#test-element").click(function() {
    alert("click");
});

Điều này không:

$(document).on("click","#test-element",function() {
    alert("click");
});

CẬP NHẬT:

Tôi đã nhấp chuột phải và thực hiện "Kiểm tra phần tử" trong Chrome để chỉ cần kiểm tra lại một thứ gì đó và sau đó sự kiện nhấp chuột đã hoạt động. Tôi đã làm mới và nó không hoạt động, đã kiểm tra phần tử, và sau đó nó hoạt động. Điều đó có nghĩa là gì?


1
Bạn có đang tạo nhiều phần tử có cùng ID không?
adeneo

Chỉ đăng jQuery mà không có HTML liên quan sẽ khiến bạn khó có thể hỗ trợ.
jmoerdyk

3
Hiya OP, xin vui lòng kiểm tra phiên bản của Jquery bạn đang sử dụng, :)hoặc flick một fiddle tôi có thể giúp bạn ra ngoài,
Tats_innit

Mã của bạn phải hoạt động. Các onchức năng được bổ sung trong jquery 1.7, hãy chắc chắn bạn có một phiên bản gần đây. Chỉnh sửa: chứng minh cho bạn rằng nó hoạt động trên fiddle
Phil-R

Ví dụ thứ hai của bạn hoạt động với các phiên bản 1.x mới nhất của jQuery: jsfiddle.net/AJPdS
Wookai

Câu trả lời:


153

Bạn đang sử dụng cú pháp chính xác để liên kết với tài liệu để lắng nghe sự kiện nhấp chuột cho một phần tử có id = "test-element".

Nó có thể không hoạt động do một trong số:

  • Không sử dụng phiên bản jQuery gần đây
  • Chưa sẵn sàng gói mã của bạn bên trong DOM
  • hoặc bạn đang làm điều gì đó khiến sự kiện không xuất hiện đối với người nghe trên tài liệu.

Để nắm bắt các sự kiện trên các phần tử được tạo SAU KHI khai báo trình xử lý sự kiện của bạn - bạn nên liên kết với một phần tử mẹ hoặc phần tử cao hơn trong hệ thống phân cấp.

Ví dụ:

$(document).ready(function() {
    // This WILL work because we are listening on the 'document', 
    // for a click on an element with an ID of #test-element
    $(document).on("click","#test-element",function() {
        alert("click bound to document listening for #test-element");
    });

    // This will NOT work because there is no '#test-element' ... yet
    $("#test-element").on("click",function() {
        alert("click bound directly to #test-element");
    });

    // Create the dynamic element '#test-element'
    $('body').append('<div id="test-element">Click mee</div>');
});

Trong ví dụ này, chỉ cảnh báo "liên kết với tài liệu" mới kích hoạt.

JSFiddle với jQuery 1.9.1


Rất tiếc, tôi đang sử dụng phiên bản Jquery gần đây, mã của tôi được bao bọc đúng cách, nó nằm bên trong $ (document) .ready, và sự kiện đang được nhấp là phần tử cấp thấp nhất trong tài liệu. Điều này thật khó hiểu.
Ông Lavalamp,

Tôi muốn nói rằng "cần đặt người nghe vào yếu tố chính" là không cần thiết, mặc dù tôi cũng khuyên bạn nên làm như vậy. Sủi bọt là thứ cho phép .on () hoạt động. Nếu chúng ta không thể dựa vào sự sôi sục để vượt qua người cha mẹ trực tiếp, thì đó không phải là một giải pháp tuyệt vời.
iGanja

@iGanja - điểm tốt và như bạn đề xuất, 'cần' không phải là từ phù hợp vì có những cách khác ít lý tưởng hơn để thực hiện điều này. Tôi đã sửa lại câu trả lời của mình.
itmejodie

nếu tôi đang sử dụng "này" để đối tượng yếu tố tham khảo thì làm sao tôi có thể đính kèm sự kiện đó với tài liệu ..
Ashish Joshi

1
@JasonGlisson dự đoán của tôi là trong khi bạn có người nghe trên tài liệu, có vấn đề với sự kiện không nổi lên (từ lần nhấp vào nút) hoặc sự khác biệt giữa event.targetevent.currentTargetở đâu đó trong mã của bạn, nhưng có rất nhiều những thứ nó có thể bao gồm các sự kiện con trỏ bị vô hiệu hóa trên nút
itmejodie

12

Mã của bạn sẽ hoạt động, nhưng tôi biết rằng câu trả lời đó không giúp được gì cho bạn. Bạn có thể xem một ví dụ làm việc tại đây (jsfiddle) .

Truy vấn:

$(document).on('click','#test-element',function(){
    alert("You clicked the element with and ID of 'test-element'");
});

Như ai đó đã chỉ ra, bạn đang sử dụng ID thay vì một lớp. Nếu bạn có nhiều hơn một phần tử trên trang có ID, thì jquery sẽ chỉ trả về phần tử đầu tiên có ID đó . Sẽ không có bất kỳ lỗi nào vì đó là cách nó hoạt động. Nếu đây là sự cố, thì bạn sẽ nhận thấy rằng sự kiện nhấp chuột hoạt động cho lần đầu tiên test-elementnhưng không cho bất kỳ sự kiện nào tiếp theo.

Nếu điều này không mô tả chính xác các triệu chứng của sự cố, thì có lẽ bộ chọn của bạn đã sai. Cập nhật của bạn khiến tôi tin rằng đây là trường hợp vì việc kiểm tra một phần tử sau đó nhấp lại vào trang và kích hoạt nhấp chuột. Điều có thể gây ra điều này là nếu bạn đặt người nghe sự kiện vào thực tế documentthay vì test-element. Nếu vậy, khi bạn bấm ra khỏi tài liệu và bật lại (như từ cửa sổ nhà phát triển trở lại tài liệu), sự kiện sẽ kích hoạt. Nếu đúng như vậy, bạn cũng sẽ nhận thấy sự kiện nhấp chuột được kích hoạt nếu bạn nhấp vào giữa hai tab khác nhau (vì chúng là hai tab khác nhau documentvà do đó bạn đang nhấp vào tài liệu.

Nếu cả hai đều không phải là câu trả lời, việc đăng HTML sẽ đi một chặng đường dài để tìm ra nó.


4

Một bài viết cũ, nhưng tôi muốn chia sẻ vì tôi gặp trường hợp tương tự nhưng cuối cùng tôi đã biết vấn đề:

Vấn đề là: Chúng tôi tạo một hàm để làm việc với một phần tử HTML được chỉ định, nhưng phần tử HTML liên quan đến chức năng này vẫn chưa được tạo (vì phần tử đã được tạo động). Để làm cho nó hoạt động, chúng ta nên tạo hàm cùng lúc chúng ta tạo phần tử. Yếu tố đầu tiên hơn là tạo chức năng liên quan đến nó.

Nói một cách đơn giản, một hàm sẽ chỉ hoạt động với phần tử được tạo trước nó (anh ta). Bất kỳ phần tử nào tạo ra động đều có nghĩa là sau anh ta.

Nhưng vui lòng kiểm tra mẫu này mà không để ý đến trường hợp trên:

<div class="btn-list" id="selected-country"></div>

Được nối thêm động:

<button class="btn-map" data-country="'+country+'">'+ country+' </button>

Chức năng này hoạt động tốt bằng cách nhấp vào nút:

$(document).ready(function() {    
        $('#selected-country').on('click','.btn-map', function(){ 
        var datacountry = $(this).data('country'); console.log(datacountry);
    });
})

hoặc bạn có thể sử dụng cơ thể như:

$('body').on('click','.btn-map', function(){ 
            var datacountry = $(this).data('country'); console.log(datacountry);
        });

so sánh với điều này không hoạt động:

$(document).ready(function() {     
$('.btn-map').on("click", function() { 
        var datacountry = $(this).data('country'); alert(datacountry);
    });
});

hy vọng nó sẽ giúp


Bạn có thể tránh sử dụng $ (document) .ready để đợi phần tử được thêm vào DOM nếu thay vào đó bạn bắt đầu bằng $ (document) .on ("click" ... $ (document) .on ("click", "# select-country", function () {});
Loren

3

Những công việc này:

<div id="start-element">Click Me</div>

$(document).on("click","#test-element",function() {
    alert("click");
});

$(document).on("click","#start-element",function() {
    $(this).attr("id", "test-element");
});

Đây là Fiddle


1
Đó không phải là một phần tử được tạo động, theo câu hỏi.
itsmejodie

@itsmejodie - đã đồng ý, nhưng nó bị ràng buộc động với trình xử lý sự kiện. thay đổi id về cơ bản không khác gì thêm một phần tử DOM.
iGanja

1

Thử đi:

$("#test-element").on("click" ,function() {
    alert("click");
});

Cách làm của tài liệu cũng kỳ lạ. Điều đó sẽ có ý nghĩa đối với tôi nếu được sử dụng cho một bộ chọn lớp, nhưng trong trường hợp của một id, bạn có thể chỉ có DOM vô dụng đi ngang qua đó. Trong trường hợp của bộ chọn id, bạn sẽ nhận được phần tử đó ngay lập tức.


2
Làm thế nào là điều này khác với $("#test-element").click(function() {?
Sushanth -

2
Bạn phải sử dụng .on () để liên kết các sự kiện với các DOM được tạo động - bất kỳ thứ gì được liên kết với .click () sẽ cố gắng liên kết khi tài liệu đã sẵn sàng và nếu dom không có thì sẽ không có gì xảy ra.
JTravakh

2
Nhưng sử dụng .onmà không cần sử dụng một selectorcũng giống như trực tiếp áp dụng các sự kiện click vào nó
Sushanth -

1
Đây không phải là câu trả lời chính xác cho câu hỏi. Điều này sẽ liên kết trực tiếp với phần tử và do đó không phù hợp khi phần tử đã được tạo động.
itsmejodie

1
Tôi thực sự đã đọc tài liệu, nhưng phần về hiệu suất thực sự không liên quan gì đến trình xử lý sự kiện được ủy quyền và mã của bạn không phải là trình xử lý sự kiện được ủy quyền.
adeneo
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.