चाइल्डनॉड्स के माध्यम से लूप


85

मैं इस तरह चाइल्डकोड्स के माध्यम से लूप करने की कोशिश कर रहा हूं:

var children = element.childNodes;
children.forEach(function(item){
    console.log(item);
});

हालाँकि, यह फ़ंक्शन के Uncaught TypeError: undefined is not a functionकारण आउटपुट forEachकरता है। मैं childrenइसके बजाय उपयोग करने की कोशिश करता हूं childNodesलेकिन कुछ भी नहीं बदला।

क्या किसी को पता है कि क्या चल रहा है?

जवाबों:


124

चर childrenएक NodeListउदाहरण है और NodeListएस सच नहीं हैं Arrayऔर इसलिए वे forEachविधि को विरासत में नहीं लेते हैं ।

इसके अलावा कुछ ब्राउज़र वास्तव में इसका समर्थन करते हैं nodeList.forEach


ES5

आप उपयोग कर सकते हैं sliceसे Arrayकन्वर्ट करने के लिए NodeListएक उचित में Array

var array = Array.prototype.slice.call(children);

आप इसे केवल संदर्भ के रूप में callलागू करने forEachऔर पास करने के लिए भी उपयोग कर सकते हैं NodeList

[].forEach.call(children, function(child) {});


ES6

आप fromअपने NodeListको एक में बदलने के लिए विधि का उपयोग कर सकते हैं Array

var array = Array.from(children);

या आप इस तरह फैल सिंटैक्स का... उपयोग भी कर सकते हैं

let array = [ ...children ];


एक हैक जिसका उपयोग किया जा सकता है NodeList.prototype.forEach = Array.prototype.forEachऔर आप हर बार उन्हें बदलने के लिए बिना forEachकिसी के साथ उपयोग कर सकते हैं NodeList

NodeList.prototype.forEach = Array.prototype.forEach
var children = element.childNodes;
children.forEach(function(item){
    console.log(item);
});

NodeLists, Arrays में एक व्यापक गोता देखें , NodeLists परिवर्तित करना और एक अच्छी व्याख्या और इसे करने के अन्य तरीकों के लिए DOM को समझना


मैं NodeList को शुद्ध सरणी में कैसे बदल सकता हूं?
user3828771

उदाहरण के साथ अपडेट किया गया लेकिन मैंने जो लिंक पोस्ट किया है, उसे पढ़कर यह सब स्पष्ट हो जाता है :)
गिलेस्क

2
वैकल्पिक रूप से, आप ऐसा कर सकते हैं:[].forEach.call(element.childNodes, child => console.log(child))
XåpplI'-I0llwlg'I -

2
यहां तक ​​कि कूलर es6 रास्ता: let items = [ ...children ]इसे एक सरणी में बदल देगा
zackify करें

2
नोडलिस्टों के लिए एरे तरीकों को लागू करने के साथ एक प्रमुख गेटचा है: नोड जैसे नोड नोडलिस्ट लाइव लिस्ट हैं, और यदि आप अपने लूप के दौरान डोम को हेरफेर करते हैं तो नोडलिस्ट बदलने के अधीन है, जिसका अर्थ है कि कॉलबैक फॉर फॉर () मेरा नहीं कहा जाता है। सूची के प्रत्येक तत्व - या उससे अधिक तत्व मूल रूप से सूची में थे - अप्रत्याशित परिणामों के लिए अग्रणी। इस पर लूपिंग करने से पहले एक नोडलिस्ट को एक सरणी में बदलना बेहतर होता है।
Stephband 13

30

मुझे पार्टी में बहुत देर हो चुकी है, लेकिन चूंकि element.lastChild.nextSibling === null, निम्नलिखित मुझे सबसे सीधा विकल्प लगता है:

for(var child=element.firstChild; child!==null; child=child.nextSibling) {
    console.log(child);
}

1
सबसे सरल विकल्प "लूप" के लिए नियमित रूप से उपयोग करना है। लेकिन आपका विकल्प दिलचस्प है।
किरिल रेजनिकोव

मुझे यह सबसे अच्छा लगता है, उसी को लागू करने की योजना बना रहा था .. तार्किक और रूपांतरणों की आवश्यकता नहीं
उज्जवल सिंह

23

यहाँ आप इसे for-inलूप के साथ कैसे कर सकते हैं ।

var children = element.childNodes;

for(child in children){
    console.log(children[child]);
}

14
आप चेक के बारे में भूल गए: अगर (children.hasOwnProperty (बच्चा)) {// कोड यहाँ} या आप "लंबाई" और आदि जैसे अवांछित प्रॉप्स पर प्रसारित करेंगे!
किरिल रेजनिकोव

8
इससे भी बेहतर: उपयोग for ... of ..., यह ES6 वाक्यविन्यास है, हालांकि।
जेसपेरेंटेंड

5

का उपयोग कर एक और विधि जोड़ने के लिए विरोध नहीं कर सका childElementCount। यह दिए गए माता-पिता से बाल तत्व नोड्स की संख्या लौटाता है, इसलिए आप इस पर लूप कर सकते हैं।

for(var i=0, len = parent.childElementCount ; i < len; ++i){
    ... do something with parent.children[i]
    }

4

forपाश के साथ प्रयास करें । यह त्रुटि देता है forEachक्योंकि यह नोड्स का संग्रह है nodelist

या यह नोड-सूची को सरणी में परिवर्तित करना चाहिए

function toArray(obj) {
  var array = [];
  for (var i = 0; i < obj.length; i++) { 
    array[i] = obj[i];
  }
return array;
}

या आप इसका उपयोग कर सकते हैं

var array = Array.prototype.slice.call(obj);


2

यह कोशिश करें [रिवर्स ऑर्डर ट्रैवर्सल]:

var childs = document.getElementById('parent').childNodes;
var len = childs.length;
if(len --) do {
    console.log('node: ', childs[len]);
} while(len --);

या [क्रम में]

var childs = document.getElementById('parent').childNodes;
var len = childs.length, i = -1;
if(++i < len) do {
    console.log('node: ', childs[i]);
} while(++i < len);

लूप के लिए लूप की तुलना में सरल अधिक पठनीय है। लेखक रिवर्स / उलटा ऑर्डर ट्रैवर्सल के लिए नहीं पूछता है।
किरिल रेजनिकोव

2

यहाँ एक से अधिक पुनरावृत्ति का एक कार्यात्मक ES6 तरीका है NodeList। इस विधि का उपयोग करता Arrayहै forEachतो जैसे:

Array.prototype.forEach.call(element.childNodes, f)

जहां fइट्रेटर फ़ंक्शन है जो एक चाइल्ड नोड प्राप्त करता है क्योंकि यह पहला पैरामीटर है और दूसरा के रूप में इंडेक्स।

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

const forEach = f => x => Array.prototype.forEach.call(x, f);

// For example, to log all child nodes
forEach((item) => { console.log(item); })(element.childNodes)

// The functional forEach is handy as you can easily created curried functions
const logChildren = forEach((childNode) => { console.log(childNode); })
logChildren(elementA.childNodes)
logChildren(elementB.childNodes)

(आप map()अन्य ऐरे कार्यों के लिए एक ही चाल कर सकते हैं ।)


0

यदि आप इस प्रकार की बहुत सारी चीजें करते हैं तो यह आपके लिए फ़ंक्शन को परिभाषित करने के लायक हो सकता है।

if (typeof NodeList.prototype.forEach == "undefined"){
    NodeList.prototype.forEach = function (cb){
        for (var i=0; i < this.length; i++) {
            var node = this[i];
            cb( node, i );
        }
    };
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.