2011-08-16 163 views
88

不使用jQuery,選擇具有特定data-屬性(假設爲data-foo)的所有dom元素的最有效方法是什麼。元素可以是不同的標籤元素。javascript:選擇所有具有「data-」屬性的元素(不含jQuery)

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

請記住,「document.querySelectorAll」在IE7上不起作用。你將不得不創建一個後備腳本,它會*走DOM樹並檢查每個標籤中的屬性(實際上我不知道'querySelectorAll'有多快,並且會去手工檢查標籤)。 –

+0

你不使用jQuery的原因是什麼?在這樣的情況下,這幾乎是不可替代的...... –

+0

@hay根本不用你甚至可以在純css中選擇這些元素。 – Knu

回答

198

您可以使用querySelectorAll

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

完美,謝謝!與半相關的注意事項:如果你想在名稱中選擇一個冒號的屬性,你需要像冒號一樣冒號(至少在Chrome中):querySelectorAll('[attribute \\:name]')(參見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); 
    } 
} 

不知道誰丁當作響我-1,但這裏的證明。

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

+1

你的大多數「正確」只是不正確。我很確定有人給你-1,因爲你做了很多額外的工作來獲取元素,然後將集合放入一個數組中。我沒有給-1只是不喜歡,當沒有解釋一個人。 – Loktar

+1

昂貴(頁面上的所有元素),也使用數組文字符號(即[]),並且在它之上,它不起作用。自己去看看 - > http://jsbin.com/ipisul/edit#javascript,html – shawndumas

+2

儘管OP使用HTML 5,但是使用全局('*')選擇器的'getElementsByTagName'在早期的IE版本中被打破了。這是遞歸DOM搜索完成工作的地方。在'data-foo'屬性映射的ElementNode上也沒有「data-foo」屬性。你正在尋找'dataset'對象(即:'node.dataset.foo'。 – 2011-08-16 20:57:24

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

將讓你與屬性的所有元素。

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

將只能得到你的人用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

使用hasOwnProperty是2016年迄今爲止我的最佳答案,關於其他迭代方法[Mdn hasOwnProperty](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty) – Cryptopat

-1

Here是一個有趣的解決方案的值:它使用的瀏覽器CSS引擎添加一個虛擬屬性的元素匹配選擇器,然後評估計算出的風格以找到匹配的元素:

它會動態創建一個樣式規則[...]然後掃描整個文檔(使用 很多被譴責和IE特定但非常快的document.all),並獲取每個元素的計算樣式 。然後,我們查找結果對象上的foo 屬性,並檢查它是否評估爲 「bar」。對於每個匹配的元素,我們添加到一個數組。

+2

它被標記爲html5所以它不會是 shawndumas

+1

對,我刪除了暗示舊的瀏覽器。 –

+0

不錯;)... – shawndumas

2

雖然不一樣漂亮querySelectorAll(其中有問題,一連串的),這裏是一個非常靈活的功能是遞歸的DOM,並應在大多數瀏覽器(新老)工作。只要瀏覽器支持你的條件(即:數據屬性),你應該能夠檢索元素。

好奇:不要打擾在jsPerf上測試這個與QSA。像Opera 11這樣的瀏覽器會緩存查詢並歪曲結果。

代碼:

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; 
     } 
    } 
} 

然後,您可以用下面的啓動它:

recurseDOM(document.body, {"1": 1});速度,或者只是recurseDOM(document.body);

例與規格:http://jsbin.com/unajot/1/edit

例具有不同規格:http://jsbin.com/unajot/2/edit

+10

'querySelectorAll'的問題是什麼? – ShreevatsaR

+3

我也很想聽聽這些問題。 –

相關問題