ページ上のすべての要素をループ処理しようとしているので、このページに存在するすべての要素をチェックして、特別なクラスを探します。
それで、すべての要素をチェックしたいと言うにはどうすればよいですか?
document.body.getElementsByTagName('*')
for (... of ...) { }
ページ上のすべての要素をループ処理しようとしているので、このページに存在するすべての要素をチェックして、特別なクラスを探します。
それで、すべての要素をチェックしたいと言うにはどうすればよいですか?
document.body.getElementsByTagName('*')
for (... of ...) { }
回答:
a *
を渡してgetElementsByTagName()
、ページ内のすべての要素を返すことができます。
var all = document.getElementsByTagName("*");
for (var i=0, max=all.length; i < max; i++) {
// Do something with the element here
}
が使用querySelectorAll()
可能な場合(IE9 +、IE8のCSS)、特定のクラスの要素を検索するために使用できることに注意してください。
if (document.querySelectorAll)
var clsElements = document.querySelectorAll(".mySpeshalClass");
else
// loop through all elements instead
これは確かに最新のブラウザの問題をスピードアップするでしょう。
ブラウザはNodeListでforeachをサポートするようになりました。つまり、独自のforループを作成する代わりに、要素を直接ループできます。
document.querySelectorAll('*').forEach(function(node) {
// Do whatever you want with the node object.
});
パフォーマンスのメモ -探しているものを対象とするために最善を尽くしてください。ユニバーサルセレクターは、ページの複雑さに応じて多くのノードを返すことができます。誰かが目にする可能性のあるすべてを調べる必要がある場合でも、
'body *'
すべてのhead
コンテンツを切り取るセレクターとして使用できます。
all[i]
、現在の要素を取得します。
getElementsByClassName()
はquerySelectorAll()
(前者はIE 8ではサポートされていません)よりもサポートが劣っています。OP は、ページ上のすべての要素をループしたいことを明確に述べていました。そのため、私は彼にソリューションを提供し、代替案を提供しました。何が問題なのか、私にはわかりません;-)。
同じを探していました。まあ、そうではありません。私はすべてのDOMノードをリストしたかっただけです。
var currentNode,
ni = document.createNodeIterator(document.documentElement, NodeFilter.SHOW_ELEMENT);
while(currentNode = ni.nextNode()) {
console.log(currentNode.nodeName);
}
特定のクラスの要素を取得するには、フィルター関数を使用できます。
var currentNode,
ni = document.createNodeIterator(
document.documentElement,
NodeFilter.SHOW_ELEMENT,
function(node){
return node.classList.contains('toggleable') ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
}
);
while(currentNode = ni.nextNode()) {
console.log(currentNode.nodeName);
}
MDNで見つかったソリューション
document.body.getElementsByTagName('*')
スクランブルされた順序でノードを返すことができるのだろうか。
常に最善の解決策は再帰を使用することです:
loop(document);
function loop(node){
// do some thing with the node here
var nodes = node.childNodes;
for (var i = 0; i <nodes.length; i++){
if(!nodes[i]){
continue;
}
if(nodes[i].childNodes.length > 0){
loop(nodes[i]);
}
}
}
他の提案とは異なり、このソリューションでは、すべてのノードの配列を作成する必要がないため、メモリの負荷が軽減されます。さらに重要なことに、それはより多くの結果を見つけます。それらの結果が何であるかはわかりませんが、Chromeでテストすると、document.getElementsByTagName("*");
document.getElementsByTagName("*");
見つかったノードの数は約50%増加しています」—そうです。テキストノード、コメントノード、および要素ノードが見つかります。OPが要素について尋ねているだけなので、それは不要です。
NodeList
は単にNode
DOMに既に組み込まれているを参照しているだけなので、想像するほど重くはありません。もっと知っている人は重さを量ることができますが、それは単なるメモリ参照サイズなので、ノードあたり8バイトだと思います。
次に、ドキュメントまたは要素をループ処理する別の例を示します。
function getNodeList(elem){
var l=new Array(elem),c=1,ret=new Array();
//This first loop will loop until the count var is stable//
for(var r=0;r<c;r++){
//This loop will loop thru the child element list//
for(var z=0;z<l[r].childNodes.length;z++){
//Push the element to the return array.
ret.push(l[r].childNodes[z]);
if(l[r].childNodes[z].childNodes[0]){
l.push(l[r].childNodes[z]);c++;
}//IF
}//FOR
}//FOR
return ret;
}
Jqueryを使用している人のために
$("*").each(function(i,e){console.log(i+' '+e)});
このリンク
JavaScriptリファレンスから
<html>
<head>
<title>A Simple Page</title>
<script language="JavaScript">
<!--
function findhead1()
{
var tag, tags;
// or you can use var allElem=document.all; and loop on it
tags = "The tags in the page are:"
for(i = 0; i < document.all.length; i++)
{
tag = document.all(i).tagName;
tags = tags + "\r" + tag;
}
document.write(tags);
}
// -->
</script>
</head>
<body onload="findhead1()">
<h1>Heading One</h1>
</body>
</html>
更新:編集
私の最後の答え以来、私はより簡単な解決策を見つけました
function search(tableEvent)
{
clearResults()
document.getElementById('loading').style.display = 'block';
var params = 'formAction=SearchStocks';
var elemArray = document.mainForm.elements;
for (var i = 0; i < elemArray.length;i++)
{
var element = elemArray[i];
var elementName= element.name;
if(elementName=='formAction')
continue;
params += '&' + elementName+'='+ encodeURIComponent(element.value);
}
params += '&tableEvent=' + tableEvent;
createXmlHttpObject();
sendRequestPost(http_request,'Controller',false,params);
prepareUpdateTableContents();//function js to handle the response out of scope for this question
}
すべての要素をvar all = document.getElementsByTagName("*"); for (var i=0, max=all.length; i < max; i++);
チェックする必要がある場合は、使用してすべての要素を取得できますが、繰り返しの要素またはテキストのチェックまたはループが発生します。
以下は、すべてのDOM要素の各要素を一度だけチェックまたはループして追加する再帰の実装です。
(@George Reithによる再帰の回答は、 HTMLからJSON へのマッピングです)
function mapDOMCheck(html_string, json) {
treeObject = {}
dom = new jsdom.JSDOM(html_string) // use jsdom because DOMParser does not provide client-side Window for element access
document = dom.window.document
element = document.querySelector('html')
// Recurse and loop through DOM elements only once
function treeHTML(element, object) {
var nodeList = element.childNodes;
if (nodeList != null) {
if (nodeList.length) {
object[element.nodeName] = []; // IMPT: empty [] array for parent node to push non-text recursivable elements (see below)
for (var i = 0; i < nodeList.length; i++) {
console.log("nodeName", nodeList[i].nodeName);
if (nodeList[i].nodeType == 3) { // if child node is **final base-case** text node
console.log("nodeValue", nodeList[i].nodeValue);
} else { // else
object[element.nodeName].push({}); // push {} into empty [] array where {} for recursivable elements
treeHTML(nodeList[i], object[element.nodeName][object[element.nodeName].length - 1]);
}
}
}
}
}
treeHTML(element, treeObject);
}