8

Giả sử tôi đã đính kèm nhiều trình xử lý sự kiện khác nhau vào các phần tử biểu mẫu khác nhau. Sau đó, tôi muốn xóa toàn bộ biểu mẫu.Trình xử lý sự kiện javascript có cần phải được xóa trước khi xóa phần tử mà chúng được đính kèm không?

Có cần thiết (hoặc đề xuất) hủy đăng ký mọi trình xử lý sự kiện tồn tại trên biểu mẫu và các thành phần của nó không? Nếu vậy, cách dễ nhất để loại bỏ tất cả người nghe trên một tập hợp các phần tử là gì? Hậu quả của việc không làm như vậy là gì? Tôi đang sử dụng Prototype, nếu nó quan trọng.

Đây là những gì tôi thực sự đang làm. Tôi có một hình thức đơn giản, như thế này:

<form id="form"> 
    <input type="text" id="foo"/> 
    <input type="text" id="bar"/> 
</form> 

tôi quan sát các sự kiện khác nhau trên đầu vào, ví dụ:

$('foo').observe('keypress', onFooKeypress); 
$('bar').observe('keypress', onBarKeypress); 

, vv

Các mẫu được gửi qua AJAX và phản ứng là bản sao mới của biểu mẫu. Tôi thay thế các hình thức cũ với một bản sao của cái mới làm một cái gì đó như $('form').replace(newForm). Tôi đang tích lũy một loạt các sự kiện cruft?

Trả lời

3

Vâng, một chút. Không đủ để trở thành một vấn đề lớn, nhưng các phiên bản cũ của IE sẽ bị rò rỉ trong những trường hợp đó.

Kể từ nguyên mẫu 1.6.1 (hiện đang trong ứng cử viên phát hành cuối cùng), thư viện xử lý việc dọn dẹp này khi tải trang xuống. Khi bạn sử dụng Prototype để thêm một người quan sát sự kiện, nó giữ một tham chiếu đến phần tử đó trong một mảng; trên trang unload, nó lặp qua mảng đó và loại bỏ tất cả các nhà quan sát của bạn.

Tuy nhiên, nếu người dùng sẽ ở lại trang này một thời gian, mức sử dụng bộ nhớ sẽ tích luỹ trong suốt vòng đời của trang. Bạn có một vài lựa chọn:

  1. Nghe cho các sự kiện trên một tổ tiên của mẫu, một trong đó không bao giờ được thay thế. Sau đó, trong trình xử lý của bạn, hãy kiểm tra xem sự kiện đến từ đâu. (ví dụ: "ủy quyền sự kiện")

  2. Xóa hoàn toàn tất cả các cuộc gọi của bạn trước khi gọi Element#replace. Trong ví dụ của bạn, bạn sẽ làm:

    $('foo', 'bar').each(Element.stopObserving); 
    

này tương đương với gọi stopObserving không có đối số, trong đó có tác dụng loại bỏ tất cả xử lý trên một yếu tố nhất định.

Tôi muốn giới thiệu tùy chọn 1.

(Chúng tôi đã nói chuyện về việc loại bỏ người nghe tự động trong một phiên bản tương lai của Prototype như một phần của Element#updateElement#replace, nhưng đó là một hoạt động thương mại-off.)

4

Các sự kiện không được đăng ký có thể không tự động giải phóng bộ nhớ của chúng. Điều này đặc biệt là một vấn đề trong các phiên bản cũ của IE.

Nguyên mẫu được sử dụng để có hệ thống thu gom rác tự động cho điều này, nhưng phương pháp đã bị xóa trong phiên bản 1.6. Nó được ghi thành here. Cho dù việc loại bỏ phương pháp có nghĩa là việc thu gom rác không còn diễn ra, hoặc phương pháp không còn công khai nữa, tôi không biết. Cũng lưu ý rằng nó chỉ được gọi là bỏ trang, nghĩa là nếu người dùng của bạn ở trên cùng một trang trong một thời gian dài trong khi thực hiện rất nhiều cập nhật AJAX và DOM, bộ nhớ có thể bị rò rỉ đến mức không thể chấp nhận ngay cả trong lần truy cập trang đó.

0

Bạn luôn có thể xóa mọi trình xử lý sự kiện khỏi các yếu tố bị xóa khỏi DOM trong trường hợp kịch bản mà Jonas đã đề cập bên dưới.

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