JavaScriptのみを使用して、特定のdata-
属性を持つすべてのDOM要素を選択する最も効率的な方法は何ですか(たとえば、data-foo
としましょう)。要素は異なるタグ要素でもかまいません。
<p data-foo="0"></p><br/><h6 data-foo="1"></h6>
querySelectorAll を使用できます。
document.querySelectorAll('[data-foo]');
document.querySelectorAll("[data-foo]")
その属性を持つすべての要素を取得します。
document.querySelectorAll("[data-foo='1']")
値が1のもののみを取得します。
<!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>
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を付けたのかわからないが、ここにその証拠がある。
Here は興味深いソリューションです。ブラウザCSSエンジンを使用して、セレクタに一致する要素にダミープロパティを追加し、計算されたスタイルを評価して一致する要素を見つけます。
スタイルルールを動的に作成します[...]その後、ドキュメント全体をスキャンし(多くの非難されたIE固有の非常に高速なdocument.allを使用)、各要素の計算されたスタイルを取得します。次に、結果のオブジェクトでfooプロパティを探し、「bar」として評価されるかどうかを確認します。一致する要素ごとに、配列に追加します。
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