<div class="title">
I am text node
<a class="edit">Edit</a>
</div>
Je souhaite obtenir le nœud "Je suis texte", je ne souhaite pas supprimer la balise "edit" et j'ai besoin d'une solution multi-navigateurs.
<div class="title">
I am text node
<a class="edit">Edit</a>
</div>
Je souhaite obtenir le nœud "Je suis texte", je ne souhaite pas supprimer la balise "edit" et j'ai besoin d'une solution multi-navigateurs.
Réponses:
Cela récupère l'
contents
élément sélectionné et lui applique une fonction de filtre. La fonction de filtre ne renvoie que les nœuds de texte (c'est-à-dire les nœuds avecnodeType == Node.TEXT_NODE
).la source
text()
car lafilter
fonction renvoie les nœuds eux-mêmes, pas le contenu des nœuds.jQuery("*").each(function() { console.log(this.nodeType); })
et j'en ai obtenu 1 pour tous les types de nœuds.Vous pouvez obtenir le nodeValue du premier childNode en utilisant
http://jsfiddle.net/TU4FB/
la source
null
une valeur de retour.Si vous voulez dire obtenir la valeur du premier nœud de texte de l'élément, ce code fonctionnera:
Vous pouvez le voir en action ici: http://jsfiddle.net/ZkjZJ/
la source
curNode.nodeType == 3
placenodeName
.curNode.nodeType == Node.TEXT_NODE
(la comparaison numérique est plus rapide mais curNode.nodeType == 3 n'est pas lisible - quel nœud a le numéro 3?)curNode.NodeType === Node.TEXT_NODE
. Cette comparaison se produit dans une boucle d'itérations possibles inconnues. Il est préférable de comparer deux petits nombres que de comparer des chaînes de différentes longueurs (considérations de temps et d'espace). La bonne question à se poser dans cette situation est "quel type / type de nœud ai-je?", Et non "quel nom ai-je?" developer.mozilla.org/en-US/docs/Web/API/Node/nodeTypechildNodes
, sachez qu'un nœud d'élément peut avoir plusieurs nœuds de texte. Dans une solution générique, il peut être nécessaire de spécifier quelle instance d'un nœud de texte dans un nœud d'élément que vous souhaitez cibler (le premier, le deuxième, le troisième, etc.).Une autre solution JS native qui peut être utile pour les éléments «complexes» ou profondément imbriqués consiste à utiliser NodeIterator . Mettez
NodeFilter.SHOW_TEXT
comme deuxième argument ("whatToShow"), et itérez uniquement sur les enfants du nœud de texte de l'élément.Vous pouvez également utiliser
TreeWalker
. La différence entre les deux est qu'ilNodeIterator
s'agit d'un simple itérateur linéaire, tout enTreeWalker
vous permettant de naviguer également via les frères et sœurs et les ancêtres.la source
JavaScript pur: minimaliste
Tout d'abord, gardez toujours cela à l'esprit lorsque vous recherchez du texte dans le DOM.
MDN - Espace blanc dans le DOM
Ce problème vous fera faire attention à la structure de votre XML / HTML.
Dans cet exemple purement JavaScript, je tiens compte de la possibilité de plusieurs nœuds de texte qui pourraient être entrelacés avec d'autres types de nœuds . Cependant, au départ, je ne porte pas de jugement sur les espaces, laissant cette tâche de filtrage à un autre code.
Dans cette version, je passe un
NodeList
à partir du code appelant / client.Bien sûr, en testant d'
node.hasChildNodes()
abord, il ne serait pas nécessaire d'utiliser unefor
boucle de pré-test .JavaScript pur: robuste
Ici, la fonction
getTextById()
utilise deux fonctions d'assistance:getStringsFromChildren()
etfilterWhitespaceLines()
.getStringsFromChildren ()
filterWhitespaceLines ()
getTextById ()
Ensuite, la valeur de retour (Array ou null) est envoyée au code client où elle doit être gérée. Espérons que le tableau devrait avoir des éléments de chaîne de texte réel, pas des lignes d'espaces.
Les chaînes vides (
""
) ne sont pas renvoyées car vous avez besoin d'un nœud de texte pour indiquer correctement la présence de texte valide. Renvoyer (""
) peut donner la fausse impression qu'un nœud de texte existe, amenant quelqu'un à supposer qu'il peut modifier le texte en changeant la valeur de.nodeValue
. Ceci est faux, car un nœud de texte n'existe pas dans le cas d'une chaîne vide.Exemple 1 :
Exemple 2 :
Le problème survient lorsque vous souhaitez rendre votre HTML facile à lire en l'espaçant. Maintenant, même s'il n'y a pas de texte valide lisible par l'homme, il y a toujours des nœuds de texte avec des caractères newline (
"\n"
) dans leurs.nodeValue
propriétés.Les humains voient les exemples un et deux comme fonctionnellement équivalents - des éléments vides en attente d'être remplis. Le DOM est différent du raisonnement humain. C'est pourquoi la
getStringsFromChildren()
fonction doit déterminer si des nœuds de texte existent et rassembler les.nodeValue
valeurs dans un tableau.Dans l'exemple deux, deux nœuds de texte existent et
getStringFromChildren()
renverront les.nodeValue
deux ("\n"
). Cependant,filterWhitespaceLines()
utilise une expression régulière pour filtrer les lignes de caractères d'espaces blancs purs.Revient
null
au lieu de caractères newline ("\n"
) est-il une forme de mensonge au client / code d'appel? En termes humains, non. En termes DOM, oui. Cependant, le problème ici est d' obtenir du texte, pas de le modifier. Il n'y a pas de texte humain pour revenir au code d'appel.On ne peut jamais savoir combien de caractères de nouvelle ligne peuvent apparaître dans le code HTML de quelqu'un. La création d'un compteur qui recherche le "deuxième" caractère de nouvelle ligne n'est pas fiable. Cela pourrait ne pas exister.
Bien sûr, plus tard, la question de l' édition de texte dans un
<p></p>
élément vide avec des espaces supplémentaires (exemple 2) peut signifier détruire (peut-être, sauter) tous les nœuds de texte sauf un entre les balises d'un paragraphe pour s'assurer que l'élément contient précisément ce qu'il est censé afficher.Quoi qu'il en soit, sauf dans les cas où vous faites quelque chose d'extraordinaire, vous aurez besoin d'un moyen de déterminer quelle
.nodeValue
propriété du nœud de texte a le vrai texte lisible par l'homme que vous souhaitez modifier.filterWhitespaceLines
nous amène à mi-chemin.À ce stade, vous pouvez avoir une sortie qui ressemble à ceci:
Il n'y a aucune garantie que ces deux chaînes soient adjacentes l'une à l'autre dans le DOM, donc les joindre avec
.join()
pourrait créer un composite non naturel. Au lieu de cela, dans le code qui appellegetTextById()
, vous devez choisir la chaîne avec laquelle vous souhaitez travailler.Testez la sortie.
On pourrait ajouter à l'
.trim()
intérieur degetStringsFromChildren()
pour se débarrasser des espaces de début et de fin (ou pour transformer un tas d'espaces en une chaîne de longueur nulle (""
), mais comment savoir a priori ce que chaque application peut avoir besoin pour le texte (chaîne) une fois qu'il est trouvé? Vous ne le faites pas, alors laissez cela à une implémentation spécifique, et laissezgetStringsFromChildren()
générique.Il peut y avoir des moments où ce niveau de spécificité (le
target
et tel) n'est pas requis. C'est super. Utilisez une solution simple dans ces cas. Cependant, un algorithme généralisé permet de s'adapter à des situations simples et complexes.la source
Version ES6 qui renvoie le premier contenu du nœud #text
la source
.from()
pour créer une instance de tableau copiée superficiellement. (2) L'utilisation de.find()
pour faire une comparaison de chaînes en utilisant.nodeName
. Utilisernode.NodeType === Node.TEXT_NODE
serait mieux. (3) Renvoyer une chaîne vide lorsqu'aucune valeur,,null
est plus vraie si aucun nœud de texte n'est trouvé. Si aucun nœud de texte n'est trouvé, vous devrez peut-être en créer un! Si vous renvoyez une chaîne vide""
, vous pouvez donner la fausse impression qu'un nœud de texte existe et peut être manipulé normalement. En substance, renvoyer une chaîne vide est un mensonge blanc et il vaut mieux éviter.[...node.childNodes]
pour convertir HTMLCollection en tableaux.text() - for jquery
la source
a
élément: jsfiddle.net/ekHJH.
au début de votre sélecteur, ce qui signifie que vous obtenez en fait le texte de l'title
élément, pas les éléments avecclass="title"
.innerText
est une ancienne convention IE récemment adoptée. En termes de script DOM standard,node.nodeValue
c'est ainsi que l'on saisit le texte d'un nœud de texte.Cela ignorera également les espaces blancs, vous n'avez donc jamais obtenu le code Blank textNodes..en utilisant le noyau Javascript.
Vérifiez-le sur jsfiddle: - http://jsfiddle.net/webx/ZhLep/
la source
curNode.nodeType === Node.TEXT_NODE
serait mieux. L'utilisation de la comparaison de chaînes et d'une expression régulière dans une boucle est une solution peu performante, d'autant plus que l'ampleur desoDiv.childNodes.length
augmentations. Cet algorithme résout la question spécifique de l'OP, mais, potentiellement, à un coût de performance terrible. Si la disposition ou le nombre de nœuds de texte change, il n'est pas garanti que cette solution renvoie une sortie précise. En d'autres termes, vous ne pouvez pas cibler le nœud de texte exact souhaité. Vous êtes à la merci de la structure HTML et de la disposition du texte.Vous pouvez également utiliser le
text()
test de nœud de XPath pour obtenir uniquement les nœuds de texte. Par exemplela source
C'est ma solution dans ES6 pour créer une chaîne contraining le texte concaténé de tous les nœuds enfants (récursif) . Notez que c'est également visitez le shdowroot des nœuds enfants.
Cette solution a été inspirée de la solution de https://stackoverflow.com/a/41051238./1300775 .
la source