Cách lưu trữ dữ liệu tùy ý cho một số thẻ HTML


338

Tôi đang tạo một trang có một số tương tác được cung cấp bởi javascript. Cũng giống như một ví dụ: các liên kết gửi yêu cầu AJAX để lấy nội dung của bài viết và sau đó hiển thị dữ liệu đó trong div. Rõ ràng trong ví dụ này, tôi cần mỗi liên kết để lưu trữ thêm một chút thông tin: id của bài viết. Cách tôi xử lý trong trường hợp là đưa thông tin đó vào liên kết href này:

<a class="article" href="#5">

Sau đó tôi sử dụng jQuery để tìm các phần tử a.article và đính kèm trình xử lý sự kiện thích hợp. (đừng quá bận tâm về khả năng sử dụng hoặc ngữ nghĩa ở đây, đây chỉ là một ví dụ)

Dù sao, phương thức này hoạt động, nhưng nó có mùi một chút và hoàn toàn không thể mở rộng (điều gì xảy ra nếu hàm nhấp có nhiều hơn một tham số? Nếu một số tham số đó là tùy chọn thì sao?)

Câu trả lời rõ ràng ngay lập tức là sử dụng các thuộc tính trên phần tử. Ý tôi là, đó là những gì họ làm, phải không? (Loại).

<a articleid="5" href="link/for/non-js-users.html">

Trong câu hỏi gần đây của tôi, tôi đã hỏi liệu phương pháp này có hợp lệ không, và hóa ra việc thiếu định nghĩa DTD của riêng tôi (tôi không), thì không, nó không hợp lệ hoặc đáng tin cậy. Một câu trả lời chung là đưa dữ liệu vào classthuộc tính (mặc dù điều đó có thể là do ví dụ được chọn kém của tôi), nhưng với tôi, điều này còn có mùi hơn nữa. Vâng, nó hợp lệ về mặt kỹ thuật, nhưng nó không phải là một giải pháp tuyệt vời.

Một phương pháp khác mà tôi đã sử dụng trước đây là thực sự tạo ra một số JS và chèn nó vào trang trong một <script>thẻ, tạo ra một cấu trúc có thể liên kết với đối tượng.

var myData = {
    link0 : {
        articleId : 5,
        target : '#showMessage'
        // etc...
    },
    link1 : {
        articleId : 13
    }
};

<a href="..." id="link0">

Nhưng điều này có thể là một nỗi đau thực sự ở mông để duy trì và nói chung chỉ là rất lộn xộn.

Vì vậy, để đi đến câu hỏi, làm thế nào để bạn lưu trữ các mẩu thông tin tùy ý cho các thẻ HTML ?


2
Câu hỏi liên quan: stackoverflow.com/questions/209428/
Mạnh

Câu trả lời:


361

Phiên bản HTML nào bạn đang sử dụng?

Trong HTML 5, hoàn toàn hợp lệ khi có các thuộc tính tùy chỉnh được thêm tiền tố vào dữ liệu- , vd

<div data-internalid="1337"></div>

Trong XHTML, điều này không thực sự hợp lệ. Nếu bạn đang ở chế độ XHTML 1.1, trình duyệt có thể sẽ phàn nàn về nó, nhưng ở chế độ 1.0, hầu hết các trình duyệt sẽ chỉ âm thầm bỏ qua nó.

Nếu tôi là bạn, tôi sẽ làm theo cách tiếp cận dựa trên kịch bản. Bạn có thể làm cho nó tự động được tạo ở phía máy chủ để không phải chịu đau ở phía sau.


5
@Tchalvak: Đúng, nhưng bit này sẽ hoạt động trên hầu hết các trình duyệt, không hơn không kém.
Tamas Czinege

2
Những người khác đã tuyên bố rằng không có lý do để chờ đợi hỗ trợ, vì vấn đề duy nhất mà nguyên nhân này là không thể xác thực và nó không phá vỡ IE. Xem câu trả lời của TJ Crowler tại đây: stackoverflow.com/questions/1923278/,
Chris

42
Nếu bạn sử dụng các thuộc tính data-xxx và bạn muốn truy xuất chúng, bạn chỉ cần sử dụng "domEuity.getAttribution ('data-anything')" mà không cần bất kỳ khuôn khổ của bên thứ ba nào.
Ohad Kravchick


19
Nhắc nhở: Để truy xuất dữ liệu, 1337, thông qua jquery, hãy nhớ xóa 'dữ liệu' khỏi tên biến. Ví dụ: sử dụng: $(this).data('internalid'); Thay vì:$(this).data('data-internalid');
Gideon Rosenthal

134

Nếu bạn đã sử dụng jQuery rồi thì bạn nên tận dụng phương thức "dữ liệu", đây là phương pháp được đề xuất để lưu trữ dữ liệu tùy ý trên một phần tử dom với jQuery.

Để lưu trữ một cái gì đó:

$('#myElId').data('nameYourData', { foo: 'bar' });

Để lấy dữ liệu:

var myData = $('#myElId').data('nameYourData');

Đó là tất cả những gì có nhưng hãy xem tài liệu jQuery để biết thêm thông tin / ví dụ.


20

Chỉ là một cách khác, cá nhân tôi sẽ không sử dụng nhưng nó hoạt động (đảm bảo JSON của bạn hợp lệ vì eval () nguy hiểm).

<a class="article" href="link/for/non-js-users.html">
    <span style="display: none;">{"id": 1, "title":"Something"}</span>
    Text of Link
</a>

// javascript
var article = document.getElementsByClassName("article")[0];
var data = eval(article.childNodes[0].innerHTML);

1
+1 cho tư duy bên. Tôi đồng ý rằng tôi có thể sẽ không muốn sử dụng phương pháp này, nhưng đó là một lựa chọn mơ hồ khả thi!
nickf

9
@nickf Bạn có thể thoát khỏi việc evalsử dụng JSON.parsethay vào đó jsfiddle.net/EAXmY
Simon

12

Các thuộc tính tùy ý không hợp lệ, nhưng hoàn toàn đáng tin cậy trong các trình duyệt hiện đại. Nếu bạn đang thiết lập các thuộc tính thông qua javascript, thì bạn cũng không phải lo lắng về việc xác thực.

Một cách khác là đặt thuộc tính trong javascript. jQuery có một phương thức tiện ích tuyệt vời chỉ dành cho mục đích đó hoặc bạn có thể tự cuộn.


3
Tại sao không sử dụng data-thuộc tính thay thế?
Flimm

10

Một bản hack sẽ hoạt động với khá nhiều trình duyệt có thể là sử dụng các lớp mở như thế này: <a class='data\_articleid\_5' href="link/for/non-js-users.html>;

Đây không phải là tất cả thanh lịch đối với những người theo chủ nghĩa thuần túy, nhưng nó được hỗ trợ toàn cầu, tuân thủ tiêu chuẩn và rất dễ thao tác. Nó thực sự có vẻ như là phương pháp tốt nhất có thể. Nếu bạn serialize, sửa đổi , sao chép thẻ của bạn hoặc làm bất cứ điều gì khác,data sẽ vẫn được đính kèm, sao chép, v.v.

Vấn đề duy nhất là bạn không thể lưu trữ các đối tượng không tuần tự theo cách đó và có thể có giới hạn nếu bạn đặt một cái gì đó thực sự lớn ở đó.

Cách thứ hai là sử dụng các thuộc tính giả như:<a articleid='5' href="link/for/non-js-users.html">

Điều này thanh lịch hơn, nhưng phá vỡ tiêu chuẩn và tôi không chắc chắn 100% về hỗ trợ. Nhiều trình duyệt hỗ trợ đầy đủ, tôi nghĩ IE6 hỗ trợ JStruy cập cho nó nhưng khôngCSS selectors (điều này không thực sự quan trọng ở đây), có thể một số trình duyệt sẽ hoàn toàn bị nhầm lẫn, bạn cần kiểm tra nó.

Làm những việc buồn cười như tuần tự hóa và khử lưu huỳnh sẽ còn nguy hiểm hơn.

Sử dụng idsđể JSbăm thuần túy hầu hết hoạt động, ngoại trừ khi bạn cố gắng sao chép các thẻ của mình. Nếu bạn có tag <a href="..." id="link0">, sao chép nó thông qua các JSphương thức tiêu chuẩn , và sau đó cố gắng sửa đổi datađính kèm chỉ một bản sao, bản sao khác sẽ được sửa đổi.

Sẽ không có vấn đề gì nếu bạn không sao chép taghoặc sử dụng dữ liệu chỉ đọc . Nếu bạn sao chép tagvà họ đã sửa đổi, bạn cần xử lý thủ công.


lưu trữ valse trên lớp là tuyệt vời
Saravanan Rajaraman

10

Sử dụng jquery,

để lưu trữ: $('#element_id').data('extra_tag', 'extra_info');

lấy: $('#element_id').data('extra_tag');


6

Tôi biết rằng bạn hiện đang sử dụng jQuery, nhưng nếu bạn đã xác định nội tuyến của trình xử lý onclick. Sau đó, bạn có thể làm:

 <a href='/link/for/non-js-users.htm' onclick='loadContent(5);return false;'>
     Article 5</a>

6

Bạn có thể sử dụng các thẻ đầu vào ẩn. Tôi không nhận được lỗi xác thực tại w3.org với điều này:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang='en' xml:lang='en' xmlns='http://www.w3.org/1999/xhtml'>
  <head>
    <meta content="text/html;charset=UTF-8" http-equiv="content-type" />
    <title>Hello</title>
  </head>
  <body>
    <div>
      <a class="article" href="link/for/non-js-users.html">
        <input style="display: none" name="articleid" type="hidden" value="5" />
      </a>
    </div>
  </body>
</html>

Với jQuery, bạn sẽ nhận được ID bài viết với nội dung như (chưa được kiểm tra):

$('.article input[name=articleid]').val();

Nhưng tôi muốn giới thiệu HTML5 nếu đó là một tùy chọn.


13
Tôi thực sự không nghĩ style="display: none"là cần thiết cho các trường đầu vào ẩn.
phylae

1
Cách tiếp cận tốt, hoàn toàn hợp lệ trong tất cả các phiên bản HTML. Tôi hoàn toàn không khuyến khích mã hóa với giả định rằng tất cả người dùng của bạn sẽ có một trình duyệt khiếu nại HTML5 hoàn toàn. Và hiển thị: không cần thiết cho các trường ẩn.
andreszs

Rất đẹp. Đây là giải pháp tốt nhất tôi đã tìm thấy cho XHTML, nơi các thuộc tính dữ liệu không phải là một tùy chọn hợp lệ. IMO nó không lạm dụng thẻ / thuộc tính theo những cách ngoài ý muốn, nó gần như không có "mùi" nào cả. Và như những người khác đã nói: display: none không thực sự cần thiết.
Arahman

4

Tại sao không sử dụng dữ liệu có ý nghĩa đã có, thay vì thêm dữ liệu tùy ý?

ví dụ sử dụng <a href="https://stackoverflow.com/articles/5/page-title" class="article-link">, và sau đó bạn có thể lập trình được tất cả liên kết bài viết trên trang (thông qua classname) và ID bài viết (phù hợp với regex /articles\/(\d+)/chống lại this.href).


2
Vấn đề với điều này là nó cũng không thực sự mở rộng
ehv

4

Là người dùng jQuery, tôi sẽ sử dụng plugin Metadata . HTML trông rõ ràng, nó xác nhận và bạn có thể nhúng bất cứ thứ gì có thể được mô tả bằng cách sử dụng ký hiệu JSON.


3

Vì vậy, cần có bốn lựa chọn để làm như vậy:

  1. Đặt dữ liệu trong thuộc tính id.
  2. Đặt dữ liệu vào thuộc tính tùy ý
  3. Đặt dữ liệu vào thuộc tính lớp
  4. Đặt dữ liệu của bạn vào một thẻ khác

http://www.shanison.com/?p=321


@ h4ck3rm1k3 ... không thuộc tính id vì nó phải là tài liệu duy nhất trong tài liệu và nó sẽ được lặp lại nếu cần thiết trong một thanh bên, hoặc một cái gì đó ... Đó là một câu hỏi cũ, nhưng nó vẫn hợp lệ
Miguel-svq

2

Tôi ủng hộ việc sử dụng thuộc tính "rel". XHTML xác thực, bản thân thuộc tính hiếm khi được sử dụng và dữ liệu được truy xuất một cách hiệu quả.


Không thể làm id đó phá vỡ thuộc tính nofollow trên các liên kết
Carter Cole

2

Đây là lời khuyên tốt. Cảm ơn @Prestaul

Nếu bạn đã sử dụng jQuery rồi thì bạn nên tận dụng phương thức "dữ liệu", đây là phương pháp được đề xuất để lưu trữ dữ liệu tùy ý trên một phần tử dom với jQuery.

Rất đúng, nhưng nếu bạn muốn lưu trữ dữ liệu tùy ý trong HTML cũ thì sao? Đây là một thay thế khác ...

<input type="hidden" name="whatever" value="foobar"/>

Đặt dữ liệu của bạn trong các thuộc tính tên và giá trị của một yếu tố đầu vào ẩn. Điều này có thể hữu ích nếu máy chủ đang tạo HTML (tức là tập lệnh PHP hoặc bất cứ thứ gì) và mã JavaScript của bạn sẽ sử dụng thông tin này sau.

Phải thừa nhận rằng, không phải là sạch nhất, nhưng đó là một sự thay thế. Nó tương thích với tất cả các trình duyệt và XHTML hợp lệ. Bạn KHÔNG nên sử dụng các thuộc tính tùy chỉnh, cũng không nên thực sự sử dụng các thuộc tính có tiền tố 'data-', vì nó có thể không hoạt động trên tất cả các trình duyệt. Và, ngoài ra, tài liệu của bạn sẽ không vượt qua xác thực W3C.


không chắc chắn chính xác, nhưng một số trình duyệt có thể phàn nàn nếu bạn sử dụng các thuộc tính tùy chỉnh với loại tài liệu "nghiêm ngặt". Dù bằng cách nào, nó không hợp lệ XHTML.
BMiner

2

Bạn có thể sử dụng tiền tố dữ liệu của thuộc tính do chính bạn tạo ra của một yếu tố ngẫu nhiên (<span data-randomname="Data goes here..."></span> ), nhưng điều này chỉ hợp lệ trong HTML5. Do đó trình duyệt có thể phàn nàn về tính hợp lệ.

Bạn cũng có thể sử dụng một <span style="display: none;">Data goes here...</span>thẻ. Nhưng theo cách này, bạn không thể sử dụng các hàm thuộc tính và nếu css và js bị tắt, đây cũng không thực sự là một giải pháp gọn gàng.

Nhưng những gì cá nhân tôi thích là như sau:

<input type="hidden" title="Your key..." value="Your value..." />

Tất cả các trường hợp đầu vào sẽ bị ẩn, các thuộc tính hoàn toàn hợp lệ và nó sẽ không được gửi nếu nó nằm trong một <form>thẻ, vì nó không có bất kỳ tên nào, phải không? Trên hết, các thuộc tính thực sự dễ nhớ và mã trông đẹp và dễ hiểu. Bạn thậm chí có thể đặt thuộc tính ID vào đó, vì vậy bạn cũng có thể dễ dàng truy cập bằng JavaScript và truy cập cặp khóa-giá trị input.title; input.value.


Tôi chắc chắn rằng bạn đã không làm việc với các bảng html và lựa chọn khá đủ. Bạn sẽ sử dụng thuộc tính data- thường xuyên hơn để lưu một số công việc.

1
Tôi thực sự sử dụng thuộc tính 'data-' rất nhiều. Nhưng nó phụ thuộc vào yêu cầu của bạn là gì. Ví dụ: với <input /> bạn có thể có bất kỳ khóa nào, trong khi đối với 'data-', điều này được giới hạn ở một chuỗi chữ thường mà không có bất kỳ ký tự không chữ và số nào.
Yeti

1

Một khả năng có thể là:

  • Tạo một div mới để chứa tất cả dữ liệu mở rộng / tùy ý
  • Làm điều gì đó để đảm bảo rằng div này là vô hình (ví dụ: CSS cộng với một thuộc tính lớp của div)
  • Đặt dữ liệu mở rộng / tùy ý trong các thẻ [X] HTML (ví dụ như văn bản trong các ô của bảng hoặc bất kỳ thứ gì bạn có thể muốn) trong div vô hình này

1

Một cách tiếp cận khác có thể là lưu trữ cặp khóa: value dưới dạng một lớp đơn giản bằng cú pháp sau:

<div id="my_div" class="foo:'bar'">...</div>

Điều này là hợp lệ và có thể dễ dàng được lấy ra bằng các bộ chọn jQuery hoặc một hàm được tạo tùy chỉnh.


0

Tại nhà tuyển dụng trước của tôi, chúng tôi đã sử dụng các thẻ HTML tùy chỉnh mọi lúc để giữ thông tin về các thành phần của biểu mẫu. Lưu ý: Chúng tôi biết rằng người dùng đã buộc phải sử dụng IE.

Nó không hoạt động tốt cho FireFox tại thời điểm đó. Tôi không biết liệu FireFox có thay đổi điều này hay không, nhưng lưu ý rằng việc thêm các thuộc tính của riêng bạn vào các thành phần HTML có thể hoặc không được trình duyệt của trình đọc của bạn hỗ trợ.

Nếu bạn có thể kiểm soát trình duyệt nào mà trình đọc của bạn đang sử dụng (tức là một applet web nội bộ cho một công ty), thì bằng mọi cách, hãy thử nó. Nó có thể đau gì, phải không?


0

Đây là cách tôi làm cho bạn các trang ajax ... đây là một phương pháp khá dễ dàng ...

    function ajax_urls() {
       var objApps= ['ads','user'];
        $("a.ajx").each(function(){
               var url = $(this).attr('href');
               for ( var i=0;i< objApps.length;i++ ) {
                   if (url.indexOf("/"+objApps[i]+"/")>-1) {
                      $(this).attr("href",url.replace("/"+objApps[i]+"/","/"+objApps[i]+"/#p="));
                   }
               }
           });
}

Cách thức hoạt động của nó là về cơ bản nó nhìn vào tất cả các URL có lớp 'ajx' và nó thay thế một từ khóa và thêm dấu # ... vì vậy nếu js bị tắt thì các url sẽ hoạt động như bình thường ... tất cả " ứng dụng "(mỗi phần của trang web) có từ khóa riêng ... vì vậy tất cả những gì tôi cần làm là thêm vào mảng js ở trên để thêm nhiều trang ...

Vì vậy, ví dụ cài đặt hiện tại của tôi được đặt thành:

 var objApps= ['ads','user'];

Vì vậy, nếu tôi có một url như:

www.domain.com/ads/3923/bla/dada/bla

tập lệnh js sẽ thay thế / ads / part để URL của tôi cuối cùng trở thành

www.domain.com/ads/#p=3923/bla/dada/bla

Sau đó, tôi sử dụng plugin jqery bbq để tải trang phù hợp ...

http://benalman.com/projects/jquery-bbq-plugin/


0

Tôi đã tìm thấy plugin siêu dữ liệu là một giải pháp tuyệt vời cho vấn đề lưu trữ dữ liệu tùy ý bằng thẻ html theo cách giúp dễ dàng truy xuất và sử dụng với jQuery.

Quan trọng : Tệp thực tế bạn bao gồm chỉ có 5 kb chứ không phải 37 kb (là kích thước của gói tải xuống hoàn chỉnh)

Dưới đây là một ví dụ về nó đang được sử dụng để lưu trữ các giá trị tôi sử dụng khi tạo sự kiện theo dõi phân tích google (lưu ý: data.label và data.value là các tham số tùy chọn)

$(function () {
    $.each($(".ga-event"), function (index, value) {
        $(value).click(function () {
            var data = $(value).metadata();
            if (data.label && data.value) {
                _gaq.push(['_trackEvent', data.category, data.action, data.label, data.value]);
            } else if (data.label) {
                _gaq.push(['_trackEvent', data.category, data.action, data.label]);
            } else {
                _gaq.push(['_trackEvent', data.category, data.action]);
            }
        });
    });
});

<input class="ga-event {category:'button', action:'click', label:'test', value:99}" type="button" value="Test"/>

0

Trong html, chúng ta có thể lưu trữ các thuộc tính tùy chỉnh với tiền tố 'data-' trước tên thuộc tính như

<p data-animal='dog'>This animal is a dog.</p>. Kiểm tra tài liệu

Chúng tôi có thể sử dụng thuộc tính này để thiết lập động và nhận các thuộc tính bằng cách sử dụng jQuery như: Nếu chúng tôi có thẻ ap như

<p id='animal'>This animal is a dog.</p>

Sau đó, để tạo một thuộc tính được gọi là 'giống' cho thẻ trên, chúng ta có thể viết:

$('#animal').attr('data-breed', 'pug');

Để lấy dữ liệu bất cứ lúc nào, chúng tôi có thể viết:

var breedtype = $('#animal').data('breed');


0

Miễn là công việc thực tế của bạn được thực hiện trên máy chủ, tại sao bạn vẫn cần thông tin tùy chỉnh trong các thẻ html trong đầu ra? tất cả những gì bạn cần biết trên máy chủ là một chỉ mục vào bất kỳ loại danh sách cấu trúc nào với thông tin tùy chỉnh của bạn. Tôi nghĩ rằng bạn đang tìm cách lưu trữ thông tin không đúng chỗ.

Tuy nhiên, tôi sẽ nhận ra rằng thật không may, trong nhiều trường hợp, giải pháp đúng không phải là giải pháp đúng. Trong trường hợp đó, tôi thực sự khuyên bạn nên tạo một số javascript để giữ thông tin bổ sung.

Nhiều năm sau đó:

Câu hỏi này đã được đăng khoảng ba năm trước khi data-...các thuộc tính trở thành một tùy chọn hợp lệ với sự ra đời của html 5 vì vậy sự thật đã thay đổi và câu trả lời ban đầu tôi đưa ra không còn phù hợp nữa. Bây giờ tôi đề nghị sử dụng các thuộc tính dữ liệu thay thế.

<a data-articleId="5" href="link/for/non-js-users.html">

<script>
    let anchors = document.getElementsByTagName('a');
    for (let anchor of anchors) {
        let articleId = anchor.dataset.articleId;
    }
</script>

Làm thế nào bạn có thể truyền dữ liệu vào javascript?
nickf
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.