2010-03-28 20 views
6

मेरी वर्तमान परियोजना में एक प्रदत्त चयनकर्ता के आधार पर किसी तत्व और उसके सभी वंशजों से टेक्स्ट सामग्री एकत्र करना शामिल है।जावास्क्रिप्ट: स्क्रिप्ट को अनदेखा करते हुए, किसी तत्व के सभी वंशजों से टेक्स्ट कैसे प्राप्त करें?

उदाहरण के लिए, जब चयनकर्ता #content आपूर्ति और इस HTML के खिलाफ चलाए:

<div id="content"> 
    <p>This is some text.</p> 
    <script type="text/javascript"> 
    var test = true; 
    </script> 
    <p>This is some more text.</p> 
</div> 

मेरी स्क्रिप्ट (एक छोटे से खाली स्थान के सफाई के बाद) वापसी होगी:

यह कुछ पाठ है। var test = true; यह कुछ और पाठ है।

हालांकि, मुझे <script> तत्वों के भीतर होने वाले टेक्स्ट नोड्स को अवहेलना करने की आवश्यकता है।

यह मेरे वर्तमान कोड (तकनीकी रूप से, यह एक या अधिक प्रदान की चयनकर्ताओं के आधार पर मैच) का एक अंश है:

// get text content of all matching elements 
for (x = 0; x < selectors.length; x++) { // 'selectors' is an array of CSS selectors from which to gather text content 
    matches = Sizzle(selectors[x], document); 
    for (y = 0; y < matches.length; y++) { 
    match = matches[y]; 
    if (match.innerText) { // IE 
     content += match.innerText + ' '; 
    } else if (match.textContent) { // other browsers 
     content += match.textContent + ' '; 
    } 
    } 
} 

यह थोड़ा ज्यादा में कि यह सिर्फ तत्व के भीतर सभी पाठ नोड्स रिटर्न साधारण (है और इसके वंशज) जो प्रदत्त चयनकर्ता से मेल खाते हैं। जिस समाधान को मैं ढूंढ रहा हूं वह <script> तत्वों के भीतर आने वाले सभी टेक्स्ट नोड्स को वापस कर देगा। इसे विशेष रूप से उच्च प्रदर्शन करने की आवश्यकता नहीं है, लेकिन मुझे अंततः क्रॉस-ब्राउज़र संगत होने की आवश्यकता है।

मुझे लगता है कि मुझे तत्व के सभी बच्चों के माध्यम से किसी भी तरह से लूप की आवश्यकता होगी जो चयनकर्ता से मेल खाता है और <script> तत्वों के अलावा सभी टेक्स्ट नोड्स को जमा करता है; ऐसा लगता है कि जावास्क्रिप्ट को पहचानने का कोई तरीका नहीं है जब यह पहले से ही सभी टेक्स्ट नोड्स से संचित स्ट्रिंग में घुमाया गया है।

मैं jQuery (प्रदर्शन/बैंडविड्थ कारणों के लिए) का उपयोग नहीं कर सकता, हालांकि आपने देखा होगा कि मैं अपने सिज़ल चयनकर्ता इंजन का उपयोग करता हूं, इसलिए jQuery का चयनकर्ता तर्क उपलब्ध है।

किसी भी मदद के लिए अग्रिम धन्यवाद!

उत्तर

8
function getTextContentExceptScript(element) { 
    var text= []; 
    for (var i= 0, n= element.childNodes.length; i<n; i++) { 
     var child= element.childNodes[i]; 
     if (child.nodeType===1 && child.tagName.toLowerCase()!=='script') 
      text.push(getTextContentExceptScript(child)); 
     else if (child.nodeType===3) 
      text.push(child.data); 
    } 
    return text.join(''); 
} 

या, यदि आप <script> तत्वों (जो आमतौर पर ध्यान देने योग्य दुष्प्रभाव नहीं होता है) को हटाने के लिए डोम को बदल सकते हैं, तेज:

var scripts= element.getElementsByTagName('script'); 
while (scripts.length!==0) 
    scripts[0].parentNode.removeChild(scripts[0]); 
return 'textContent' in element? element.textContent : element.innerText; 
+0

बहुत बढ़िया, धन्यवाद, बॉबन्स! मैं पहले दृष्टिकोण के साथ गया - आप शायद सही हैं कि '

2

संपादित:

खैर पहले मुझे कहते हैं कि im भी अपने एकाकी पर कड़ाके की धूप के साथ familar नहीं करते हैं, सिर्फ पुस्तकालयों का उपयोग यह ... जैसा कि कहा गया भीतर ..

अगर मैं यह करने के लिए किया था मैं कुछ ऐसा करूंगा:

var selectors = new Array('#main-content', '#side-bar'); 
function findText(selectors) { 
    var rText = ''; 
    sNodes = typeof selectors = 'array' ? $(selectors.join(',')) : $(selectors); 
    for(var i = 0; i < sNodes.length; i++) { 
     var nodes = $(':not(script)', sNodes[i]); 
     for(var j=0; j < nodes.length; j++) { 
     if(nodes[j].nodeType != 1 && node[j].childNodes.length) { 
      /* recursion - this would work in jQ not sure if 
       * Sizzle takes a node as a selector you may need 
       * to tweak. 
       */ 
      rText += findText(node[j]); 
     } 
     } 
    } 

    return rText; 
} 

मैंने इनमें से किसी का परीक्षण नहीं किया लेकिन आपको यह विचार देना चाहिए। उम्मीद है कि अधिक दिशा के साथ किसी और इच्छा पाइप ऊपर :-)


नहीं कर सकते तो आप सिर्फ माता पिता नोड हड़पने और अपने पाश में nodeName जाँच ... की तरह:

if(match.parentNode.nodeName.toLowerCase() != 'script' && match.nodeName.toLowerCase() != 'script') { 
    match = matches[y]; 
    if (match.innerText) { // IE 
     content += match.innerText + ' '; 
    } else if (match.textContent) { // other browsers 
     content += match.textContent + ' '; 
    } 
} 

jQuery बिल्कुल not() का समर्थन करता है चयनकर्ताओं में वाक्यविन्यास तो क्या आप बस $(':not(script)') कर सकते हैं?

+0

धन्यवाद prodigitalson - मैं नहीं यकीन हालांकि यह मेरा लक्ष्य पूरा करेगा, हालांकि। हो सकता है कि मैं अपने कोड उदाहरण में थोड़ा अस्पष्ट हो गया हो (बस इसे संपादित किया गया हो) - यह क्या करता है सीएसएस चयनकर्ताओं की एक सरणी को पार करता है, और प्रत्येक जो डोम नोड से मेल खाता है, यह केवल आंतरिक टेक्स्ट (आईई) या टेक्स्ट सामग्री (अन्य) उस नोड की संपत्ति। यह वास्तव में तत्वों के बच्चों के माध्यम से लूप नहीं करता है। हालांकि, मुझे लगता है कि उत्तरार्द्ध संभवतः ऐसा करने का सबसे अच्छा तरीका है - मिलान किए गए तत्व के सभी वंशजों के माध्यम से लूप,