जावास्क्रिप्ट में जांच कैसे करें यदि एक तत्व दूसरे के भीतर समाहित है


201

अगर मैं एक DOM तत्व दूसरे DOM एलिमेंट का बच्चा हूं, तो मैं कैसे जांच सकता हूं? क्या इसके लिए कोई विधियां निर्मित हैं? उदाहरण के लिए, कुछ इस तरह:

if (element1.hasDescendant(element2)) 

या

if (element2.hasParent(element1)) 

यदि नहीं, तो किसी भी विचार को यह कैसे करना है? इसके लिए क्रॉस ब्राउजर होना भी जरूरी है। मुझे यह भी उल्लेख करना चाहिए कि बच्चे को माता-पिता के नीचे कई स्तरों पर नेस्ट किया जा सकता है।


3
आपको
बजे

मेरा मानना ​​है कि जेएस आजकल एक "लाइव मानक" के रूप में स्वीकार किए जाते हैं, उत्तर को स्वीकार किए जाने वाले उत्तर के रूप में "कॉनटिन्स" विधि के लिए फिर से जांचा जाना चाहिए।
डेविडटुबमैन

जवाबों:


219

अद्यतन: अब इसे प्राप्त करने का एक मूल तरीका है। Node.contains()। टिप्पणी में और नीचे दिए गए जवाबों का उल्लेख किया।

पुराना उत्तर:

parentNodeसंपत्ति का उपयोग करके काम करना चाहिए। यह क्रॉस-ब्राउज़र के दृष्टिकोण से भी बहुत सुरक्षित है। अगर रिश्ते को एक स्तर गहरा होने के लिए जाना जाता है, तो आप इसे बस जाँच सकते हैं:

if (element2.parentNode == element1) { ... }

यदि बच्चे को माता-पिता के अंदर मनमाने ढंग से गहरा घोंसला दिया जा सकता है, तो आप रिश्ते के लिए परीक्षण करने के लिए निम्न के समान फ़ंक्शन का उपयोग कर सकते हैं:

function isDescendant(parent, child) {
     var node = child.parentNode;
     while (node != null) {
         if (node == parent) {
             return true;
         }
         node = node.parentNode;
     }
     return false;
}

आपके उत्तर के लिए धन्यवाद, समस्या यह है कि बच्चे को माता-पिता के कई स्तरों से वंचित किया जा सकता है।
ए जे।

@AJ: मैंने अपने उत्तर को एक समाधान में शामिल करने के लिए अद्यतन किया, जो कि माता-पिता के मनमाने ढंग से बच्चे के घोंसले के लिए काम करना चाहिए।
असफ

228
अगर अब कोई भी इस पर आ रहा है तो आपके लिए Node.contains ( developer.mozilla.org/en-US/docs/DOM/Node.contains ) का उपयोग करना संभव हो सकता है, जो आधुनिक ब्राउज़रों में एक मूल कार्य है।
एडम हीथ

2
@JohnCarrell Node.contains(हालांकि कोई कैनियूज़ पृष्ठ नहीं है)
gcampbell

3
@ क्या आप नया शामिल करने के लिए अपना जवाब अपडेट कर सकते हैं Node.contains? :)

355

आपको इसका उपयोग करना चाहिए Node.contains, क्योंकि यह अब मानक है और सभी ब्राउज़रों में उपलब्ध है।

https://developer.mozilla.org/en-US/docs/Web/API/Node.contains


Node.hasParent (मूल) विधि अनावश्यक है, लेकिन Node.prototype.hasParent = function (तत्व) {return element.contains (यह);};
llange

6
क्या यह मोबाइल ब्राउज़र में भी समर्थित है? Mdn डॉक्स में एंड्रॉइड, सफारी, IE और ओपेरा के लिए प्रश्न चिह्न हैं।
thetallweeks

1
@thetallweeks - मेरे Android 7 पर कम से कम काम करता है।
स्फिंक्सएक्स

5
आप कम से कम एक उदाहरण जोड़ सकते हैं
Nino ackopac

2
यह अच्छा उत्तर है, लेकिन उदाहरण वास्तविक अच्छा होगा:var parent = document.getElementById('menu'); var allElements = document.getElementsByTagName('a'); if (parent.contains(allElements[i]) { alert('Link is inside meni'); }
baron_bartek

45

मुझे सिर्फ 'मेरा ’साझा करना था।

यद्यपि वैचारिक रूप से असफ के उत्तर (समान क्रॉस-ब्राउज़र संगतता, यहां तक ​​कि IE6 से लाभ) के समान है, यह बहुत छोटा है और यह तब काम आता है जब आकार प्रीमियम पर होता है और / या जब इसकी इतनी बार आवश्यकता नहीं होती है।

function childOf(/*child node*/c, /*parent node*/p){ //returns boolean
  while((c=c.parentNode)&&c!==p); 
  return !!c; 
}

.. एक लाइनर के रूप में ( सिर्फ 64 वर्ण !):

function childOf(c,p){while((c=c.parentNode)&&c!==p);return !!c}

और यहाँ jsfiddle


उपयोग:
childOf(child, parent) रिटर्न बूलियनtrue| false

स्पष्टीकरण:
while जब तक स्थिति का मूल्यांकन करता है, तब तक मूल्यांकन करता हैtrue। (और) ऑपरेटर रिटर्न इस बूलियन सही / गलत के बाद बाएं ओर और दाएँ हाथ की ओर का मूल्यांकन है, लेकिन केवल अगर बाएं ओर सच था ( )
&&left-hand && right-hand

बाएं हाथ की ओर (की &&) है (c=c.parentNode):।
यह पहली आवंटित करेगा parentNodeके cलिए cऔर उसके बाद AND ऑपरेटर जिसके परिणामस्वरूप का मूल्यांकन करेंगे cएक बूलियन के रूप में।
चूंकि parentNodeरिटर्न nullतब होता है जब कोई अभिभावक नहीं बचा होता है और nullउसे परिवर्तित कर दिया जाता है false, जबकि अधिक माता-पिता नहीं होने पर लूप सही ढंग से बंद हो जाएगा।

(के दाएँ हाथ की ओर &&) है: c!==p। तुलना ऑपरेटर है ' नहीं बिल्कुल के बराबर'। तो अगर बच्चे के माता पिता माता पिता (आपके द्वारा निर्दिष्ट) यह करने के लिए मूल्यांकन करता है नहीं है , लेकिन अगर बच्चे के माता पिता है माता-पिता तो यह करने के लिए मूल्यांकन करता है । इसलिए यदि झूठ का मूल्यांकन किया जाता है, तो ऑपरेटर समय की स्थिति के रूप में लौटता है और समय-पाश रुक जाता है। (ध्यान दें कि थोड़ी देर के लिए शरीर की जरूरत नहीं है और समापन अर्धविराम की आवश्यकता है।)
!==truefalse
c!==p&&false;

इसलिए जब लूप समाप्त हो जाता है, cतो या तो एक नोड (नहीं null) होता है जब यह एक माता-पिता को मिला या यह nullतब होता है (जब लूप एक मैच खोजने के बिना अंत तक चला गया)।

इस प्रकार हम बस returnउस तथ्य (नोड के बजाय, बूलियन मान के रूप में परिवर्तित) के साथ: return !!c;: !( NOTऑपरेटर) एक बूलियन मान (उलट trueहो जाता है falseऔर इसके विपरीत)। एक बूलियन में
!cधर्मान्तरित c(नोड या अशक्त) से पहले यह उस मूल्य को उल्टा कर सकता है। इसलिए एक दूसरा !( !!c) जोड़ना इस झूठी पीठ को सच में बदल देता है (यही वजह है कि डबल !!का इस्तेमाल अक्सर 'बूलियन में कुछ भी बदलने के लिए' किया जाता है)।


अतिरिक्त:
फ़ंक्शन का शरीर / पेलोड इतना छोटा है कि, मामले पर निर्भर करता है (जैसे कि जब इसका उपयोग अक्सर नहीं किया जाता है और कोड में बस एक बार दिखाई देता है), तो कोई भी फ़ंक्शन (रैपिंग) को छोड़ सकता है और बस लूप का उपयोग कर सकता है:

var a=document.getElementById('child'),
    b=document.getElementById('parent'),
    c;

c=a; while((c=c.parentNode)&&c!==b); //c=!!c;

if(!!c){ //`if(c)` if `c=!!c;` was used after while-loop above
    //do stuff
}

के बजाय:

var a=document.getElementById('child'),
    b=document.getElementById('parent'),
    c;

function childOf(c,p){while((c=c.parentNode)&&c!==p);return !!c}

c=childOf(a, b);    

if(c){ 
    //do stuff
}

4
@ सोलोमन्यूको: सख्त समानता तुलना ( !==) यह संकलक को स्पष्ट करके गति में सुधार कर सकती है कि यह टाइप-चेकिंग और वैकल्पिक अंतर्निहित रूपांतरण चरणों को छोड़ सकता है जो एक ढीली समानता तुलना में होगा, इस प्रकार गति में सुधार (अधिक सटीक रूप से हम क्या कर रहे हैं) ऐसा होना चाहते हैं, जो प्रोग्रामर के लिए भी फायदेमंद हो)। मुझे यह भी याद है कि जब मैंने यह लिखा था, तो यह था कि बस ढीली तुलना ( !=) या तो बहुत त्रुटि-प्रवण थी या कुछ पुराने ब्राउज़र में बिल्कुल भी काम नहीं करती थी (मुझे संदेह है कि यह IE6 में था, लेकिन मैं भूल गया हूं )।
गीतालाब

29

एक अन्य समाधान जिसका उल्लेख नहीं किया गया था:

यहाँ उदाहरण है

var parent = document.querySelector('.parent');

if (parent.querySelector('.child') !== null) {
    // .. it's a child
}

इससे कोई फर्क नहीं पड़ता कि तत्व एक सीधा बच्चा है, यह किसी भी गहराई पर काम करेगा।


वैकल्पिक रूप से, .contains()विधि का उपयोग कर :

यहाँ उदाहरण है

var parent = document.querySelector('.parent'),
    child = document.querySelector('.child');

if (parent.contains(child)) {
    // .. it's a child
}

19

Node # comparDocumentPosition पर एक नज़र डालें

function isDescendant(ancestor,descendant){
    return ancestor.compareDocumentPosition(descendant) & 
        Node.DOCUMENT_POSITION_CONTAINS;
}

function isAncestor(descendant,ancestor){
    return descendant.compareDocumentPosition(ancestor) & 
        Node.DOCUMENT_POSITION_CONTAINED_BY;
}

अन्य रिश्तों में शामिल हैं DOCUMENT_POSITION_DISCONNECTED, DOCUMENT_POSITION_PRECEDING, और DOCUMENT_POSITION_FOLLOWING

IE <= 8 में समर्थित नहीं है।


दिलचस्प! यह मुझे एक जेएस फ़ंक्शन की याद दिलाता है जिसे मैंने वर्ष 2003 में विकसित किया था ... मुझे कुछ दिन लिया और कुछ जेएस डेवलपर्स की मदद ली ... अविश्वसनीय (और दुखद) कि आजकल कोई पूर्ण ड्रैग-ड्रॉप नहीं है और न ही ऑब्जेक्ट-फिट पूर्ण ब्राउज़र कार्यान्वयन ।
डेविडटुबमैन

16

आप इसमें शामिल विधि का उपयोग कर सकते हैं

var result = parent.contains(child);

या आप उपयोग करने का प्रयास कर सकते हैं (compareDocumentPosition)

var result = nodeA.compareDocumentPosition(nodeB);

अंतिम एक अधिक शक्तिशाली है: यह परिणाम के रूप में एक बिटमास्क लौटाता है।


2

मुझे यह पता लगाने के लिए कि एक तत्व दूसरे तत्व का बच्चा है या नहीं, यह जानने के लिए एक अद्भुत कोड आया। मुझे इसका उपयोग करना है क्योंकि IE .containsतत्व विधि का समर्थन नहीं करता है । उम्मीद है कि इससे दूसरों को भी मदद मिलेगी।

नीचे समारोह है:

function isChildOf(childObject, containerObject) {
  var returnValue = false;
  var currentObject;

  if (typeof containerObject === 'string') {
    containerObject = document.getElementById(containerObject);
  }
  if (typeof childObject === 'string') {
    childObject = document.getElementById(childObject);
  }

  currentObject = childObject.parentNode;

  while (currentObject !== undefined) {
    if (currentObject === document.body) {
      break;
    }

    if (currentObject.id == containerObject.id) {
      returnValue = true;
      break;
    }

    // Move up the hierarchy
    currentObject = currentObject.parentNode;
  }

  return returnValue;
}

मैंने शाब्दिक रूप से इस पृष्ठ पर हर दूसरे पॉलीफ़िल की कोशिश की है। इसमें शामिल हैं, और यह एकमात्र ऐसा काम है। धन्यवाद!
प्रोटिओएन्जेलियन

1

इसको आजमाओ:

x = document.getElementById("td35");
if (x.childElementCount > 0) {
    x = document.getElementById("LastRow");
    x.style.display = "block";
}
else {
    x = document.getElementById("LastRow");
    x.style.display = "none";
}

-2

मैं हाल ही में इस समारोह में आया था जो कर सकता है:

Node.compareDocumentPosition ()


2
नीचा दिखाया गया क्योंकि केवल एक बाहरी लिंक की तुलना में अधिक जानकारी के साथ एक ही उत्तर पहले से ही कई बार मौजूद था।
स्टीफन फैबियन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.