2012-06-09 32 views
39

Tôi có một trang bằng cách sử dụng hộp thoại jquery-ui. Mỗi khi hộp thoại mở ra, tải nội dung trang bằng ajax. Sau đó, nó liên kết một số sự kiện bằng cách sử dụng jquery "on()". Khi hộp thoại đóng, nó sẽ làm trống nội dung của nó.Tôi có cần hủy liên kết sự kiện jquery trước khi xóa phần tử không?

Câu hỏi là, tôi có cần hủy liên kết sự kiện trên ".ajax-content" trước $ .empty() không?

chỉnh sửa: mối quan tâm 1. bất kỳ hiệu suất suy thoái JS có thể? nếu tôi trống() hàng trăm nút theo cách này.

quan tâm 2. sẽ xóa phần tử cũng xóa sự kiện khỏi bộ nhớ (hoặc chuỗi thực thi/chuỗi đánh giá)?

Tôi hiện không làm bất cứ điều gì với họ. Nếu hộp thoại mở/đóng nhiều lần mà không làm mới trang, nó có gây ra bất kỳ sự cố nào không?

Mã nhìn như thế này:

<div id="jquery-dialog" class="container"> 
    <div class="ajax-content"> 
    some buttons.... 
    </div> 
</div> 

------after each ajax load------------ 
$(".ajax-content").on("click", ".button", function(event) { 
    //handles the click 
}); 

------on dialog close------------ 
$("#jquery-dialog").empty(); 
+3

+1: Thật là một câu hỏi hay? Tôi cũng quan tâm đến điều này. – vietean

Trả lời

43

Tôi biết đây là câu trả lời cũ nhưng tôi tin câu trả lời được chấp nhận là gây hiểu lầm.

Mặc dù chính xác là bạn sẽ cần hủy liên kết sự kiện trên JS thô để tránh rò rỉ bộ nhớ trên trình duyệt cũ (ehem IE), gọi remove() hoặc empty() sẽ làm điều đó cho bạn.

Vì vậy, cuộc gọi hiện tại của bạn để trống() nên là đủ, nó không cần phải được đi trước bởi unbind()

Từ jQuery docs (http://api.jquery.com/empty/)

Để tránh rò rỉ bộ nhớ, jQuery loại bỏ các cấu trúc khác như dữ liệu và trình xử lý sự kiện từ các phần tử con trước khi loại bỏ các phần tử.

+1

Cảm ơn câu trả lời. – Reed

+0

Cảm ơn bạn ... ngắn gọn, đến mức, và cung cấp tài liệu tham khảo tài liệu. +1 – greaterKing

1

Nó tốt hơn để unbind nhưng phải.

Hầu hết các trình duyệt xử lý chính xác và xóa các trình xử lý đó.

Bạn cũng có thể nhìn thấy do-i-need-to-remove-event-listeners

Better cách để xử lý vấn đề này, bạn có thể sử dụng các sự kiện đại biểu.

+0

Cảm ơn bạn đã liên kết. Đã học được điều gì đó mới mẻ. – Reed

-1

Câu trả lời của Oscar chưa hoàn chỉnh, nếu bên trong một phần (xem được tải qua ajax) bạn đính kèm sự kiện bằng .on(), thì bạn phải gọi .off() trước .empty().

Tìm mã sau, nếu .off() không được gọi, các sự kiện được chỉ định trong p1.html qua trình xử lý tiêu chuẩn .click() sẽ bị xóa khi gọi .empty(), nhưng các sự kiện được chỉ định trong p2.html qua. on() không bị xóa và được gán lại mỗi lần tải một phần.

chỉ mục.html

<html> 
<body> 
<script src="ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script> 
    <div id='spi' style="padding: 20px; border: 1px solid #666;"> 
    </div> 
    <br/> 
    <a href="p1.html" class="spi">Load Partial 1</a> | 
    <a href="p2.html" class="spi">Load Partial 2</a> 
    <script type="text/javascript"> 
    $(document).on('click', 'a.spi' , function(e) { 
     e.preventDefault(); 

     /* 
     !!! IMPORTANT !!! 
     If you do not call .off(), 
     events assigned on p2.html via .on() 
     are kept and fired one time for each time p2.html was loaded 
     */ 

     $("#spi").off(); 


     $("#spi").empty(); 
     $("#spi").load($(this).attr('href')); 
    }); 
    </script> 
</body> 
</html> 

p1.html

This is the partial 1<br/> 
<br/> 
<br/> 
<a href="javascript:void(0)" id='p1_l1'>Link 1</a> 
<br/><br/> 
<a href="javascript:void(0)" id='p1_l2'>Link 2</a> 
<br/><br/> 
<a href="javascript:void(0)" id='p1_l3'>Link 3</a> 


<script type="text/javascript"> 
    $("#p1_l1").click(function(e) { 
     e.preventDefault(); 
     console.debug("P1: p1_l1"); 
    }); 
    $("#p1_l2").click(function(e) { 
     e.preventDefault(); 
     console.debug("P1: p1_l2"); 
    }); 
</script> 

p2.html

This is the partial 2<br/> 
<br/> 
<br/> 
<a href="javascript:void(0)" id='p2_l1'>Link 1</a> 
<br/><br/> 
<a href="javascript:void(0)" id='p2_l2'>Link 2</a> 


<script type="text/javascript"> 
    $("#spi").on('click', 'a', function(e) { 
     e.preventDefault(); 
     console.debug('P2: ' + $(this).attr('id')); 
    }); 
</script> 
+0

Khi bạn gọi tới .on() trên p2.html sự kiện được đính kèm vào '#spi' (không phải cho phần tử 'a' bên trong). Khi bạn sau đó .empty() nó sau này, bạn đang unbinding sự kiện gắn liền với 'a' yếu tố nhưng những người trên '#spi' persist.Tôi nghĩ rằng nếu bạn viết lại $ ("# spi"). 'click', 'a', function) thành $ ("# spi a"). ('click', function) bạn sẽ có hiệu ứng bạn muốn. – Oscar

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