2012-01-06 25 views
190

Tôi đang sử dụng jQuery v.1.7.1 trong đó phương thức .live() dường như không còn được dùng nữa.Phương thức jQuery .live() vs .on() để thêm một sự kiện nhấp sau khi tải html động

Vấn đề tôi đang gặp là khi động tải html vào một yếu tố sử dụng:

$('#parent').load("http://..."); 

Nếu tôi cố gắng và thêm một sự kiện nhấp chuột sau đó nó không đăng ký sự kiện bằng cách sử dụng một trong các phương pháp:

$('#parent').click(function() ...); 

hoặc

// according to documentation this should be used instead of .live() 
$('#child').on('click', function() ...); 

cách chính xác để đạt được fu này là gì nctionality? Nó chỉ có vẻ làm việc với .live() cho tôi, nhưng tôi không nên sử dụng phương pháp đó. Lưu ý rằng #child là phần tử được tải động.

Cảm ơn.

+24

Tại sao bạn nói * "được cho là không được dùng nữa" *? Bạn không tin các tài liệu? –

+6

Nó không được chấp nhận _supposedly_: nó _is_ không được chấp nhận. Nếu bạn nhìn vào [jQuery doco cho '.live()'] (http://api.jquery.com/live/), nó sẽ cho bạn biết cách viết lại các sử dụng hiện tại của '.live()' để sử dụng '.delegate() 'hoặc' .on() '(tùy thuộc vào việc bạn đang sử dụng phiên bản 1.7+ hay không). Lưu ý rằng mặc dù nếu bạn thêm một trình xử lý bằng '.click()' "sau đó" như bạn đề cập, tức là sau khi nạp động các phần tử, nó sẽ hoạt động - vấn đề duy nhất đang cố gắng gán với '.click() '_before_ tải các phần tử động. – nnnnnn

+0

Tôi đã thay đổi từ ngữ thành 'rõ ràng' vì đó là những gì tôi muốn nói. Dù sao, bây giờ tôi hiểu rằng rõ ràng vì sự kiện .load() là không đồng bộ thì phần tử #child chỉ có thể được nhận ra một cách đáng tin cậy trong trình xử lý thành công, điều này có ý nghĩa. –

Trả lời

543

Nếu bạn muốn trình xử lý nhấp chuột hoạt động cho phần tử được tải động, thì bạn đặt trình xử lý sự kiện trên đối tượng cha mẹ (không được tải động) và cung cấp cho bộ chọn phù hợp với đối tượng động của bạn như thế này : handler

$('#parent').on("click", "#child", function() {}); 

sự kiện này sẽ được gắn vào đối tượng #parent và bất cứ lúc nào một sự kiện click bong bóng lên đến nó có nguồn gốc từ #child, nó sẽ cháy handler nhấp chuột của bạn. Điều này được gọi là xử lý sự kiện được ủy quyền (xử lý sự kiện được ủy quyền cho một đối tượng cha).

Nó thực hiện theo cách này bởi vì bạn có thể đính kèm sự kiện để các đối tượng #parent ngay cả khi đối tượng #child chưa hề tồn tại, nhưng khi sau đó nó tồn tại và được nhấp vào, sự kiện click sẽ bong bóng lên đến đối tượng #parent, nó sẽ thấy rằng nó bắt nguồn từ #child và có trình xử lý sự kiện cho một nhấp chuột vào số #child và kích hoạt sự kiện của bạn.

+2

Giải thích tốt, cảm ơn. –

+17

** Lời giải thích tuyệt vời **! Tôi đã không bao giờ có thể quấn đầu của tôi xung quanh 'sống()' so với 'on()' nhưng đêm nay tôi quyết định một lần nữa để thử, và lời giải thích của bạn ngay lập tức tiết lộ những gì tôi đã mất tích tất cả cùng. Cảm ơn! – MikeSchinkel

+4

** Một triệu lượt **. Tôi bắt đầu sử dụng loại trực tiếp trước khi tôi nhận ra điều này là có thể trong jQuery cho trẻ em được tạo động, cảm ơn bạn rất nhiều. –

20

$(document).on('click', '#selector', function() { /* do stuff */ });

EDIT: Tôi đang cung cấp thêm một chút thông tin về cách làm việc này, bởi vì ... lời nói. Với ví dụ này, bạn đang đặt một người nghe trên toàn bộ tài liệu.

Khi bạn click trên bất kỳ yếu tố (s) phù hợp với #selector, sự kiện bong bóng lên đến tài liệu chính - chừng nào không có người nghe khác mà gọi event.stopPropagation() phương pháp - mà có thể đứng đầu bọt của một sự kiện đến các yếu tố cha mẹ .

Thay vì liên kết với một phần tử cụ thể hoặc tập hợp các phần tử, bạn đang nghe bất kỳ sự kiện nào đến từ các yếu tố phù hợp với bộ chọn được chỉ định. Điều này có nghĩa là bạn có thể tạo một người nghe, một lần, điều đó sẽ tự động khớp với các phần tử hiện có cũng như bất kỳ phần tử được thêm động nào.

Đây là thông minh cho một vài lý do, bao gồm cả hiệu suất và sử dụng bộ nhớ (trong các ứng dụng quy mô lớn)

+0

Ông đã cố gắng .on() và nói rằng nó không làm việc ... –

+22

Anh ta đã thử '$ (phần tử) .on (...)'. Đây là '$ (tài liệu) .on (..., phần tử, ...)'. Những con thú khác nhau. – cHao

+0

Điều này làm việc hoàn hảo cho tôi, cảm ơn !! –

4

.Trên() là dành cho jQuery phiên bản 1.7 trở lên. Nếu bạn có một phiên bản cũ, sử dụng này:

$("#SomeId").live("click",function(){ 
    //do stuff; 
}); 
+8

OP nói "Tôi đang sử dụng jQuery v.1.7.1" –

+0

Tất cả những gì tôi thực sự có thể cho bạn biết là nó không được hỗ trợ bên dưới. Tôi đã có may mắn với on() tự của tôi và hoàn nguyên để sống() trên một ứng dụng doanh nghiệp chạy jQuery 1.7.1. –

+0

'.live()' đã không được chấp nhận cho tất cả các phiên bản của jQuery. Trước 1.7, bạn nên sử dụng '.delegate()', không phải '.live()'. – jfriend00

32

Hãy thử điều này:

$('#parent').on('click', '#child', function() { 
    // Code 
}); 

Từ các tài liệu $.on():

xử lý tổ chức sự kiện đang bị ràng buộc duy nhất với các yếu tố hiện đang được chọn; họ phải tồn tại trên trang tại thời điểm mã của bạn thực hiện cuộc gọi đến .on().

yếu tố #child của bạn không tồn tại khi bạn gọi $.on() trên nó, vì vậy sự kiện này không bị ràng buộc (không giống như $.live()). Tuy nhiên, #parent, hiện có, vì vậy việc ràng buộc sự kiện đó là tốt.

Đối số thứ hai trong mã của tôi ở trên hoạt động như một 'bộ lọc' để chỉ kích hoạt nếu sự kiện sôi nổi lên đến #parent từ #child.

+0

Nếu tôi gọi phương thức $ .on() sau phương thức $ .load(), thì tại sao phần tử #child tồn tại tại thời điểm đó? –

+6

@SeanThoman - bạn phải gọi nó từ trình xử lý thành công của phương thức '.load()' - không phải từ mã sau phương thức '.load()'. '# child' chỉ được biết là được nạp khi trình xử lý thành công thực sự thực hiện và không phải trước đây. – jfriend00

+0

và thậm chí sau đó thời gian cần để chèn bất kỳ dữ liệu nào bạn đã quay trở lại DOM có nghĩa là nó có thể không kết nối. Tôi đã làm rất nhiều công việc ứng dụng trang đơn gần đây và tiêu chuẩn của tôi là var $ body = $ ('body'); $ body.on ("event", ".element/# class", hàm (e) {}); cho tất cả. 1 bộ chọn. Không lo lắng về những gì là hoặc không được tải. – lupos

11

Tương đương .live() trong 1,7 trông như sau:

$(document).on('click', '#child', function() ...); 

Về cơ bản, xem các tài liệu cho các sự kiện nhấp chuột và lọc chúng cho #child.

+1

Tại sao $ (tài liệu)? –

+0

Vì đó là cách trình xử lý sự kiện gắn vào tài liệu (cách thức '.live()' làm). – cHao

+16

Một lý do khiến '.live()' không được chấp nhận bây giờ là bởi vì nó là xấu để đặt tất cả các trình xử lý sự kiện trực tiếp trên đối tượng tài liệu. Mọi thứ có thể thực sự, thực sự chậm lại. Các sự kiện không chỉ làm bong bóng tất cả các cách lên đến tài liệu, nhưng bạn có thể có rất nhiều trình xử lý sự kiện để xem xét trên đối tượng tài liệu. Lợi thế chính của '.on()' là bạn có thể đính kèm nó vào một đối tượng cha mẹ gần với đối tượng thực tế hơn và cải thiện đáng kể hiệu năng. Vì vậy ... tôi sẽ KHÔNG khuyên bạn nên sử dụng '.on()' với đối tượng tài liệu. Tốt hơn hết là chọn một đối tượng cha mẹ gần hơn. – jfriend00

3

Tôi đã sử dụng 'live' trong dự án của mình nhưng một người bạn của tôi đã đề xuất rằng tôi nên sử dụng 'on' thay vì trực tiếp. Và khi tôi cố gắng sử dụng, tôi đã gặp phải vấn đề như bạn đã gặp phải.

Trên các trang của tôi, tôi tạo các nút trong bảng và nhiều thứ tự động trên trang chủ. nhưng khi tôi sử dụng phép thuật biến mất.

Các giải pháp khác như sử dụng nó như một đứa trẻ chỉ gọi các chức năng của bạn mỗi lần trên mỗi lần nhấp. Nhưng tôi tìm thấy một cách để làm cho nó xảy ra một lần nữa và đây là giải pháp.

Viết mã của bạn như:

function caller(){ 
    $('.ObjectYouWntToCall').on("click", function() {...magic...}); 
} 

Gọi người gọi(); sau khi bạn tạo đối tượng trong trang như thế này.

$('<dom class="ObjectYouWntToCall">bla... bla...<dom>').appendTo("#whereeveryouwant"); 
caller(); 

Bằng cách này, chức năng của bạn được gọi khi được cho là không phải mọi nhấp chuột trên trang.

8

Tôi biết hơi muộn để có câu trả lời, nhưng tôi đã tạo một polyfill cho phương thức .live(). Tôi đã thử nghiệm nó trong jQuery 1.11, và nó có vẻ hoạt động khá tốt. Tôi biết rằng chúng ta phải thực hiện phương thức .on() ở bất kỳ nơi nào có thể, nhưng trong các dự án lớn, nơi mà không thể chuyển đổi tất cả các cuộc gọi .live() thành .on() công việc:

if(jQuery && !jQuery.fn.live) { 
    jQuery.fn.live = function(evt, func) { 
     $('body').on(evt, this.selector, func); 
    } 
} 

Chỉ cần bao gồm sau khi bạn tải jQuery và trước khi bạn gọi trực tiếp().

Các vấn đề liên quan