2011-08-16 15 views
88

jQueryを使用せずに、特定のdata-属性を持つすべてのdom要素を選択する最も効率的な方法は何ですか(data-fooとしましょう)。要素は異なるタグ要素であってもよい。javascript: "data-"属性(jQueryなし)を持つすべての要素を選択する

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

IE7では 'document.querySelectorAll'は動作しません。 * DOMツリーを歩き回り、各タグの属性をチェックするフォールバックスクリプトを作成する必要があります(実際には 'querySelectorAll'がどれほど速く、タグの手動チェックのために行くのかわかりません)。 –

+0

jQueryを使用しない理由は何ですか?これはこのような状況ではほとんど不可能です。 –

+0

あなたは純粋なCSSでもこれらの要素を選択することすらできません。 – Knu

答えて

198

あなたはquerySelectorAllを使用することができます:ここ-1で私をdingedが、誰

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

パーフェクト、ありがとう! Semi-related note:名前にコロンを含む属性を選択する場合は、次のようにコロン(少なくともChromeでは)をエスケープする必要があります。querySelectorAll( '[attribute \\:name]') ://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); 
    } 
} 

わからないが証拠です。

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

+1

あなたのほとんど「正しい」は正しくありません。私はあなたが-1を与えたことをかなり確信しています。なぜなら、要素を取得し、配列に配列を入れるという余分な作業が多いからです。私は-1を与えてくれませんでした。 – Loktar

+1

高価(ページ上のすべての要素)、配列リテラル表記([])も使用し、その上には機能しません。自分で見てください - > http://jsbin.com/ipisul/edit#javascript,html – shawndumas

+2

OPはHTML 5を使用していますが、古いIEビルドではグローバル( '*')セレクタ付きの 'getElementsByTagName'が壊れています。ここで、再帰的なDOM検索でジョブが完了します。また、 'data-foo'属性からマップされたElementNodeには" data-foo "プロパティもありません。あなたは 'dataset'オブジェクトを探しています(' node.dataset.foo' –

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

あなたにその属性を持つすべての要素を取得します。それは要素にダミーのプロパティを追加するために、ブラウザのCSSのエンジンを使用しています。

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

これまでの2016年のhasOwnPropertyの使用は私にとって最高の答えでしたが、これは他の反復方法に関して非常に高速です[Mdn hasOwnProperty](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty) – Cryptopat

-1

Hereの値を持つものが興味深いソリューションであなたを取得しますセレクタに一致させ、計算されたスタイルを評価して一致する要素を見つける:

それはスタイルルールを動的に作成します。[ を大量に書き出し、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; 
     } 
    } 
} 

あなたは、次でそれを開始することができます。異なるとhttp://jsbin.com/unajot/1/edit

例:あなたの仕様に

スピードについてrecurseDOM(document.body, {"1": 1});、または単にrecurseDOM(document.body);

例仕様:http://jsbin.com/unajot/2/edit

+10

'querySelectorAll'の問題点は何ですか? – ShreevatsaR

+3

私もこれらの問題について聞いてみたいと思います。 –

関連する問題