Comment obtenir le nœud de texte d’un élément?

I am text node Edit

Je souhaite obtenir le “Je suis un nœud de texte”, je ne souhaite pas supprimer la balise “edit” et j’ai besoin d’une solution inter-navigateurs.

 var text = $(".title").contents().filter(function() { return this.nodeType == Node.TEXT_NODE; }).text(); 

Cela récupère le contents de l’élément sélectionné et lui applique une fonction de filtrage. La fonction de filtre renvoie uniquement les nœuds de texte (c.-à-d. Les nœuds avec nodeType == Node.TEXT_NODE ).

Vous pouvez obtenir la valeur nodeValue du premier childNode en utilisant

 $('.title')[0].childNodes[0].nodeValue 

http://jsfiddle.net/TU4FB/

Si vous voulez dire obtenir la valeur du premier nœud de texte dans l’élément, ce code fonctionnera:

 var oDiv = document.getElementById("MyDiv"); var firstText = ""; for (var i = 0; i < oDiv.childNodes.length; i++) { var curNode = oDiv.childNodes[i]; if (curNode.nodeName === "#text") { firstText = curNode.nodeValue; break; } } 

Vous pouvez voir ceci en action ici: http://jsfiddle.net/ZkjZJ/

Une autre solution JS native qui peut être utile pour des éléments “complexes” ou profondément nesteds consiste à utiliser NodeIterator . Placez NodeFilter.SHOW_TEXT comme deuxième argument (“whatToShow”) et effectuez une itération sur les enfants du nœud de texte de l’élément.

 var root = document.getElementById('...'), iter = document.createNodeIterator (root, NodeFilter.SHOW_TEXT), textnode; while (textnode = iter.nextNode()) { // do something with the text node } 

Vous pouvez également utiliser TreeWalker . La différence entre les deux est que NodeIterator est un iterator linéaire simple, tandis que TreeWalker vous permet également de naviguer entre frères et sœurs et ancêtres.

.text() - for jquery

 $('.title').clone() //clone the element .children() //select all the children .remove() //remove all the children .end() //again go back to selected element .text(); //get the text of element 

Version ES6 qui renvoie le premier contenu de noeud #text

 const extract = (node) => { const text = Array.from(node.childNodes).find(child => child.NodeType === Node.TEXT_NODE); return text && text.textContent.sortingm(); } 

Ceci ignorera également les espaces, donc vous n’avez jamais le texte vide.

 var oDiv = document.getElementById("MyDiv"); var firstText = ""; for (var i = 0; i < oDiv.childNodes.length; i++) { var curNode = oDiv.childNodes[i]; whitespace = /^\s*$/; if (curNode.nodeName === "#text" && !(whitespace.test(curNode.nodeValue))) { firstText = curNode.nodeValue; break; } } 

Vérifiez sur jsfiddle: - http://jsfiddle.net/webx/ZhLep/

JavaScript pur: minimaliste

Tout d’abord, gardez toujours cela à l’esprit lorsque vous recherchez du texte dans le DOM.

MDN – Whitespace dans le DOM

Ce problème vous fera faire attention à la structure de votre XML / HTML.

Dans cet exemple JavaScript pur, je prends en compte la possibilité de plusieurs nœuds de texte pouvant être entrelacés avec d’autres types de nœuds . Cependant, au départ, je ne juge pas les espaces, laissant cette tâche de filtrage à un autre code.

Dans cette version, je passe une NodeList depuis le code appelant / client.

 /** * Gets ssortingngs from text nodes. Minimalist. Non-robust. Pre-test loop version. * Generic, cross platform solution. No ssortingng filtering or conditioning. * * @author Anthony Rutledge * @param nodeList The child nodes of a Node, as in node.childNodes. * @param target A positive whole number >= 1 * @return Ssortingng The text you targeted. */ function getText (nodeList, target) { var trueTarget = target - 1; var length = nodeList.length; // Because you may have many child nodes. for (var i = 0; i < length; i++) { if ((nodeList[i].nodeType === Node.TEXT_NODE) && (i === trueTarget)) { return nodeList[i].nodeValue; // Done! No need to keep going. } } return null; } 

Bien sûr, en testant d'abord node.hasChildNodes() , il ne serait pas nécessaire d'utiliser une boucle de pré-test.

 /** * Gets ssortingngs from text nodes. Minimalist. Non-robust. Post-test loop version. * Generic, cross platform solution. No ssortingng filtering or conditioning. * * @author Anthony Rutledge * @param nodeList The child nodes of a Node, as in node.childNodes. * @param target A positive whole number >= 1 * @return Ssortingng The text you targeted. */ function getText (nodeList, target) { var trueTarget = target - 1; var length = nodeList.length; var i = 0; do { if ((nodeList[i].nodeType === Node.TEXT_NODE) && (i === trueTarget)) { return nodeList[i].nodeValue; // Done! No need to keep going. } i++; } while (i < length); return null; } 

Pure JavaScript: Robuste

Ici, la fonction getTextById() utilise deux fonctions d'assistance: getSsortingngsFromChildren() et filterWhitespaceLines() .


getSsortingngsFromChildren ()

 /** * Collects ssortingngs from child text nodes. * Generic, cross platform solution. No ssortingng filtering or conditioning. * * @author Anthony Rutledge * @version 6.0 * @param parentNode An instance of the Node interface, such as an Element. object. * @return Array of ssortingngs, or null. * @throws TypeError if the parentNode is not a Node object. */ function getSsortingngsFromChildren(parentNode) { var ssortingngs = []; // The hopeful output; var nodeList; var length; if (!parentNode instanceof Node) { throw new TypeError("The parentNode parameter expects an instance of a Node."); } if (!parentNode.hasChildNodes()) { return null; // We are done. Node may resemble  } nodeList = parentNode.childNodes; length = nodeList.length; for (var i = 0; i < length; i++) { if (nodeList[i].nodeType === Node.TEXT_NODE) { strings.push(nodeList[i].nodeValue); } } if (strings.length > 0) { return ssortingngs; } return null; } 

filterWhitespaceLines ()

 /** * Filters an array of ssortingngs to remove whitespace lines. * Generic, cross platform solution. * * @author Anthony Rutledge * @version 6.0 * @param textArray a Ssortingng associated with the id atsortingbute of an Element. * @return Array of ssortingngs that are not lines of whitespace, or null. * @throws TypeError if the textArray param is not of type Array. */ function filterWhitespaceLines(textArray) { var filteredArray = []; // The hopeful output. var whitespaceLine = /(?:^\s+$)/; // Non-capturing Regular Expression. if (!textArray instanceof Array) { throw new TypeError("The textArray parameter expects an instance of a Array."); } for (var i = 0; i < textArray.length; i++) { if (!whitespaceLine.test(textArray[i])) { // If it is not a line of whitespace. filteredArray.push(textArray[i].trim()); // Trimming here is fine. } } if (filteredArray.length > 0) { return filteredArray ; // Leave selecting and joining ssortingngs for a specific implementation. } return null; // No text to return. } 

getTextById ()

 /** * Gets ssortingngs from text nodes. Robust. * Generic, cross platform solution. * * @author Anthony Rutledge * @version 6.0 * @param id A Ssortingng associated with the id property of an Element. * @return Array of ssortingngs, or null. * @throws TypeError if the id param is not of type Ssortingng. * @throws TypeError if the id param cannot be used to find a node by id. */ function getTextById(id) { var textArray = null; // The hopeful output. var idDatatype = typeof id; // Only used in an TypeError message. var node; // The parent node being examined. try { if (idDatatype !== "ssortingng") { throw new TypeError("The id argument must be of type Ssortingng! Got " + idDatatype); } node = document.getElementById(id); if (node === null) { throw new TypeError("No element found with the id: " + id); } textArray = getSsortingngsFromChildren(node); if (textArray === null) { return null; // No text nodes found. Example:  } textArray = filterWhitespaceLines(textArray); if (textArray.length > 0) { return textArray; // Leave selecting and joining ssortingngs for a specific implementation. } } catch (e) { console.log(e.message); } return null; // No text to return. } 

Ensuite, la valeur de retour (Array ou null) est envoyée au code client où elle doit être gérée. Si tout va bien, 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, ce qui amène l’utilisateur à supposer qu’il peut modifier le texte en modifiant 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 code HTML facile à lire en l’espaçant. Maintenant, même s'il n'y a pas de texte valide lisible par l'homme, il existe toujours des nœuds de texte avec des caractères de nouvelle ligne ( "\n" ) dans leurs propriétés .nodeValue .

Les humains voient les exemples un et deux comme équivalents fonctionnellement - les éléments vides en attente d'être remplis. Le DOM est différent du raisonnement humain. C'est pourquoi la fonction getSsortingngsFromChildren() doit déterminer si des nœuds de texte existent et rassembler les valeurs .nodeValue dans un tableau.

 for (var i = 0; i < length; i++) { if (nodeList[i].nodeType === Node.TEXT_NODE) { textNodes.push(nodeList[i].nodeValue); } } 

Dans l'exemple deux, deux nœuds de texte existent et getSsortingngFromChildren() renverra la valeur .nodeValue des deux ( "\n" ). Toutefois, filterWhitespaceLines() utilise une expression régulière pour filtrer les lignes filterWhitespaceLines() .

Retourne null au lieu de newline ( "\n" ) caractères une forme de mentir au client / code d'appel? En termes humains, non. En termes de DOM, oui. Cependant, le problème ici est d' obtenir du texte, pas de le modifier. Il n'y a pas de texte humain à retourner 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 caractère de "nouvelle" ligne n'est pas fiable. Il pourrait ne pas exister.

Bien sûr, plus tard, le problème de l’ édition de texte dans un élément vide

avec des espaces supplémentaires (exemple 2) peut signifier détruire (peut-être ignorer) tous les noeuds l'élément contient exactement ce qu'il est censé afficher.

Indépendamment de cela, sauf dans les cas où vous faites quelque chose d'extraordinaire, vous aurez besoin d'un moyen de déterminer la propriété .nodeValue du nœud de texte qui contient le texte lisible que vous souhaitez modifier. filterWhitespaceLines nous amène à mi-chemin.

 var whitespaceLine = /(?:^\s+$)/; // Non-capturing Regular Expression. for (var i = 0; i < filteredTextArray.length; i++) { if (!whitespaceLine.test(textArray[i])) { // If it is not a line of whitespace. filteredTextArray.push(textArray[i].trim()); // Trimming here is fine. } } 

À ce stade, vous pouvez avoir une sortie qui ressemble à ceci:

 ["Dealing with text nodes is fun.", "Some people just use jQuery."] 

Il n'y a aucune garantie que ces deux chaînes soient adjacentes dans le DOM, donc les joindre avec .join() pourrait créer un composite non naturel. Au lieu de cela, dans le code qui appelle getTextById() , vous devez choisir la chaîne avec laquelle vous voulez travailler.

Testez la sortie.

 try { var ssortingngs = getTextById("bio"); if (ssortingngs === null) { // Do something. } else if (ssortingngs.length === 1) { // Do something with ssortingngs[0] } else { // Could be another else if // Do something. It all depends on the context. } } catch (e) { console.log(e.message); } 

On pourrait append .sortingm() intérieur de getSsortingngsFromChildren() pour se débarrasser des espaces de début et de fin (ou pour transformer une série d'espaces en chaîne de longueur zéro ( "" )), mais comment savoir à priori pour arriver au texte (chaîne) une fois qu'il est trouvé Vous ne le faites pas, laissez cela à une implémentation spécifique et laissez getSsortingngsFromChildren() être générique.

Il peut y avoir des moments où ce niveau de spécificité (la target et tel) n'est pas requirejs. C'est super. Utilisez une solution simple dans ces cas. Toutefois, un algorithme généralisé vous permet de gérer des situations simples et complexes.

Vous pouvez également utiliser le test de noeud text() de XPath pour obtenir uniquement les noeuds de texte. Par exemple

 var target = document.querySelector('div.title'); var iter = document.evaluate('text()', target, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE); var node; var want = ''; while (node = iter.iterateNext()) { want += node.data; }