web-dev-qa-db-ja.com

jQueryを使用せずに「data-」属性を持つすべての要素を選択します

JavaScriptのみを使用して、特定のdata-属性を持つすべてのDOM要素を選択する最も効率的な方法は何ですか(たとえば、data-fooとしましょう)。要素は異なるタグ要素でもかまいません。

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

querySelectorAll を使用できます。

document.querySelectorAll('[data-foo]');
295
Joe
document.querySelectorAll("[data-foo]")

その属性を持つすべての要素を取得します。

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

値が1のもののみを取得します。

169
Joseph Marikle

試してみる→こちら

    <!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>
11
shawndumas
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/

0
Brian

Here は興味深いソリューションです。ブラウザCSSエンジンを使用して、セレクタに一致する要素にダミープロパティを追加し、計算されたスタイルを評価して一致する要素を見つけます。

スタイルルールを動的に作成します[...]その後、ドキュメント全体をスキャンし(多くの非難されたIE固有の非常に高速なdocument.allを使用)、各要素の計算されたスタイルを取得します。次に、結果のオブジェクトでfooプロパティを探し、「bar」として評価されるかどうかを確認します。一致する要素ごとに、配列に追加します。

0

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

0
user1385191