2012-02-18 14 views
6

C'è un modo per ottenere innerText solo dell'elemento superiore (e ignorare il testo interiore dell'elemento figlio)?C'è un modo per ottenere innerText solo dell'elemento superiore (e ignorare innerText dell'elemento figlio)?

Esempio:

<div> 
    top node text 
    <div> child node text </div> 
</div> 

come ottenere il "testo in alto nodo", ignorando "text nodo figlio"? La proprietà innerText del div superiore sembra restituire la concatenazione sia del testo interno che di quello superiore.

+1

Rimuovere prima i nodi figlio diretti non di testo? – Oded

+1

@Oded: non necessario. Basta scorrere i bambini e concatenare. Vai tranquillo. –

risposta

11

Basta scorrere i nodi figlio e concatenare i nodi di testo:

var el = document.getElementById("your_element_id"), 
    child = el.firstChild, 
    texts = []; 

while (child) { 
    if (child.nodeType == 3) { 
     texts.push(child.data); 
    } 
    child = child.nextSibling; 
} 

var text = texts.join(""); 
+1

+1 Molto meglio della clonazione di quello che potrebbe essere un bit molto grande dell'albero DOM, giusto per scartarne la maggior parte. L'unico miglioramento sarebbe 'text = []' all'inizio e quindi 'text.push (child.data)' per iterazione, e infine 'text = text.join ('')' alla fine per trasformare la matrice di pezzi in una stringa, che tende ad essere più veloce di concatenazioni ripetute a una corda sempre crescente. –

+0

@DanielEarwicker: l'ho preso in considerazione, ma penso che gli ultimi benchmark che ho visto suggeriscono che non è chiaro che migliora le prestazioni, quindi ho optato per la versione più semplice. Controllerò ora. –

+1

Bello. PS. 'data' è definito nell'interfaccia [' CharacterData'] (https://developer.mozilla.org/en/DOM/CharacterData), che è implementata da 'Text' (text node). –

3
  1. Clona l'elemento.
  2. Ciclo attraverso tutti i nodi figlio (indietro, per evitare conflitti):
    Se l'elemento ha un attributo tagName, allora è un elemento: Rimuovere il nodo.
  3. Utilizzare innerText per ottenere il contenuto testuale (con fallback su textContent, quando innerText non è supportato).

Codice:

var elem = document.getElementById('theelement'); 
elem = elem.cloneNode(true); 
for (var i=elem.childNodes.length-1; i>=0; i--) { 
    if (elem.childNodes[i].tagName) elem.removeChild(elem.childNodes[i]); 
} 
var innerText = elem['innerText' in elem ? 'innerText' : 'textContent']; 
+0

Wow, funziona come un incantesimo in tutti i browser. Francamente, non pensavo fosse possibile prima di postare la domanda :) ... grazie ... – ivymike

+2

Non c'è bisogno di clonare o mutare il DOM. Basta leggere il nodo del testo figli. Vedi la mia risposta. –

+2

@ivymike Il metodo di Tims è migliore. Suggerisco di accettare la sua risposta invece della mia. Funziona anche su tutti i browser (testato in IE6 +, Chrome 1+, Safari 5, Firefox 3+). –

0

Se non si vuole ignorare testo interno del elemento figlio, utilizzare il seguente function:

function getInnerText(el) { 
    var x = []; 
    var child = el.firstChild; 
    while (child) { 
     if (child.nodeType == 3) { 
      x.push(child.nodeValue); 
     } 
     else if (child.nodeType == 1) { 
      var ii = getInnerText(child); 
      if (ii.length > 0) x.push(ii); 
     } 
     child = child.nextSibling; 
    } 
    return x.join(" "); 
} 
+0

Mi manca qualcosa o è il contrario di quello che stanno chiedendo? – Tom

2

Funzionerà nel tuo esempio: document.getElementById("item").firstChild.nodeValue;

Nota: Tenete a mente che questo funzionerà se si sa che si tratta di quella specifica HTML. Se il codice HTML può cambiare, ad esempio: il codice

<div> 
    <div class="item"> child node text </div> 
    top node text 
</div> 

quindi si dovrebbe utilizzare la soluzione più generico @Tim Down


Qui sta lavorando frammento:

window.onload = function() { 
 
    var text = document.getElementById("item").firstChild.nodeValue; 
 
    document.getElementById("result").innerText = text.trim(); 
 
};
#result { 
 
    border: 1px solid red; 
 
}
<div id="item"> 
 
    top node text 
 
    <div> child node text </div> 
 
</div> 
 

 

 

 
<strong>Result:</strong> <div id="result"></div>

Problemi correlati