2012-03-31 12 views
9

¿Cómo obtengo el texto de un elemento sin los elementos secundarios? Ni element.textContent ni element.innerText parecen estar funcionando.obtener el texto de un elemento sin elementos secundarios en javascript

HTML:

<body> 
<h1>Test Heading</h1> 
<div> 
Awesome video and music. Thumbs way up. Love it. Happy weekend to you and your family. Love, Sasha 
</div> 
</body> 
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script> 
<script type="text/javascript"> 
    fool("body"); 
</script> 

y aquí está la función fool:

jQuery.fn.justtext = function(text) { 
    return $(this).clone() 
    .children() 
    .remove() 
    .end() 
    .text(); 
}; 

function fool(el) { 

    reverse(el); 

    function reverse(el) { 
     $(el).children().each(function() { 
      if($(this).children().length > 0) { 
       reverse(this); 
       if($(this).justtext() != "") 
        reverseText(this); 
      } else { 
       reverseText(this) 
      } 
     }); 
    } 

    function reverseText(el){ 
     var text = el.textContent; 
     var frag = text.toString().split(/ /); 
     var foo = ""; 
     var punctation_marks = [".",",","?","!"," ",":",";"]; 
     for(i in frag){ 
      if(punctation_marks.indexOf(frag[i]) == -1) 
       foo += actualReverse(frag[i],punctation_marks) + " "; 
     } 
     el.textContent = foo; 
    } 

    function actualReverse(text,punctation_marks) { 
     return (punctation_marks.indexOf(text.split("")[text.split("").length-1]) != -1)?text.split("").slice(0,text.split("").length-1).reverse().join("") + text.split("")[text.split("").length-1] : text.split("").reverse().join(""); 
    } 
} 

edición: usando node.nodeType realmente no ayuda, y he aquí por qué: Imaginge el siguiente código HTML

<td class="gensmall"> 
    Last visit was: Sat Mar 31, 2012 10:50 am 
    <br> 
    <a href="./search.php?search_id=unanswered">View unanswered posts</a> | <a href="./search.php?search_id=active_topics">View active topics</a> 
</td> 

si que haría uso de nodeType, sólo el texto del elemento a cambiaría, pero no el td sí mismo ("última visita ....")

+0

PLZ publicar su html – Jigs

+0

Cualquier código? Probablemente su selector esté equivocado, 'element' no contiene ningún contenido cuando' .textContent' y 'innerText' están vacíos. –

+0

¿Qué quiere decir exactamente con "sin hijos"? – Pointy

Respuesta

14

Sólo tiene que encontrar los nodos de texto:

var element = document.getElementById('whatever'), text = ''; 
for (var i = 0; i < element.childNodes.length; ++i) 
    if (element.childNodes[i].nodeType === 3) 
    text += element.childNodes[i].textContent; 

edición — si desea el texto descendiente ("niños") nodos, y (como es ahora aparente) que está utilizando jQuery:

$.fn.allText = function() { 
    var text = ''; 
    this.each(function() { 
    $(this).contents().each(function() { 
     if (this.nodeType == Node.TEXT_NODE) 
     text += this.textContent; 
     else if (this.nodeType == Node.ELEMENT_NODE) 
     text += $(this).allText(); 
    }); 
    }); 
    return text; 
}; 

Espere y lo probaré :-) (parece que funciona)

+5

Sugiero usar 'Node.TEXT_NODE' en lugar de" 3 ", ya que es más legible. –

+1

también puede tener que recurse a través de nodos de texto para encontrar los nodos de texto que contienen. (Por ejemplo, celdas de la tabla) –

+0

@ David-SkyMesh: Ese es exactamente mi problema. Edité mi pregunta –

2

El texto de un elemento también es un nodo separado. Considere este pedazo de código:

<span> 
    Some text 
    <span>Inner text</span> 
    More text 
    <span>More inner text</span> 
    Even more text 
</span> 

¿Qué quiere decir cuando se dice ahora desea que el texto del elemento? ¿Solo los niños directos?

A continuación, este código de pieza de código puede ayudar a:

for (var element in elements) { 
    if (element.nodeType == Node.TEXT_NODE) { 
     // do something 
    } 
} 
4

Este código se obtiene el mismo resultado que las otras dos respuestas, pero de una manera más expresiva, funcional. Los métodos de matriz filter y map son compatibles con todos los navegadores modernos (IE9 y superiores).

Al tirar esto allí ya que las otras respuestas están un poco anticuadas por ahora.

var content = Array.prototype.filter.call(element.childNodes, function (element) { 
    return element.nodeType === Node.TEXT_NODE; 
}).map(function (element) { 
    return element.textContent; 
}).join(""); 
1

Además de respuestas como puntiagudo, manejo carácter de nueva línea de <br/> se puede hacer así:

txt = ''; 
for (var i = 0; i < element.childNodes.length; ++i) 
    if (element.childNodes[i].nodeType == 3) { 
     txt += element.childNodes[i].textContent; 
    } else if (element.childNodes[i].nodeType == 1) { 
     name = element.childNodes[i].nodeName || element.childNodes[i].tagName || ''; 
     if (name.toUpperCase() == 'BR') { 
      txt += '\n'; 
     } 
    } 
return txt; 
Cuestiones relacionadas