जावास्क्रिप्ट में, एक नोडलिस्ट को एक सरणी में बदलने का सबसे अच्छा तरीका क्या है?


84

DOM विधि document.querySelectorAll()(और कुछ अन्य) a लौटाते हैं NodeList

सूची का उपयोग करते हुए जैसे पर काम करने के लिए forEach(), NodeListचाहिए पहले एक करने के लिए परिवर्तित किया जा Array

सबसे अच्छा तरीका है कन्वर्ट करने के लिए क्या है NodeListएक करने के लिए Array?


1
मुझे लगता है कि querySelectorAll () का रिटर्न वैल्यू तकनीकी रूप से एक नोडलिस्ट कहलाता है।
jfriend00

से एमडीएम "elementList = document.querySelectorAll (चयनकर्ताओं);"
cc युवा

1
एलिमेंटलिस्ट वैरिएबल नाम है। उसी पृष्ठ का वर्णन है कि वापसी मूल्य का प्रकार एक नोडलिस्ट कैसे है।
jfriend00

सुधार के लिए धन्यवाद - प्रश्न में तय
cc युवा

जवाबों:


70

ES6 के साथ आप बस कर सकते हैं:

const spanList = [...document.querySelectorAll("span")];

1
यह मैं देताType 'NodeListOf<Element>' must have a '[Symbol.iterator]()' method that returns an iterator.ts(2488)
कॉलबैक

हाय @ कॉलबैक, यह टाइपस्क्रिप्ट संबंधित त्रुटि की तरह लगता है। आपने अपनी tsconfig फ़ाइल के लिब एरे में "es6" जोड़े बिना es6 संकलन को लक्षित करने के लिए चुना हो सकता है। सादर
फ्रीजिस्टिक्स

1
हाय @ फ्रीज, आप सही कह रहे हैं! मैं es2015 को लक्षित कर रहा हूं। धन्यवाद!
कॉलबैक

@ कॉलबैक ES6 और ES2015 एक ही चीज हैं
DarkNeuron

66

ES6 के साथ आप उपयोग कर सकते हैं Array.from(myNodeList)। फिर अपनी पसंदीदा सरणी विधि का उपयोग करें।

var myNodeList = document.querySelectorAll('.my-selector');

// ALT 1
Array.from(myNodeList).forEach(function(el) {
  console.log(el);
});

पुराने ब्राउज़र में भी यह काम करने के लिए ES6 शिम का उपयोग करें ।


यदि आप ट्रांसपिलर का उपयोग कर रहे हैं (उदाहरण के लिए बैबेल) तो दो और विकल्प हैं:

var myNodeList = document.querySelectorAll('.my-selector');

// ALT 2
for (var el of myNodeList) {
  el.classList.add('active'); // or some other action
}

// ALT 3
[...myNodeList].forEach((el) => {
  console.log(el);
});

यह भी सच नहीं है कि es6 के तहत एक नोडलिस्ट एक पुनरावृत्ति की आपूर्ति करता है?
cc युवा

4
@ccyoung लेकिन itter गैर-अनुरूप ES6 ब्राउज़रों में काम नहीं करता है क्योंकि आप प्रतीक वस्तु को नहीं Array.from(myNodeList)हिला सकते हैं इसलिए इसका उपयोग करना बेहतर है क्योंकि इसे चमकाया जा सकता है।
रोच

इसलिए मेरे पास यह मुद्दा है जहां Array.from (el.childNodes) सरणी के भाग के रूप में पहला नोड वापस नहीं करता है।
ज़िनोआदिदी

49

प्रोटोटाइप sliceसे विधि का उपयोग करके आप इसे एक सरणी में बदल सकते हैं Array:

var elList = document.querySelectorAll('.viewcount');
elList = Array.prototype.slice.call(elList, 0);

इसके अलावा, अगर आप सभी की जरूरत है forEach, तो आप आह्वान कर सकते हैं कि से Arrayप्रोटोटाइप, पहले एक सरणी के लिए यह मजबूर बिना:

var elList = document.querySelectorAll('.viewcount');
Array.prototype.forEach.call(elList, function(el) {
    console.log(el);
});

ES6 में, आप Array.fromइसे एक ऐरे में बदलने के लिए नए फ़ंक्शन का उपयोग कर सकते हैं :

Array.from(elList).forEach(function(el) {
    console.log(el);
});

यह वर्तमान में केवल ब्लीडिंग एज ब्राउज़र में है, लेकिन यदि आप एक पॉलीफ़िल सेवा का उपयोग कर रहे हैं, तो आपको इस फ़ंक्शन का उपयोग पूरे मंडल में करना होगा।


यदि आप ES6 ट्रांसपिलर का उपयोग कर रहे हैं , तो आप for..ofइसके बजाय लूप का उपयोग कर सकते हैं :

for (var element of document.querySelectorAll('.some .elements')) {
  // use element here
}

धन्यवाद। नए जावास्क्रिप्ट के तहत सोचा / उम्मीद की जा रही थी कि एक अधिक रसीला ज़बरदस्ती है।
सीसी जवान

6
युवा @cc - क्या ध्यान दें, कारण मैं उपयोग कर रहा हूँ Array.prototype.forEachके बजाय [].forEachक्योंकि बाद एक नई सरणी वस्तु है, जो पूरी तरह से अनावश्यक है बनाता है, है।
जोसफ सिलबर

@ जोसेफिल्बर आह धन्यवाद - कि खाली बनाया गया नया सरणी है []? मेरी सोच यह है कि इससे कचरा इकट्ठा हो जाएगा और स्मृति प्रभाव नगण्य है, क्या कोई इस पर टिप्पणी कर सकता है?
डैनियल सोकोलोव्स्की

@ डैनियल यह सच है, लेकिन अभी भी ऐरे को बनाने और नष्ट करने की गणना है।
ब्रेट

21

धर्मांतरण क्यों? - callतत्व संग्रह पर सीधे ऐरे का कार्य;)

[].forEach.call( $('a'), function( v, i) {
    // do something
});

यह सोचते हैं $ के लिए अपना उपनाम है querySelectorAll ज़ाहिर है,


संपादित करें: ES6 और भी छोटे सिंटैक्स के लिए अनुमति देता है [...$('a')]( केवल मई 2014 तक फ़ायरफ़ॉक्स में काम करता है )


यह मानते हुए $है querySelectorAll
c69

3
आपके उत्तर का तात्पर्य jQuery के उपयोग से है। अगर ऐसा है, तो यह कब्रिस्तान पूरी तरह से अनावश्यक है, इसके लिए धन्यवाद .each()
मैट बॉल

1
इतने जोर से क्यों हंस रहे हो ? कुछ भी नहीं आप की तरह उपनाम बनाने से मना करते हैं function $ ( s ) { return document.querySelectorAll(s); }
c69

5
यदि आप jQuery का उपयोग करने जा रहे हैं, तो अधिक रसीला समाधान है:$('a').each(function(i, v) {...});
jfriend00

2
offtopic: EcmaScript 5 एक वर्ष पहले से ही एक मानक है, सभी वर्तमान-पीढ़ी के ब्राउज़र Arrays के नए तरीकों का समर्थन करते हैं, और सवाल विशिष्ट रूप से NodeList उर्फ ​​तत्व संग्रह पर उन तरीकों का उपयोग करने के बारे में था।
c69

10

2020 अपडेट: नोडलीस्ट.फॉरच () अब एक आधिकारिक मानक है और सभी वर्तमान ब्राउज़रों में समर्थित है।

पुराने ब्राउज़र नीचे पॉलीफ़िल का उपयोग कर सकते हैं।

जावास्क्रिप्ट में सूची पर काम करने के लिए, उदाहरण के लिए forEach () का उपयोग करके, NodeList को एक Array में परिवर्तित किया जाना चाहिए।

यह सच नहीं है। .forEach()वर्तमान ब्राउज़रों में काम करता है। यदि यह गायब है, तो आप Array से NodeList में .forEach () जोड़ने के लिए एक पॉलीफ़िल का उपयोग कर सकते हैं और यह काम करता है:

if ( ! NodeList.prototype.forEach ) {
  NodeList.prototype.forEach = Array.prototype.forEach;
}

अब आप चला सकते हैं:

myNodeList.forEach(function(node){...})

Arrays की तरह NodeLists पर पुनरावृति करने के लिए।

यह हर जगह .call () की तुलना में बहुत छोटा और क्लीनर कोड पैदा करता है।


1
यह जवाब वास्तव में मुझे क्या चाहिए था और इन 3 लाइनों ने बहुत समय बचाया। अन्य सभी उत्तरों में कोड का एक गुच्छा बदलने की आवश्यकता होती है और मुझे समझ नहीं आ रहा है कि क्यों।
स्क्रिप्बलमैकर

डाउनवोट्स संभवत: इसलिए थे क्योंकि बंदर निर्मित
अंतर्वस्त्रों को

@DuBistKomisch यह एक पॉलीफ़िल है, केवल तभी लागू किया जाता है यदि मानक NodeList.foreach () मौजूद नहीं है।
मिकमेकाना

2
आह मेरा बुरा, एहसास नहीं था कि वे वास्तव में forEachविशेष रूप से जोड़ा गया है , मैं यहाँ आया थाfilter
DuBistKomisch

@DuBistKomisch आप के लिए एक ही तकनीक का उपयोग कर सकते हैं filter, लेकिन आप इसे एक अनौपचारिक नाम NodeList.prototype.dbkFilterया समान देने की इच्छा कर सकते हैं यदि आप एक अलग कार्यान्वयन का उपयोग करके भविष्य के मानक के बारे में चिंतित हैं।
मिकमेकाना

9

क्या यह होना चाहिए forEach? आप forसूची पर पुनरावृति करने के लिए बस एक लूप का उपयोग कर सकते हैं :

for (var i = 0; i < elementList.length; i++) {
    doSomethingWith(elementlist.item(i));
}

1
सरल समाधान के साथ जाने के लिए +1 जो अनावश्यक सरणी रूपांतरण नहीं जोड़ता है। FYI करें, इसके बजाय elementList.item(i), आप बस उपयोग कर सकते हैं elementList[i]
5

4
व्यक्तिगत रूप से मुझे forEach()एक बेहतर प्रोग्रामिंग शैली और कम वर्बोज़ - ymmv
cc युवा

@ जवान: वास्तव में, मैं आपसे सहमत हूं। इस तरह के मामलों को छोड़कर, जहां मुझे रूपांतरण चलाने की आवश्यकता होगी, ताकि मैं अपने पसंदीदा पैटर्न का उपयोग कर सकूं। यह उसे भद्दा बनाता है और ऐसा दिखता है: "जब आपके पास एक हथौड़ा होता है, तो सब कुछ नाखून की तरह दिखाई देने लगता है।"
nfechner

और यहाँ एक पौष्टिक तरीका है :) for (var oElement, i = 0; oElement = aMenuItemsElements; i++ { console.log(oElement); }
डैनियल सोकोलोव्स्की

यहाँ समस्या यह है कि आप किसी अन्य for (var i…)लूप को घोंसला नहीं बना सकते हैं क्योंकि लूप के लिए अपना दायरा नहीं बनता है (जैसे यह अब C / C ++ में है)। और फिर iघुलमिल जाते हैं।
जेन्स

2

ES6 जैसे शांत तरीके की अनुमति देता है, var nodeArray = Array.from(nodeList)लेकिन मेरा पसंदीदा नया प्रसार ऑपरेटर है।

var nodeArray = Array(...nodeList);

एक सही समाधान! यह समाधान टाइपस्क्रिप्ट के लिए भी लागू होता है।
NIDS

मैं यह जोड़ना चाहूंगा कि यह केवल टाइपस्क्रिप्ट के साथ काम करता है जब तक आप ईएस 5 या उससे कम पर ट्रांसपाइल नहीं कर रहे हैं।
रुडी

2

मेरे साथ ES6 में काम किया

मान लेते हैं कि आपके पास इस तरह का नोडलिस्ट है

<ul>
  <li data-time="5:17">Flexbox video</li>
  <li data-time="8:22">Flexbox video</li>
  <li data-time="3:24">Redux video</li>
  <li data-time="5:17">Flexbox video</li>
  <li data-time="7:17">Flexbox video</li>
  <li data-time="4:17">Flexbox video</li>
  <li data-time="2:17">Redux video</li>
  <li data-time="7:17">Flexbox video</li>
  <li data-time="9:54">Flexbox video</li>
  <li data-time="5:53">Flexbox video</li>
  <li data-time="7:32">Flexbox video</li>
  <li data-time="2:47">Redux video</li>
  <li data-time="9:17">Flexbox video</li>

</ul>


const items = Array.from(document.querySelectorAll('[data-time]'));

console.log(items);

2

मैं निम्नलिखित का उपयोग करता हूं क्योंकि मुझे लगता है कि यह पढ़ना सबसे आसान है:

const elements = document.getElementsByClassName('element');
[...elements].forEach((element) => {
   // code
});


1

खैर, यह मेरे लिए भी काम करता है:

const elements = Object.values( document.querySelector(your selector here) )

Object.values()Arrayदी गई वस्तु के मूल्यों का प्रतिफल । NodeListवस्तु है, जैसा कि जेएस में सब कुछ है।

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values

लेकिन यह IE के साथ संगत नहीं है, इसलिए मुझे लगता Array.prototype.*array_method*.call(yourNodeList)है कि सबसे अच्छा विकल्प है। इससे आप किसी भी ऐरे विधि को अपने पर लागू कर सकते हैंNodeList


-1

मान लें कि नोड एक नोडलिस्ट है:

var elems = document.querySelectorAll('select option:checked');

तो यह एक सरणी में बदल दिया जा सकता है:

var values = [].map.call(elems, function(obj) {
  return obj.value;
});

संदर्भ: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map#Example:_using_map_generically_questSelectorAll

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.