जावास्क्रिप्ट: कैसे एक पृष्ठ पर सभी डोम तत्वों के माध्यम से पाश करने के लिए?


156

मैं एक पृष्ठ पर सभी तत्वों पर लूप करने की कोशिश कर रहा हूं, इसलिए मैं एक विशेष वर्ग के लिए इस पृष्ठ पर मौजूद प्रत्येक तत्व की जांच करना चाहता हूं।

तो, मैं कैसे कहूं कि मैं हर तत्व की जांच करना चाहता हूं?


1
क्या आप वाकई हर तत्व के माध्यम से लूप करना चाहते हैं? क्यों नहीं कि विशेष वर्ग के तत्वों को हथियाने के लिए jquery और चयनकर्ताओं का उपयोग किया जाए?
एन.जी.

क्या कोई डॉक्यूमेंट नहीं है ।getElementsByTagName विधि?
सुपरजेडि २२४

* TL; DR: केवल-दृश्य तत्वों के लिए, उपयोग करें:document.body.getElementsByTagName('*')
एंड्रयू

Iterate with:for (... of ...) { }
एंड्रयू 10

जवाबों:


252

आप एक पारित कर सकते हैं *करने के लिए 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 पर फॉरचेक का समर्थन करते हैं । इसका मतलब है कि आप सीधे लूप के लिए अपने लिखने के बजाय तत्वों को लूप कर सकते हैं।

document.querySelectorAll('*').forEach(function(node) {
    // Do whatever you want with the node object.
});

प्रदर्शन नोट - आप जो खोज रहे हैं, उसे करने की पूरी कोशिश करें। एक सार्वभौमिक चयनकर्ता पृष्ठ की जटिलता के आधार पर बहुत सारे नोड लौटा सकता है। यहां तक ​​कि अगर आपको किसी की हर चीज को देखने की जरूरत है, तो इसका मतलब है कि आप 'body *'चयनकर्ता के रूप में सभी headसामग्री को काट सकते हैं।


2
यह विधि बहुत अच्छी लगती है, लेकिन मैं ऊपरी विधि में एक तत्व का चयन कैसे कर सकता हूं? मुझे केवल इंडेक्स 'i' मिला है?
फ्लोरियन मुलर

2
@ फ़्लोरियन: जैसे आप एक ऐरे एलिमेंट को एक्सेस all[i]करेंगे - वैसा ही आपको एलीमेंट तत्व देगा।
एंडी ई

2
पाश के पक्ष में तत्व का चयन कैसे करें?
देबिप्रसाद

2
@ जेसे एल्ड्रिज: बस आदत का एक बल / अच्छा अभ्यास। प्रत्येक पुनरावृत्ति पर संपत्ति की खोज से बचना आमतौर पर एक माइक्रो-ऑप्टिमाइज़ेशन है, लेकिन इसे लिखना विशेष रूप से अधिक कठिन नहीं है और इसलिए मैं इसे स्वाभाविक रूप से करता हूं।
एंडी ई

2
@ जोनाथन getElementsByClassName()की तुलना में बदतर समर्थन है querySelectorAll()(पूर्व IE 8 में समर्थित नहीं है)। ओपी ने स्पष्ट रूप से कहा कि वह एक पृष्ठ पर सभी तत्वों पर लूप करना चाहता है , जिसके लिए मैंने उसे समाधान दिया और एक विकल्प की पेशकश की। मुझे यकीन नहीं है कि समस्या क्या है; ;-)
एंडी ई

39

उसी की तलाश में था। खैर, बिल्कुल नहीं। मैं केवल सभी 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);
}

एमडीएन पर समाधान पाया


कभी डॉक्यूमेंट नहीं देखा ।ceeateNodeIterator दिलचस्प लगता है कि जेएस क्या नई सुविधाएँ लाता है;)
फ्लोरियन मुलर

2
इसकी एक शांत विशेषता यह है कि नोडिटर भी html में दिखाई देने वाले क्रम में नोड्स को चलता है। मुझे आश्चर्य है कि अगर उनमें से कुछ document.body.getElementsByTagName('*')तले हुए क्रम में नोड्स वापस कर सकते हैं।
सिविल

वाह यह वास्तव में अच्छी तरह से समर्थित है!
रोज़गारपैक

15

हमेशा की तरह पुनरावृत्ति का उपयोग करने के लिए सबसे अच्छा समाधान है:

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

अन्य सुझावों के विपरीत, इस समाधान के लिए आपको सभी नोड्स के लिए एक सरणी बनाने की आवश्यकता नहीं है, इसलिए मेमोरी पर इसकी अधिक रोशनी। अधिक महत्वपूर्ण बात, यह अधिक परिणाम पाता है। मुझे यकीन नहीं है कि वे परिणाम क्या हैं, लेकिन क्रोम पर परीक्षण करते समय इसकी तुलना में लगभग 50% अधिक नोड्स मिलते हैंdocument.getElementsByTagName("*");


19
पुनरावर्तन का उपयोग करने का सबसे अच्छा समय पुनरावर्तन का उपयोग करने का सबसे अच्छा समय है।
एडम्लिव

8
"यह तुलना में लगभग 50% अधिक नोड्स पाता है document.getElementsByTagName("*");" - हाँ, यह पाठ नोड्स और टिप्पणी नोड्स के साथ-साथ तत्व नोड्स को भी ढूंढेगा । जैसा कि ओपी केवल तत्वों के बारे में पूछ रहा था, वह अनावश्यक है।
पॉल डी। वेइट

1
यह स्मृति पर हल्का हो सकता है। आप प्रत्येक स्तर की पुनरावृत्ति में कितना करते हैं, इस पर निर्भर करते हुए, आप नीचे तक पहुंचने तक एक शक्तिशाली बड़ी कॉल स्टैक का निर्माण कर सकते हैं। A NodeListकेवल Nodeउस DOM को संदर्भित कर रहा है जो पहले से आपके DOM में बना हुआ है, इसलिए यह उतना भारी नहीं है जितना आप कल्पना कर सकते हैं। कोई व्यक्ति जो अधिक जानता है, में वजन कर सकता है, लेकिन मुझे लगता है कि यह सिर्फ एक स्मृति संदर्भ आकार है, इसलिए प्रति नोड 8 बाइट्स।
Qaribou

9

यहाँ एक और उदाहरण है कि आप किसी दस्तावेज़ या किसी तत्व के माध्यम से कैसे लूप कर सकते हैं:

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


3

एंडी ई। ने अच्छा जवाब दिया।

यदि आप कुछ विशेष चयनकर्ता (हाल ही में मेरी जरूरत हो गई है) में सभी चिल्ड का चयन करना चाहते हैं, तो मैं जोड़ूंगा, आप चाहें तो किसी भी DOM ऑब्जेक्ट पर "getElementsByTagName ()" विधि लागू कर सकते हैं।

एक उदाहरण के लिए, मुझे वेब पेज के "दृश्य" भाग को पार्स करने की आवश्यकता थी, इसलिए मैंने इसे बनाया

var visualDomElts = document.body.getElementsByTagName('*');

यह कभी भी सिर के हिस्से को ध्यान में नहीं रखेगा।


अति उत्कृष्ट! । । ।
एंड्रयू

2

इस लिंक
जावास्क्रिप्ट संदर्भ से

<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

    }

इस एसओ चर्चा के अनुसार , के document.allपक्ष में हतोत्साहित किया जाता है document.getElementBy*
thejoshwolfe

@Thejoshwolfe धन्यवाद, आप मेरे समाजिक समाधान के बारे में क्या सोचते हैं जो मैंने अपडेट किया है
shareef



0

सभी तत्वों का उपयोग 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);

}

-1

आप के साथ कोशिश कर सकते हैं document.getElementsByClassName('special_class');


4
सही तरीका है getElementsByClassName()और यह इंटरनेट एक्सप्लोरर द्वारा संस्करण 9 तक समर्थित नहीं है
एंडी ई
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.