2009-08-17 7 views
7

यदि मेरे पास HTML दस्तावेज़ में दो नोड्स हैं, तो मैं कैसे बता सकता हूं कि HTML दस्तावेज़ में एचओएम दस्तावेज़ों में एचटीएमएल दस्तावेज़ ऑर्डर में कौन सा पहला आता है?नोड्स से दस्तावेज़ ऑर्डर निर्धारित करें

उदाहरण के लिए,

function funstuff(a, b) { 
    //a and b can be any node in the DOM (text, element, etc) 
    if(b comes before a in document order) { 
     var t = b; b = a; a = t; 
    } 
    // process the nodes between a and b. I can handle this part 
    // when I know that a comes before b. 
} 

उत्तर

5

Resig to the rescue के लिए नहीं कहा:

// Compare Position - MIT Licensed, John Resig 
function comparePosition(a, b){ 
    return a.compareDocumentPosition ? 
    a.compareDocumentPosition(b) : 
    a.contains ? 
     (a != b && a.contains(b) && 16) + 
     (a != b && b.contains(a) && 8) + 
     (a.sourceIndex >= 0 && b.sourceIndex >= 0 ? 
      (a.sourceIndex < b.sourceIndex && 4) + 
      (a.sourceIndex > b.sourceIndex && 2) : 
      1) + 
     0 : 
     0; 
} 
+0

यह ध्यान दिया जाना चाहिए कि रेसिग की विधि केवल टेक्स्ट नोड्स पर नहीं, तत्व नोड्स पर काम करेगी। – Michael

+0

हाँ। टेक्स्ट नोड्स में .sourceIndex नहीं है और उनके पास नहीं है .contains()। – Michael

+0

&& उन सभी मामलों में कुछ भी नहीं करता है, क्योंकि आरएचएस हमेशा सत्य होता है। – gsnedders

1

बल्कि मुश्किल है, मैं व्यक्तिगत रूप से प्रत्येक पेड़ जब तक मैं एक आम ansester पाया itterate होगा, तो जाँच जो माता-पिता नोड (या वास्तविक नोड है कि कम होने पर) पहले firstChild के साथ शुरू आता है और भाई बहन के माध्यम से काम, कुछ की तरह:

function OrderCheck(node1, node2){ 

    var ar1 = [null, node1]; 
    var ar2 = [null, node2]; 

    for(var i = 1; ar1[i] != null; i++) 
     ar1[i+1]=ar1[i].parentNode; 
    for(var i = 1; ar2[i] != null; i++) 
     ar2[i+1]=ar2[i].parentNode; 
    ar1.reverse(); ar2.reverse(); // easier to work with. 
    i = 0; 
    while(ar1[i] === ar2[i]){ 
     if(ar1[i] === null) 
     return 0; 
     else 
     i++ 
    } 

    if(ar1[i] === null) 
     return 2; 
    if(ar2[i] === null) 
     return 1; 

    if(i != 0){ 
     var n = ar1[i-1].firstChild; 
     do{ 
     if(n === ar1[i]) 
      return 1; 
     if(n === ar2[i]) 
      return 2; 
     }while(n = n.nextSibling); 
    } 
     return -1;// Shouldn't happen. 
    } 

    var order = OrderCheck(document.body, document.body.previousSibling); 
    if(order == 1){ 
     // element 1 first 
    }else if(order == 2){ 
     // element 2 first 
    }else{ 
     // there was an error. 
    } 

मैं सिर्फ दो संभावित समस्याओं को ठीक करने की कोशिश में इस कोड को संपादित किया, मैं इस नए संपादित लेकिन परीक्षण नहीं किया है, इसलिए यदि कुछ टूट जाता है मैं फिर से कोशिश करना होगा । ("बग भी नहीं चलाता" स्टाइल बग को ठीक करने के लिए फिर से संपादित किया गया)।

+0

अच्छा जवाब है, लेकिन मैं यह विफल रहता है एक नोड लगता है दूसरे का पूर्वज है। आपको 'i' के लिए किसी भी सरणी की लंबाई से परे परीक्षण करने की आवश्यकता है। – Alohci

+0

यह एक बहुत ही रोचक विचार है, जिसकी मैंने सोचा था उससे कहीं अधिक कुशल। अगर मैं a.compareDocumentPosition परिभाषित नहीं किया गया है (यह एक डोम 3 विधि है) तो मैं इसे वापस गिरने के रूप में शामिल करने जा रहा हूं। धन्यवाद! – Michael

4

आप डोम समारोह compareDocumentPosition उपयोग कर सकते हैं जो दो नोड्स 'संबंधों के आधार पर अलग नंबरों वापस आ जाएगी:

DOCUMENT_POSITION_DISCONNECTED = 0x01; 
DOCUMENT_POSITION_PRECEDING = 0x02; 
DOCUMENT_POSITION_FOLLOWING = 0x04; 
DOCUMENT_POSITION_CONTAINS = 0x08; 
DOCUMENT_POSITION_CONTAINED_BY = 0x10; 

संभावित परिणाम के रूप में इन कोड के एक से अधिक की राशि हो सकता है जवाब एक बिटमास्क है, लेकिन मैं ऐसी परिस्थिति की कल्पना नहीं कर सकता जहां इन दोनों स्थितियों में एक ही समय में सत्य होगा। यह भी ध्यान रखें कि "कट" परिणाम नोड्स सृजन किया गया है के साथ उदाहरण के लिए वापस कर दी जाएगी लेकिन दस्तावेज़ पेड़ अभी तक

+0

ध्यान दें कि * तुलना करें दस्तावेज़ दस्तावेज़ * इंटरनेट एक्सप्लोरर के किसी भी संस्करण द्वारा समर्थित नहीं है, आईई 8 तक और इसमें शामिल है। – NickFitz

+0

मुझे लगता है कि पूर्ण समाधान स्क्रैग के कोड पर वापस आना होगा यदि इसे परिभाषित नहीं किया गया है। पारितोषिक के लिए धन्यवाद। – Michael

संबंधित मुद्दे