बच्चे को नोड्स प्राप्त करने का सबसे अच्छा तरीका


233

मैं सोच रहा था, जावास्क्रिप्ट किसी भी तत्व से पहला बाल तत्व प्राप्त करने के लिए कई तरह के तरीके प्रदान करता है, लेकिन सबसे अच्छा कौन सा है? सबसे अच्छा, मेरा मतलब है: सबसे क्रॉस-ब्राउज़र संगत, सबसे तेज़, सबसे व्यापक और पूर्वानुमान जब यह व्यवहार की बात आती है। एलियासेस के रूप में उपयोग की जाने वाली विधियों / गुणों की सूची:

var elem = document.getElementById('container');
var child = elem.children[0];
var child = elem.firstElementChild; // == children[0]

यह दोनों मामलों के लिए काम करता है:

var child = elem.childNodes[0]; // or childNodes[1], see below

यह रूपों, या <div>पुनरावृत्ति के मामले में है । अगर मैं पाठ तत्वों का सामना कर सकता हूं:

var child = elem.childNodes; // treat as NodeList
var child = elem.firstChild;

जहाँ तक मैं बाहर काम कर सकते हैं, firstChildसे NodeList का उपयोग करता है childNodes, और firstElementChildउपयोग करता है children। मैं एमडीएन संदर्भ पर इस धारणा को आधार बना रहा हूं:

childNodeतत्व नोड के पहले बाल तत्व का संदर्भ है, या nullयदि कोई नहीं है।

मैं अनुमान लगा रहा हूं कि, गति के मामले में, अंतर, यदि कोई हो, तो कुछ भी नहीं होगा, क्योंकि firstElementChildप्रभावी रूप से एक संदर्भ है children[0], और childrenवस्तु पहले से ही स्मृति में है।

जो मुझे फेंक देता है, वह childNodesवस्तु है। मैंने इसका उपयोग तालिका तत्व में एक रूप को देखने के लिए किया है। childrenसभी फ़ॉर्म तत्वों को सूचीबद्ध करते समय , childNodesHTML कोड से व्हॉट्सएप को शामिल करना भी संभव है:

console.log(elem.childNodes[0]);
console.log(elem.firstChild);

दोनों लॉग करते हैं <TextNode textContent="\n ">

console.log(elem.childNodes[1]);
console.log(elem.children[0]);
console.log(elem.firstElementChild);

सभी लॉग <input type="text">। कैसे? मुझे लगता है कि एक वस्तु मुझे "कच्चे" HTML कोड के साथ काम करने की अनुमति देगी, जबकि दूसरा DOM से चिपक जाता है, लेकिन childNodesतत्व दोनों स्तरों पर काम करने लगता है।

अपने प्रारंभिक प्रश्न पर वापस जाने के लिए, मेरा अनुमान होगा: यदि मैं सबसे व्यापक वस्तु चाहता हूं, childNodesतो जाने का रास्ता है, लेकिन इसकी व्यापकता के कारण, यह उस तत्व को वापस करने के संदर्भ में सबसे अधिक अनुमानित नहीं हो सकता है जो मैं चाहता हूं / किसी भी समय उम्मीद करें। क्रॉस-ब्राउज़र समर्थन भी उस मामले में एक चुनौती साबित हो सकता है, हालांकि मैं गलत हो सकता हूं।

क्या कोई भी वस्तुओं के बीच अंतर को स्पष्ट कर सकता है? यदि कोई गति अंतर है, लेकिन नगण्य है, तो मैं भी जानना चाहूंगा। अगर मुझे यह सब गलत लग रहा है, तो मुझे शिक्षित करने के लिए स्वतंत्र महसूस करें।


पुनश्च: कृपया, मुझे जावास्क्रिप्ट पसंद है, इसलिए हां, मैं इस तरह की चीज से निपटना चाहता हूं। "आपके लिए jQuery के सौदे" जैसे उत्तर वह नहीं हैं जो मैं खोज रहा हूं, इसलिए नहीं टैग।


49
>> कृपया, कृपया, मुझे जावास्क्रिप्ट पसंद है, हां, मैं इस तरह की चीज से निपटना चाहता हूं। 'तुम्हारे लिए इस के साथ jQuery के सौदों' जैसे जवाब नहीं हैं जो मैं देख रहा हूँ << इसके लिए upvotes
david.barkhuizen

जवाबों:


211

लगता है जैसे आप इसे उखाड़ फेंक रहे हैं। आप के बीच का अंतर देखा होगा childNodesऔर childrenहै, जो कि childNodesखाली स्थान के की पूरी तरह से मिलकर पाठ नोड्स सहित सभी नोड्स, शामिल हैं, जबकि childrenसिर्फ बच्चे नोड्स तत्व हैं का एक संग्रह है। वास्तव में यही सब कुछ है।

संग्रह के बारे में अप्रत्याशित कुछ भी नहीं है, हालांकि जागरूक होने के लिए कुछ मुद्दे हैं:

  • IE <= 8 में सफेद स्थान-केवल पाठ नोड्स शामिल नहीं हैं, childNodesजबकि अन्य ब्राउज़र करते हैं
  • IE <= 8 में टिप्पणी नोड्स शामिल हैं childrenजबकि अन्य ब्राउज़रों में केवल तत्व हैं

children, firstElementChildऔर दोस्त सिर्फ उपयुक्तता हैं, डोम के फ़िल्टर किए गए दृश्य को केवल तत्वों तक ही सीमित रखते हैं।


अधिक से अधिक, हालांकि एक बात अभी भी मुझे परेशान करती है: व्हॉट्सएप टेक्स्टनॉड जो कि चाइल्डकोड पिक करता है, वास्तव में कोड में एक नई लाइन और टैब का एक जोड़ा है। क्या यह XHTML सिद्धांत के कारण है? क्या यह टैग के भीतर व्हाट्सएप को स्ट्रक्चर कोड में संलग्न करके हल किया जा सकता है?
एलियास वान ओटगेम

@EliasVanOotegem: यह सिद्धांत से असंबंधित है। व्हाइट स्पेस टेक्स्ट नोड्स हमेशा HTML और XHTML दोनों के लिए DOM (IE <9 को छोड़कर) में शामिल किए जाते हैं, जहां भी वे स्रोत में दिखाई देते हैं। यह आम तौर पर एक अच्छी बात है, हालांकि अगर आप इसके लिए तैयार नहीं हैं तो यह आपको पकड़ सकता है।
टिम डाउन

मेरा मतलब था अगर यह इस तरह से मेरे मार्कअप को लिखने में मदद करेगा <td\n\t>content</td>। जैसा कि आप XML के साथ कर सकते हैं, अतिरिक्त व्हाट्सएप को डेटा (या DOM, इस मामले में) के हिस्से के रूप में माना जा सकता है। एक टैग के अंदर व्हॉट्सएप को डोम में क्यों शामिल किया जाएगा?
एलियास वान ओटगेम

@EliasVanOotegem: ओह, मैं देख रहा हूं। टैग के अंदर टैग नाम के बाद सफेद स्थान को नजरअंदाज कर दिया जाता है, इसलिए आप इस तरह का काम कर सकते हैं। मैंने देखा है कि कुछ प्रकार के तत्वों के बीच सफेद स्थान के लिए छोटे अंतराल को जोड़ने वाले ब्राउज़र को रोकने के लिए सटीक लेआउट में उपयोग की जाने वाली तकनीक।
टिम डाउन

2
@ कृतिफे: आह, निष्पक्ष बिंदु, धन्यवाद। मैं अपने उत्तर में एक नोट जोड़ूंगा। यह देखते हुए कि childrenमानक बनने से पहले एक दशक में IE 4 में उत्पन्न हुआ या अन्य ब्राउज़रों द्वारा अपनाया गया, आप तर्क दे सकते हैं कि IE <= 8 सही है और अन्य ब्राउज़र गलत हैं।
टिम डाउन

23

IEE 9 (केवल firstChild) में firstElementChild उपलब्ध नहीं हो सकता है

IE <9 पर FirstChild फर्स्टलीचाइल्ड है क्योंकि MS DOM (IE <9) खाली टेक्स्ट नोड्स को स्टोर नहीं कर रहा है। लेकिन अगर आप अन्य ब्राउज़रों पर ऐसा करते हैं तो वे खाली पाठ नोड लौटा देंगे ...

मेरा समाधान

child=(elem.firstElementChild||elem.firstChild)

यह IE <9 पर भी फर्स्टचाइल्ड देगा


यदि elem.firstChildकोई तत्व नोड नहीं है, तो परिणाम पुराने IEs में भिन्न होंगे, क्योंकि elem.firstElementChildहमेशा तत्व नोड है।
duri

मुझे क्षमा करें, लेकिन मुझे पता है कि सभी प्रमुख ब्राउज़रों में पहला बच्चा कैसे प्राप्त करें। मैं जानना चाहता हूं कि विभिन्न वस्तुओं को कैसे संरचित किया जाता है, ताकि उनके बीच समानता और अंतर की बेहतर समझ मिल सके। मैं अपने प्रश्न को बाद में स्पष्ट करने के लिए संपादित करूँगा,
मिक्सअप के

1
firstElementChildगैर-IE ब्राउज़रों में आवश्यक रूप से सुरक्षित नहीं है: फ़ायरफ़ॉक्स ने केवल संस्करण 3.5 में इसका समर्थन करना शुरू किया।
टिम डाउन

यह क्रोम, IE9 और IE8 के लिए काम कर रहा है, क्योंकि अगर उनके पास पहला क्लीयरचिल्ड है, तो दूसरे चेक को निष्पादित नहीं किया जाता है, अन्यथा (पुराना IE) हमारे पास पहला चाइल्डहिल है, और यह ब्राउज़र के लिए एक तत्व नोड है जो पहले ई-मेल नहीं है (IE <9) ) ... फिर भी मुझे आश्चर्य है कि एफएफ के बारे में
नेउ-राह

1
टिम सही है, जब मैं इन वस्तुओं पर सामान ले जा रहा था, इससे पता चला कि अच्छी साइट एक बार में जांचने के लिए है
एलियास वान ओओटगेम

20

क्रॉस ब्राउज़र का तरीका यह है कि childNodesपाने के लिए उपयोग करें NodeList, फिर nodeType ELEMENT_NODE के साथ सभी नोड्स की एक सरणी बनाएं ।

/**
 * Return direct children elements.
 *
 * @param {HTMLElement}
 * @return {Array}
 */
function elementChildren (element) {
    var childNodes = element.childNodes,
        children = [],
        i = childNodes.length;

    while (i--) {
        if (childNodes[i].nodeType == 1) {
            children.unshift(childNodes[i]);
        }
    }

    return children;
}

http://jsfiddle.net/s4kxnahu/

यह विशेष रूप से आसान है यदि आप एक उपयोगिता पुस्तकालय का उपयोग कर रहे हैं जैसे कि लॉश :

/**
 * Return direct children elements.
 *
 * @param {HTMLElement}
 * @return {Array}
 */
function elementChildren (element) {
    return _.where(element.childNodes, {nodeType: 1});
}

भविष्य:

आप छद्म वर्ग के querySelectorAllसाथ संयोजन में उपयोग कर सकते हैं :scope(उस तत्व से मेल खाता है जो चयनकर्ता का संदर्भ बिंदु है):

parentElement.querySelectorAll(':scope > *');

लिखने के समय यह क्रोम, फ़ायरफ़ॉक्स और सफारी में :scopeसमर्थित है।


: स्कोप को स्कोप से हटा दिया गया । क्या हमें फ्यूचर सेक्शन को हटाना चाहिए ?
थॉमस मार्टी

4

बस अन्य उत्तरों को जोड़ने के लिए, यहां अभी भी उल्लेखनीय अंतर हैं, खासकर जब <svg>तत्वों से निपटते हैं।

मैंने दोनों का उपयोग किया है .childNodesऔर गेटटर द्वारा वितरित के .childrenसाथ काम करना पसंद HTMLCollectionकिया है .children

आज हालांकि, मैं IE / एज के साथ मुद्दों में भाग गया जब .childrenएक पर उपयोग विफल रहा <svg>। जबकि .childrenमूल HTML तत्वों पर IE में समर्थित है, यह दस्तावेज़ / दस्तावेज़ टुकड़े, या SVG तत्वों पर समर्थित नहीं है

मेरे लिए, मैं केवल आवश्यक तत्वों को हथियाने में सक्षम था .childNodes[n]क्योंकि मुझे चिंता करने के लिए बाहरी पाठ नोड्स नहीं हैं। आप ऐसा करने में सक्षम हो सकते हैं, लेकिन जैसा कि ऊपर कहीं और उल्लेख किया गया है, यह मत भूलिए कि आप अप्रत्याशित तत्वों में भाग सकते हैं।

आशा है कि यह किसी को उनके सिर को खरोंच करने में मददगार है जो यह जानने की कोशिश कर रहा है कि .childrenआधुनिक IE पर उनके जेएस में कहीं और काम क्यों नहीं होता है और दस्तावेज़ या एसवीएफ तत्वों पर विफल रहता है।


3

अरे दोस्तों आप सफेद जगह को मूर्ख मत बनने दो। बस इसे कंसोल ब्राउजर में टेस्ट करें। देशी जावास्क्रिप्ट का उपयोग करें। यहाँ और उदाहरण एक ही वर्ग के साथ दो 'उल' सेट के साथ है। आपको सफेद स्थान से बचने के लिए अपनी 'उल' सूची को एक पंक्ति में रखने की आवश्यकता नहीं है, बस सफेद सरणी पर कूदने के लिए अपनी सरणी गणना का उपयोग करें।

श्वेत स्थान कैसे प्राप्त करें, querySelector()इसके बाद childNodes[]js fiddle लिंक: https://jsfiddle.net/aparadise/56njekdo/

var y = document.querySelector('.list');
var myNode = y.childNodes[11].style.backgroundColor='red';

<ul class="list">
    <li>8</li>
    <li>9</li>
    <li>100</li>
</ul>

<ul class="list">
    <li>ABC</li>
    <li>DEF</li>
    <li>XYZ</li>
</ul>

मेरा डाउन-वोट नहीं है, लेकिन मुझे लगता है कि किसी ने डाउन-वोट किया क्योंकि: ए) यह सवाल 4 साल पुराना है, document.querySelectorफिर वापस अच्छी तरह से समर्थित नहीं था। b) प्रश्न मूल रूप से पूछ रहा है कि अंतर क्या है childrenऔर childNodes आंतरिक रूप से , जो अधिक विश्वसनीय है, जब एक दूसरे को चुनना है। और ग) क्योंकि, जैसा कि इस सवाल में दर्शाया गया है: childNodes इसमेंchildren
व्हॉट्सएप
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.