2011-08-16 35 views
88

Nếu không sử dụng jQuery, cách hiệu quả nhất để chọn tất cả các phần tử dom có ​​thuộc tính data- nhất định (giả sử data-foo). Các phần tử có thể là các phần tử thẻ khác nhau.javascript: chọn tất cả các phần tử có thuộc tính "data-" (không có jQuery)

<p data-foo="0"></p><br/><h6 data-foo="1"></h6> 
+0

Hãy nhớ rằng 'document.querySelectorAll' không hoạt động trên IE7. Bạn sẽ phải tạo một kịch bản dự phòng mà sẽ * đi bộ * cây DOM và kiểm tra thuộc tính trong mỗi thẻ (thực ra tôi không biết tốc độ 'querySelectorAll' là bao nhiêu và sẽ kiểm tra thủ công các thẻ). –

+0

Lý do bạn không sử dụng jQuery là gì? Nó là khá nhiều không thể thay thế trong các tình huống như thế này ... –

+0

@ không phải ở tất cả các bạn thậm chí có thể chọn các yếu tố này trong css tinh khiết quá. – Knu

Trả lời

198

Bạn có thể sử dụng querySelectorAll:

document.querySelectorAll('[data-foo]'); 
+4

Hoàn hảo, cảm ơn! Ghi chú bán liên quan: nếu bạn muốn chọn thuộc tính có dấu hai chấm trong tên, bạn cần phải thoát khỏi dấu hai chấm (ít nhất là trong Chrome) như sau: querySelectorAll ('[attribute \\: name]') (xem: http : //code.google.com/p/chromium/issues/detail? id = 91637) – Jeremy

0
var matches = new Array(); 

var allDom = document.getElementsByTagName("*"); 
for(var i =0; i < allDom.length; i++){ 
    var d = allDom[i]; 
    if(d["data-foo"] !== undefined) { 
     matches.push(d); 
    } 
} 

Không chắc người dinged tôi với một -1, nhưng đây là bằng chứng.

http://jsfiddle.net/D798K/2/

+1

chủ yếu là "đúng" của bạn không chính xác. Im khá chắc chắn ai đó đã cho bạn -1 bởi vì bạn làm rất nhiều công việc phụ để có được các yếu tố, và sau đó đưa các bộ sưu tập trong một mảng. Tôi không cung cấp cho -1 chỉ không thích khi không có lời giải thích cho một. – Loktar

+1

đắt tiền (tất cả các phần tử trên trang), cũng sử dụng ký pháp dạng mảng (nghĩa là []), và trên hết, nó không hoạt động. xem cho chính mình -> http://jsbin.com/ipisul/edit#javascript,html – shawndumas

+2

Mặc dù OP đang sử dụng HTML 5 anyways, 'getElementsByTagName' với bộ chọn toàn cục (' * ') bị hỏng trong các bản dựng IE cũ hơn. Đây là nơi một tìm kiếm DOM đệ quy nhận được công việc làm. Cũng không có thuộc tính "data-foo" trên một ElementNode được ánh xạ từ thuộc tính 'data-foo'. Bạn đang tìm đối tượng 'dataset' (ví dụ:' node.dataset.foo'. –

91
document.querySelectorAll("[data-foo]") 

sẽ giúp bạn có được tất cả các yếu tố có thuộc tính đó.

document.querySelectorAll("[data-foo='1']") 

sẽ chỉ giúp bạn có được những người thân với giá trị 1.

7

Try it → here

<!DOCTYPE html> 
    <html> 
     <head></head> 
     <body> 
      <p data-foo="0"></p> 
      <h6 data-foo="1"></h6> 
      <script> 
       var a = document.querySelectorAll('[data-foo]'); 

       for (var i in a) if (a.hasOwnProperty(i)) { 
        alert(a[i].getAttribute('data-foo')); 
       } 
      </script> 
     </body> 
    </html> 
+0

Sử dụng hasOwnProperty là câu trả lời tốt nhất cho tôi cho đến nay trong năm 2016, điều này rất nhanh liên quan đến các cách lặp khác [Mdn hasOwnProperty] (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty) – Cryptopat

-1

Here là một giải pháp thú vị: nó sử dụng động cơ trình duyệt CSS để thêm một tài sản giả đến các yếu tố phù hợp với công cụ chọn và sau đó đánh giá kiểu được tính để tìm các phần tử phù hợp:

Nó tự động tạo ra một quy tắc phong cách [...] Sau đó quét toàn bộ tài liệu (sử dụng nhiều tài liệu đã chết và IE cụ thể nhưng rất nhanh) và lấy phong cách tính toán cho từng phần tử. Sau đó chúng tôi tìm kiếm thuộc tính foo trên đối tượng kết quả và kiểm tra xem nó có đánh giá là “thanh” hay không. Đối với mỗi phần tử phù hợp, chúng tôi thêm vào một mảng.

+2

nó được đánh dấu html5 vì vậy nó sẽ không được shawndumas

+1

Phải, tôi đã xóa gợi ý về các trình duyệt cũ. –

+0

công việc tốt;) ... – shawndumas

2

Mặc dù không đẹp như querySelectorAll (có nhiều vấn đề), đây là một chức năng rất linh hoạt để đệ trình DOM và hoạt động trong hầu hết các trình duyệt (cũ và mới). Miễn là trình duyệt hỗ trợ điều kiện của bạn (ví dụ: thuộc tính dữ liệu), bạn sẽ có thể truy xuất phần tử.

Để tò mò: Đừng bận tâm kiểm tra điều này so với QSA trên jsPerf. Các trình duyệt như Opera 11 sẽ lưu lại truy vấn và nghiêng kết quả.

Code:

function recurseDOM(start, whitelist) 
{ 
    /* 
    * @start:  Node - Specifies point of entry for recursion 
    * @whitelist: Object - Specifies permitted nodeTypes to collect 
    */ 

    var i = 0, 
    startIsNode = !!start && !!start.nodeType, 
    startHasChildNodes = !!start.childNodes && !!start.childNodes.length, 
    nodes, node, nodeHasChildNodes; 
    if(startIsNode && startHasChildNodes) 
    {  
     nodes = start.childNodes; 
     for(i;i<nodes.length;i++) 
     { 
      node = nodes[i]; 
      nodeHasChildNodes = !!node.childNodes && !!node.childNodes.length; 
      if(!whitelist || whitelist[node.nodeType]) 
      { 
       //condition here 
       if(!!node.dataset && !!node.dataset.foo) 
       { 
        //handle results here 
       } 
       if(nodeHasChildNodes) 
       { 
        recurseDOM(node, whitelist); 
       } 
      } 
      node = null; 
      nodeHasChildNodes = null; 
     } 
    } 
} 

Sau đó, bạn có thể bắt đầu với những điều sau đây:

recurseDOM(document.body, {"1": 1}); cho tốc độ, hoặc chỉ recurseDOM(document.body);

Ví dụ với đặc điểm kỹ thuật của bạn: http://jsbin.com/unajot/1/edit

Ví dụ với khác nhau đặc điểm kỹ thuật: http://jsbin.com/unajot/2/edit

+10

Đâu là vấn đề với 'querySelectorAll'? – ShreevatsaR

+3

Tôi cũng rất muốn nghe về những vấn đề này. –

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