<div class="title">
I am text node
<a class="edit">Edit</a>
</div>
Deseo obtener el "Yo soy nodo de texto", no deseo eliminar la etiqueta "editar" y necesito una solución de navegador cruzado.
javascript
jquery
Val
fuente
fuente
Respuestas:
Esto obtiene el valor
contents
del elemento seleccionado y le aplica una función de filtro. La función de filtro devuelve solo nodos de texto (es decir, los nodos connodeType == Node.TEXT_NODE
).fuente
text()
porque lafilter
función devuelve los nodos en sí, no el contenido de los nodos.jQuery("*").each(function() { console.log(this.nodeType); })
y obtuve 1 para todos los tipos de nodos.Puede obtener el nodeValue del primer childNode usando
http://jsfiddle.net/TU4FB/
fuente
null
un valor de retorno.Si te refieres a obtener el valor del primer nodo de texto en el elemento, este código funcionará:
Puedes ver esto en acción aquí: http://jsfiddle.net/ZkjZJ/
fuente
curNode.nodeType == 3
lugar denodeName
también.curNode.nodeType == Node.TEXT_NODE
(la comparación numérica es más rápida pero curNode.nodeType == 3 no es legible, ¿qué nodo tiene el número 3?)curNode.NodeType === Node.TEXT_NODE
. Esta comparación ocurre dentro de un ciclo de posibles iteraciones desconocidas. Comparar dos números pequeños es mejor que comparar cadenas de varias longitudes (consideraciones de tiempo y espacio). La pregunta correcta para hacer en esta situación es "¿qué tipo / tipo de nodo tengo?", Y no "¿qué nombre tengo?" developer.mozilla.org/en-US/docs/Web/API/Node/nodeTypechildNodes
, sepa que un nodo de elemento puede tener más de un nodo de texto. En una solución genérica, es posible que deba especificar qué instancia de un nodo de texto dentro de un nodo de elemento desea apuntar (el primero, el segundo, el tercero, etc.).Otra solución JS nativa que puede ser útil para elementos "complejos" o profundamente anidados es usar NodeIterator . Póngalo
NodeFilter.SHOW_TEXT
como segundo argumento ("whatToShow") e itere solo sobre los nodos secundarios de texto del elemento.También puede utilizar
TreeWalker
. La diferencia entre los dos es queNodeIterator
es un iterador lineal simple, mientrasTreeWalker
que le permite navegar a través de hermanos y ancestros también.fuente
JavaScript puro: minimalista
En primer lugar, siempre tenga esto en cuenta cuando busque texto en el DOM.
MDN - Espacio en blanco en DOM
Este problema le hará prestar atención a la estructura de su XML / HTML.
En este ejemplo puro de JavaScript, considero la posibilidad de múltiples nodos de texto que podrían intercalar con otros tipos de nodos . Sin embargo, inicialmente, no juzgo los espacios en blanco, dejando esa tarea de filtrado a otro código.
En esta versión, paso una entrada
NodeList
desde el código de llamada / cliente.Por supuesto, al probar
node.hasChildNodes()
primero, no sería necesario utilizar unfor
ciclo de prueba previa .JavaScript puro: robusto
Aquí la función
getTextById()
usa dos funciones auxiliares:getStringsFromChildren()
yfilterWhitespaceLines()
.getStringsFromChildren ()
filterWhitespaceLines ()
getTextById ()
A continuación, el valor de retorno (Array o nulo) se envía al código del cliente donde debe manejarse. Con suerte, la matriz debe tener elementos de cadena de texto real, no líneas de espacios en blanco.
Las cadenas vacías (
""
) no se devuelven porque necesita un nodo de texto para indicar correctamente la presencia de texto válido. Devolver (""
) puede dar la falsa impresión de que existe un nodo de texto, lo que lleva a alguien a asumir que puede alterar el texto cambiando el valor de.nodeValue
. Esto es falso, porque un nodo de texto no existe en el caso de una cadena vacía.Ejemplo 1 :
Ejemplo 2 :
El problema surge cuando desea que su HTML sea fácil de leer al espaciarlo. Ahora, aunque no hay texto válido legible por humanos, todavía hay nodos de texto con caracteres de nueva línea (
"\n"
) en sus.nodeValue
propiedades.Los seres humanos ven los ejemplos uno y dos como funcionalmente equivalentes: elementos vacíos que esperan ser llenados. El DOM es diferente al razonamiento humano. Es por eso que la
getStringsFromChildren()
función debe determinar si existen nodos de texto y recopilar los.nodeValue
valores en una matriz.En el ejemplo dos, existen dos nodos de texto y
getStringFromChildren()
devolverán el.nodeValue
de ambos ("\n"
). Sin embargo,filterWhitespaceLines()
usa una expresión regular para filtrar líneas de caracteres de espacio en blanco puro.¿Devolver en
null
lugar de los"\n"
caracteres de nueva línea ( ) es una forma de mentir al cliente / código de llamada? En términos humanos, no. En términos de DOM, sí. Sin embargo, el problema aquí es obtener texto, no editarlo. No hay texto humano para volver al código de llamada.Nunca se puede saber cuántos caracteres de nueva línea pueden aparecer en el HTML de alguien. La creación de un contador que busque el "segundo" carácter de nueva línea no es confiable. Puede que no exista.
Por supuesto, más adelante en la línea, el problema de editar texto en un
<p></p>
elemento vacío con espacio en blanco adicional (ejemplo 2) podría significar destruir (tal vez, omitir) todos los nodos de texto excepto uno entre las etiquetas de un párrafo para garantizar que el elemento contenga exactamente lo que es. se supone que debe mostrar.Independientemente, excepto en los casos en los que esté haciendo algo extraordinario, necesitará una forma de determinar qué
.nodeValue
propiedad del nodo de texto tiene el texto verdadero y legible por humanos que desea editar.filterWhitespaceLines
nos lleva a la mitad del camino.En este punto, es posible que tenga una salida similar a esta:
No hay garantía de que estas dos cadenas sean adyacentes entre sí en el DOM, por lo que unirlas con
.join()
podría generar una composición antinatural. En cambio, en el código que llamagetTextById()
, debe elegir con qué cadena desea trabajar.Pruebe la salida.
Se podría agregar
.trim()
dentro degetStringsFromChildren()
para deshacerse de los espacios en blanco iniciales y finales (o para convertir un montón de espacios en una cadena de longitud cero (""
), pero ¿cómo puede saber a priori lo que cada aplicación necesita que le suceda al texto (cadena)? una vez que se encuentra? Usted no, así que déjelo a una implementación específica, ygetStringsFromChildren()
sea genérico.Puede haber ocasiones en las que este nivel de especificidad (el
target
y tal) no sea necesario. Eso es grandioso. Utilice una solución sencilla en esos casos. Sin embargo, un algoritmo generalizado le permite adaptarse a situaciones simples y complejas.fuente
Versión ES6 que devuelve el primer contenido del nodo #text
fuente
.from()
para crear una instancia de matriz con copia superficial. (2) El uso de.find()
para hacer comparaciones de cadenas usando.nodeName
. Usarnode.NodeType === Node.TEXT_NODE
sería mejor. (3) Devolver una cadena vacía cuando no hay valornull
, es más cierto si no se encuentra ningún nodo de texto . Si no se encuentra ningún nodo de texto, ¡es posible que deba crear uno! Si devuelve una cadena vacía,""
puede dar la falsa impresión de que existe un nodo de texto y se puede manipular normalmente. En esencia, devolver una cuerda vacía es una mentira piadosa y es mejor evitarla.[...node.childNodes]
para convertir HTMLCollection en matrices.text() - for jquery
fuente
a
elemento: jsfiddle.net/ekHJH.
al principio de su selector, lo que significa que en realidad obtiene el texto deltitle
elemento, no los elementos conclass="title"
.innerText
es una antigua convención de IE adoptada recientemente. En términos de secuencias de comandos DOM estándar,node.nodeValue
es cómo se toma el texto de un nodo de texto.Esto también ignorará los espacios en blanco, por lo que nunca obtuvo el código de TextNodes en blanco ... usando Javascript central.
Compruébelo en jsfiddle: - http://jsfiddle.net/webx/ZhLep/
fuente
curNode.nodeType === Node.TEXT_NODE
seria mejor. El uso de la comparación de cadenas y una expresión regular dentro de un bucle es una solución de bajo rendimiento, especialmente a medida queoDiv.childNodes.length
aumenta la magnitud . Este algoritmo resuelve la pregunta específica del OP, pero, potencialmente, a un costo de rendimiento terrible. Si cambia la disposición, o el número, de los nodos de texto, no se puede garantizar que esta solución devuelva resultados precisos. En otras palabras, no puede apuntar al nodo de texto exacto que desea. Estás a merced de la estructura HTML y la disposición del texto allí.También puede usar la
text()
prueba de nodo de XPath para obtener solo los nodos de texto. Por ejemplofuente
Esta es mi solución en ES6 para crear una cadena que contraiga el texto concatenado de todos los childnodes (recursivo) . Tenga en cuenta que también visite el shdowroot de childnodes.
Esta solución se inspiró en la solución de https://stackoverflow.com/a/41051238./1300775 .
fuente