463 votes

Utilisation de .text() pour récupérer uniquement le texte non imbriqué dans des balises enfant

Si j'ai un html comme ça :

<li id="listItem">
    This is some text
    <span id="firstSpan">First span text</span>
    <span id="secondSpan">Second span text</span>
</li>

J'essaie d'utiliser .text() pour récupérer juste la chaîne "Ceci est du texte", mais si je disais $('#list-item').text() j'obtiens "This is some textFirst span textSecond span text".

Existe-t-il un moyen d'obtenir (et éventuellement de supprimer, via quelque chose du genre .text("") ) seulement le texte libre à l'intérieur d'une balise, et non le texte à l'intérieur de ses balises enfants ?

Le HTML n'a pas été écrit par moi, c'est donc avec cela que je dois travailler. Je sais qu'il serait simple d'envelopper le texte dans des balises lors de l'écriture du code HTML, mais là encore, le code HTML est pré-écrit.

0 votes

Parce que je n'ai pas encore assez de réputation pour commenter et que je ne souhaite pas que les connaissances soient perdues (en espérant qu'elles aident quelqu'un d'autre), une combinaison de Réponse de macio.Jun un RegExp, et Réponse de "iStranger à Remplacer un textNode par du HTML en Javascript ? m'a permis de rechercher une chaîne dans les nœuds de texte et de remplacer toutes les occurrences par des liens.

566voto

DotNetWala Points 1538

J'ai aimé cette mise en œuvre réutilisable basée sur la clone() méthode trouvée ici pour obtenir uniquement le texte à l'intérieur de l'élément parent.

Le code est fourni pour une référence facile :

$("#foo")
    .clone()    //clone the element
    .children() //select all the children
    .remove()   //remove all the children
    .end()  //again go back to selected element
    .text();

6 votes

Avec cette solution, vous obtenez uniquement le texte sans l'enfant, mais vous ne pouvez pas remplacer uniquement le texte.

1 votes

Je ne comprends pas une chose : si .end() revient à l'élément sélectionné, alors text() devrait copier le texte original avec les éléments enfants. Mais en pratique, je vois que le texte de notre clone manipulé est copié. Donc end() retourne au clone() ?

81 votes

C'est une manière vraiment inefficace de faire cela.

418voto

macio.Jun Points 1857

Réponse simple :

$("#listItem").contents().filter(function(){ 
  return this.nodeType == 3; 
})[0].nodeValue = "The text you want to replace with"

47 votes

Je ne comprends pas pourquoi les réponses efficaces (qui ne génèrent pas de structures de données superflues) ne sont pas votées autant que les réponses qui semblent moins effrayantes. +5 si je pouvais.

18 votes

Le simple et efficace réponse

11 votes

C'est non seulement plus efficace mais aussi plus correct ! Cette solution répond aux situations où le texte est dispersé entre les éléments enfants. +5

226voto

Stuart Points 7201

Cela ressemble à un cas de surutilisation de Jquery pour moi. Ce qui suit va saisir le texte en ignorant les autres noeuds :

document.getElementById("listItem").childNodes[0];

Vous aurez besoin de couper ça, mais ça vous donne ce que vous voulez en une seule ligne facile.

EDIT

Ce qui précède permettra d'obtenir le nœud de texte . Pour obtenir le texte réel, utilisez ceci :

document.getElementById("listItem").childNodes[0].nodeValue;

48 votes

Meilleure réponse, vous n'êtes pas censé avoir besoin d'un plugin pour cela ou d'une chaîne de 10 appels jQuery. $('.foo')[0].childNodes[0].nodeValue.trim()

6 votes

Que se passe-t-il si le contenu du texte est divisé en plusieurs noeuds (comme une séquence de crlf, texte, crlf) ? existe-t-il des garanties (de vie) que le dom construit par l'ua utilisera la structure la plus simple ?

5 votes

Totalement la meilleure réponse... pourquoi les autres personnes utilisent parfois trop jQuery ?

82voto

WakeupMorning Points 88

Plus facile et plus rapide :

$("#listItem").contents().get(0).nodeValue

0 votes

Est-ce compatible avec les différents navigateurs ?

0 votes

Bien sûr, il récupère un des éléments correspondant à l'objet jQuery donné par l'index : Docs Jquery .get() .

1 votes

@Nate Au cas où vous auriez besoin de l'utiliser sur une balise <br/>, vous pourriez utiliser la balise macio.Jun La réponse de la Commission.

48voto

DUzun Points 355

Similaire à la réponse acceptée, mais sans clonage :

$("#foo").contents().not($("#foo").children()).text();

Et voici un plugin jQuery à cet effet :

$.fn.immediateText = function() {
    return this.contents().not(this.children()).text();
};

Voici comment utiliser ce plugin :

$("#foo").immediateText(); // get the text without children

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X