2009-07-21 35 views
16

Tôi đang phát triển mã bằng cách sử dụng jQuery và cần lưu trữ dữ liệu được liên kết với các phần tử DOM nhất định. Có một loạt các câu hỏi khác về cách để lưu trữ dữ liệu tùy ý bằng phần tử html, nhưng tôi quan tâm hơn đến lý do tại sao tôi chọn một tùy chọn so với phần còn lại.Sử dụng kho dữ liệu của jQuery so với các thuộc tính expando

Nói, vì lợi ích của đối số cực kỳ đơn giản, tôi muốn lưu trữ thuộc tính "lineNumber" với mỗi hàng trong một bảng "thú vị".

Lựa chọn 1 sẽ được chỉ cần thiết lập một tài sản expando trên mỗi phần tử DOM (Tôi hy vọng Tôi đang sử dụng thuật ngữ 'expando' một cách chính xác):

$('.interesting-line').each(function(i) { this.lineNumber = i; }); 

Lựa chọn 2 sẽ sử dụng dữ liệu của jQuery() để liên kết thuộc tính với phần tử:

$('.interesting-line').each(function(i) { $(this).data('lineNumber', i); }); 

Bỏ qua bất kỳ thiếu sót nào khác của mã mẫu của tôi, có lý do chính đáng để bạn chọn phương tiện lưu trữ tài sản khác không?

Trả lời

12

Nếu bạn là tác giả của plugin, bạn nên sử dụng $.data. Nếu bạn cần phải lưu trữ các thuộc tính thường xuyên và hiếm khi cần phải truy vấn DOM cho nó sau đó sử dụng $.data.

Có nói rằng đối với tất cả các ứng dụng của khách hàng của tôi, tôi có xu hướng đối với lưu trữ tùy chỉnh DOM thuộc tính trên phần tử DOM mình để tôi có thể truy vấn chúng sau này sử dụng thuộc tính [] selector:

var domElement = $('.interesting-line[lineNumber=' + lineNumber + ']').get(0); 

Đây là nhiều hơn nữa có thể đọc được bằng cách lặp lại bộ gói được gọi .data() trên mỗi mục. Thường thì tôi đang liên kết với một thư viện bên thứ ba khác hoạt động trên một phần tử DOM để có thể truy cập nhanh chóng và dễ dàng vào phần tử DOM thông qua cơ chế này giữ cho mã có thể đọc được. Nó dễ dàng như việc lưu trữ ánh xạ bảng tra cứu lineNumbers đến các phần tử, tuy nhiên kỹ thuật thuộc tính expando ít rủi ro rò rỉ bộ nhớ hơn, vì bạn không lưu trữ các tham chiếu đến các phần tử DOM mà bạn cần dọn dẹp sau này.

Cập nhật 5 năm sau Chỉ cần đọc này sau khi nó nhận được một [cũng xứng đáng] downvote: xin vui lòng bỏ qua các văn bản striked trên. jQuery thực hiện không phải truy vấn DOM dựa trên các thuộc tính expando được đặt và đã không làm như vậy trong một thời gian. Vì vậy, hãy sử dụng $.data. Không có lý do gì để gây ô nhiễm DOM khi không có sử dụng thực dụng để làm như vậy.

+2

Có [một plugin jQuery] (http://plugins.jquery.com/files/jquery.dataSelector.js.txt) cho phép bạn sử dụng các bộ chọn như trong var 'domElement = $ ('. Interesting-line: data (" lineNumber = '+ lineNumber +' ") '). get (0);' – ErikE

2

Sử dụng $.data không sửa đổi DOM. Bạn nên sử dụng $.data. Nếu bạn đang tạo một plugin thì bạn nên lưu trữ một đối tượng trong $.data với các thuộc tính trên đối tượng đó trái ngược với việc lưu trữ từng thuộc tính đó dưới dạng cặp khóa/giá trị khác nhau trong cấu trúc $.data.

+2

lưu ý rằng đó là cách các kho lưu trữ $ .data hoạt động, vì vậy bạn chỉ cần thêm một mức độ gián tiếp bổ sung. nếu bạn tư vấn về điều này vì cách ly không gian tên, nó có thể được thực hiện một cách hiệu quả với tiền tố của một plugin cụ thể. được cấp, điều này sẽ chỉ có ý nghĩa nếu lưu trữ rất nhiều dữ liệu và/hoặc truy cập nó trên một vòng lặp chặt chẽ. bất cứ nơi nào khác, đó là vấn đề về sở thích phong cách – Javier

+1

Vâng, tôi muốn tránh sửa đổi DOM. IIRC, nó có thể gây ra một số rò rỉ bộ nhớ khá xấu trên một số trình duyệt. – seth

+0

@Javier: Tôi đã chuyển tiếp tài liệu cho $ .data. Tôi đồng ý rằng các lớp bổ sung của indirection không có vẻ như tất cả những gì có giá trị nhưng tài liệu nhà nước thực hành tốt nhất của nó. –

21

Sử dụng $.data sẽ bảo vệ bạn khỏi rò rỉ bộ nhớ.

Trong IE, khi bạn chỉ định đối tượng javascript cho thuộc tính expando trên phần tử DOM, các chu kỳ vượt qua liên kết đó không phải là rác được thu thập. Nếu đối tượng javascript của bạn giữ một tham chiếu đến đối tượng dom, toàn bộ chu kỳ sẽ bị rò rỉ. Nó hoàn toàn có thể kết thúc với các tham chiếu ẩn đối với các đối tượng DOM, do đóng cửa, vì vậy bạn có thể bị rò rỉ mà không nhận ra nó.

Kho dữ liệu jQuery được thiết lập để ngăn không cho các chu trình này hình thành. Nếu bạn sử dụng nó, bạn sẽ không bị rò rỉ bộ nhớ theo cách này. Ví dụ của bạn sẽ không bị rò rỉ vì bạn đang đặt các nguyên thủy (chuỗi) trên phần tử DOM. Nhưng nếu bạn đặt một vật thể phức tạp hơn ở đó, bạn có nguy cơ bị rò rỉ.

Sử dụng $.data để bạn không phải lo lắng.

+0

Điều này chỉ áp dụng cho IE7-, phải không? – thorn

+0

Nó chắc chắn là ít hơn rất nhiều cần thiết trong năm 2017 hơn là vào năm 2011! Tôi _think_ rằng IE8 có cùng một vấn đề, và nó được sửa trong IE9, nhưng tôi thực sự không biết. –

+0

Sẽ rất thiết thực để đính kèm dữ liệu trực tiếp vào các phần tử. Đơn giản hơn nhiều so với việc theo dõi rò rỉ bộ nhớ của jQuery do '$ .data' gây ra. – thorn

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