<div class="title">
I am text node
<a class="edit">Edit</a>
</div>
मैं "मैं पाठ नोड हूं" प्राप्त करना चाहता हूं, "संपादित करें" टैग को हटाने की इच्छा नहीं करता हूं, और क्रॉस ब्राउज़र समाधान की आवश्यकता है।
<div class="title">
I am text node
<a class="edit">Edit</a>
</div>
मैं "मैं पाठ नोड हूं" प्राप्त करना चाहता हूं, "संपादित करें" टैग को हटाने की इच्छा नहीं करता हूं, और क्रॉस ब्राउज़र समाधान की आवश्यकता है।
जवाबों:
var text = $(".title").contents().filter(function() {
return this.nodeType == Node.TEXT_NODE;
}).text();
यह contentsचयनित तत्व को प्राप्त करता है, और इसके लिए एक फिल्टर फ़ंक्शन लागू करता है। फ़िल्टर फ़ंक्शन केवल पाठ नोड्स (यानी उन नोड्स के साथ nodeType == Node.TEXT_NODE) देता है।
text()क्योंकि filterफ़ंक्शन नोड्स की सामग्री को नहीं, बल्कि स्वयं नोड्स को लौटाता है।
jQuery("*").each(function() { console.log(this.nodeType); })और मुझे सभी नोड प्रकारों के लिए 1 मिला ।
आप पहले चाइल्डनोड का उपयोग करके नोडवैल्यू प्राप्त कर सकते हैं
$('.title')[0].childNodes[0].nodeValue
nullरिटर्न वैल्यू मिल सकती है ।
यदि आपको लगता है कि तत्व में पहले टेक्स्ट नोड का मूल्य मिलता है, तो यह कोड काम करेगा:
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;
}
}
आप इसे यहां देख सकते हैं: http://jsfiddle.net/ZkjZJ/
curNode.nodeType == 3इसके बजाय उपयोग कर सकते हैं nodeName।
curNode.nodeType == Node.TEXT_NODE(संख्यात्मक तुलना तेज़ है लेकिन curNode.nodeType == 3 पढ़ने योग्य नहीं है - क्या नोड का नंबर 3 है?)
curNode.NodeType === Node.TEXT_NODE। यह तुलना अज्ञात संभव पुनरावृत्तियों के एक लूप के भीतर हो रही है। दो छोटी संख्याओं की तुलना विभिन्न लंबाई (समय और स्थान के विचारों) के तार की तुलना करने से बेहतर है। इस स्थिति में पूछने के लिए सही प्रश्न है "मेरे पास किस प्रकार / कितना नोड है?", और नहीं "मेरे पास क्या नाम है?" developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
childNodesयह जानने के लिए कि एक तत्व नोड आपके टेक्स्ट नोड से अधिक हो सकता है । एक सामान्य समाधान में, किसी को उस पाठ नोड के उदाहरण को निर्दिष्ट करने की आवश्यकता हो सकती है जिसमें आप उस तत्व नोड को लक्षित करना चाहते हैं (पहला, दूसरा, तीसरा, आदि ...)।
एक और मूल जेएस समाधान जो "जटिल" या गहराई से नेस्टेड तत्वों के लिए उपयोगी हो सकता है, वह है NodeIterator का उपयोग करना । NodeFilter.SHOW_TEXTदूसरे तर्क ("whatToShow") के रूप में रखें , और तत्व के सिर्फ पाठ नोड बच्चों पर पुनरावृति करें।
var root = document.querySelector('p'),
iter = document.createNodeIterator(root, NodeFilter.SHOW_TEXT),
textnode;
// print all text nodes
while (textnode = iter.nextNode()) {
console.log(textnode.textContent)
}
<p>
<br>some text<br>123
</p>
आप भी इस्तेमाल कर सकते हैं TreeWalker। दोनों के बीच का अंतर यह है कि NodeIteratorएक सरल रैखिक पुनरावृत्ति है, जबकि TreeWalkerआप भाई-बहनों और पूर्वजों के माध्यम से भी नेविगेट करने की अनुमति देता है।
सबसे पहले, डोम में पाठ की तलाश में हमेशा इसे ध्यान में रखें।
यह समस्या आपको अपने XML / HTML की संरचना पर ध्यान देगी।
इस शुद्ध जावास्क्रिप्ट उदाहरण में, मैं कई प्रकार के टेक्स्ट नोड्स की संभावना के लिए खाता हूं जो अन्य प्रकार के नोड्स के साथ इंटरलेय किया जा सकता है । हालाँकि, शुरू में, मैं व्हॉट्सएप पर निर्णय पारित नहीं करता, उस फ़िल्टरिंग कार्य को अन्य कोड पर छोड़ देता हूं।
इस संस्करण में, मैं NodeListकॉलिंग / क्लाइंट कोड से एक पास करता हूं ।
/**
* Gets strings from text nodes. Minimalist. Non-robust. Pre-test loop version.
* Generic, cross platform solution. No string 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 String The text you targeted.
*/
function getText(nodeList, target)
{
var trueTarget = target - 1,
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;
}
बेशक, node.hasChildNodes()पहले परीक्षण करके , प्री-टेस्ट forलूप का उपयोग करने की आवश्यकता नहीं होगी ।
/**
* Gets strings from text nodes. Minimalist. Non-robust. Post-test loop version.
* Generic, cross platform solution. No string 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 String The text you targeted.
*/
function getText(nodeList, target)
{
var trueTarget = target - 1,
length = nodeList.length,
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;
}
यहाँ फ़ंक्शन getTextById()दो सहायक कार्यों का उपयोग करता है: getStringsFromChildren()और filterWhitespaceLines()।
getStringsFromChildren ()
/**
* Collects strings from child text nodes.
* Generic, cross platform solution. No string filtering or conditioning.
*
* @author Anthony Rutledge
* @version 7.0
* @param parentNode An instance of the Node interface, such as an Element. object.
* @return Array of strings, or null.
* @throws TypeError if the parentNode is not a Node object.
*/
function getStringsFromChildren(parentNode)
{
var strings = [],
nodeList,
length,
i = 0;
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 <element></element>
}
nodeList = parentNode.childNodes;
length = nodeList.length;
do {
if ((nodeList[i].nodeType === Node.TEXT_NODE)) {
strings.push(nodeList[i].nodeValue);
}
i++;
} while (i < length);
if (strings.length > 0) {
return strings;
}
return null;
}
filterWhitespaceLines ()
/**
* Filters an array of strings to remove whitespace lines.
* Generic, cross platform solution.
*
* @author Anthony Rutledge
* @version 6.0
* @param textArray a String associated with the id attribute of an Element.
* @return Array of strings that are not lines of whitespace, or null.
* @throws TypeError if the textArray param is not of type Array.
*/
function filterWhitespaceLines(textArray)
{
var filteredArray = [],
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 strings for a specific implementation.
}
return null; // No text to return.
}
getTextById ()
/**
* Gets strings from text nodes. Robust.
* Generic, cross platform solution.
*
* @author Anthony Rutledge
* @version 6.0
* @param id A String associated with the id property of an Element.
* @return Array of strings, or null.
* @throws TypeError if the id param is not of type String.
* @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 !== "string") {
throw new TypeError("The id argument must be of type String! Got " + idDatatype);
}
node = document.getElementById(id);
if (node === null) {
throw new TypeError("No element found with the id: " + id);
}
textArray = getStringsFromChildren(node);
if (textArray === null) {
return null; // No text nodes found. Example: <element></element>
}
textArray = filterWhitespaceLines(textArray);
if (textArray.length > 0) {
return textArray; // Leave selecting and joining strings for a specific implementation.
}
} catch (e) {
console.log(e.message);
}
return null; // No text to return.
}
इसके बाद, वापसी मान (ऐरे, या नल) क्लाइंट कोड को भेजा जाता है जहां इसे संभाला जाना चाहिए। उम्मीद है, सरणी में वास्तविक पाठ के स्ट्रिंग तत्व होने चाहिए, न कि व्हॉट्सएप की लाइनें।
खाली स्ट्रिंग्स ( "") वापस नहीं आए क्योंकि आपको मान्य टेक्स्ट की उपस्थिति को ठीक से इंगित करने के लिए टेक्स्ट नोड की आवश्यकता होती है। रिटर्निंग ( "") गलत प्रभाव दे सकता है कि एक टेक्स्ट नोड मौजूद है, जिससे कोई यह मान सकता है कि वे पाठ का मान बदलकर बदल सकते हैं .nodeValue। यह गलत है, क्योंकि खाली स्ट्रिंग के मामले में एक टेक्स्ट नोड मौजूद नहीं है।
उदाहरण 1 :
<p id="bio"></p> <!-- There is no text node here. Return null. -->
उदाहरण 2 :
<p id="bio">
</p> <!-- There are at least two text nodes ("\n"), here. -->
समस्या तब आती है, जब आप अपने HTML को बाहर पढ़कर आसानी से बनाना चाहते हैं। अब, भले ही कोई मानव पठनीय मान्य पाठ नहीं है, फिर भी"\n" उनके अंदर नईलाइन ( ) वर्णों के साथ पाठ नोड्स हैं.nodeValue गुणों हैं।
मनुष्य उदाहरणों को एक और दो को कार्यात्मक रूप से समकक्ष के रूप में देखता है - खाली तत्वों को भरने की प्रतीक्षा करता है। डोम मानव तर्क से अलग है। यही कारण है कि getStringsFromChildren()फ़ंक्शन को यह निर्धारित करना चाहिए कि टेक्स्ट नोड्स मौजूद हैं और .nodeValueमानों को एक सरणी में इकट्ठा करते हैं।
for (var i = 0; i < length; i++) {
if (nodeList[i].nodeType === Node.TEXT_NODE) {
textNodes.push(nodeList[i].nodeValue);
}
}
उदाहरण दो में, दो टेक्स्ट नोड मौजूद हैं और उन दोनों ( ) getStringFromChildren()को वापस कर देंगे । हालाँकि, शुद्ध व्हाट्सएप वर्णों की पंक्तियों को फ़िल्टर करने के लिए एक नियमित अभिव्यक्ति का उपयोग करता है।.nodeValue"\n"filterWhitespaceLines()
क्या nullन्यूलाइन ( "\n") वर्णों के बजाय क्लाइंट / कॉलिंग कोड में झूठ बोलने का एक रूप है? मानवीय दृष्टि से, नहीं। DOM शब्दों में, हाँ। हालाँकि, यहाँ मुद्दा पाठ का है, संपादन का नहीं। कॉलिंग कोड पर लौटने के लिए कोई मानव पाठ नहीं है।
कोई यह नहीं जान सकता कि किसी के HTML में कितने नए वर्ण दिखाई दे सकते हैं। एक काउंटर बनाना जो "दूसरा" न्यूलाइन वर्ण के लिए दिखता है, अविश्वसनीय है। यह मौजूद नहीं हो सकता है।
बेशक, लाइन के नीचे, अतिरिक्त व्हाट्सएप (उदाहरण 2) के साथ एक खाली तत्व में पाठ को संपादित<p></p> करने का मतलब हो सकता है कि तत्व को सुनिश्चित करने के लिए पैराग्राफ के टैग के बीच सभी पाठ नोड को नष्ट कर दिया जाए, लेकिन इसमें क्या है। प्रदर्शन करना चाहिए।
भले ही, ऐसे मामलों को छोड़कर जहां आप कुछ असाधारण कर रहे हैं, आपको यह निर्धारित करने के लिए एक तरीके की आवश्यकता होगी कि किस टेक्स्ट नोड की .nodeValueसंपत्ति में सही, मानवीय पठनीय पाठ है जिसे आप संपादित करना चाहते हैं। filterWhitespaceLinesवहाँ हमें आधा रास्ता मिलता है।
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.
}
}
इस बिंदु पर आपके पास ऐसा उत्पादन हो सकता है जो इस तरह दिखता है:
["Dealing with text nodes is fun.", "Some people just use jQuery."]
इस बात की कोई गारंटी नहीं है कि ये दो तार डोम में एक दूसरे से सटे हुए हैं, इसलिए इनके साथ जुड़ने से .join()अप्राकृतिक संयोग बन सकता है। इसके बजाय, उस कोड में जो कॉल करता हैgetTextById() , आपको यह चुनने की आवश्यकता है आप किस स्ट्रिंग के साथ काम करना चाहते हैं।
आउटपुट का परीक्षण करें।
try {
var strings = getTextById("bio");
if (strings === null) {
// Do something.
} else if (strings.length === 1) {
// Do something with strings[0]
} else { // Could be another else if
// Do something. It all depends on the context.
}
} catch (e) {
console.log(e.message);
}
व्हाट्सएप को अग्रणी और अनुगामी बनाने से छुटकारा पाने के लिए (या रिक्त स्थान का एक गुच्छा शून्य लंबाई स्ट्रिंग में बदलने .trim()के getStringsFromChildren()लिए) जोड़ सकते हैं "", लेकिन आप प्राथमिकताओं को कैसे जान सकते हैं कि पाठ (स्ट्रिंग) के लिए हर आवेदन की आवश्यकता हो सकती है एक बार जब यह मिल जाता है? आप नहीं करते हैं, इसलिए इसे एक विशिष्ट कार्यान्वयन के लिए छोड़ दें, और getStringsFromChildren()सामान्य रहने दें।
ऐसा समय हो सकता है जब इस स्तर की विशिष्टता ( targetऔर ऐसी) की आवश्यकता नहीं है। यह बहुत बढ़िया बात है। उन मामलों में एक सरल समाधान का उपयोग करें। हालांकि, एक सामान्यीकृत एल्गोरिदम आपको सरल और जटिल स्थितियों को समायोजित करने में सक्षम बनाता है।
ES6 संस्करण जो पहले #text नोड सामग्री को लौटाता है
const extract = (node) => {
const text = [...node.childNodes].find(child => child.nodeType === Node.TEXT_NODE);
return text && text.textContent.trim();
}
.from()उथले-नकल सरणी उदाहरण बनाने के लिए उपयोग । (2) का उपयोग .find()करते हुए एक स्ट्रिंग तुलना करने का उपयोग .nodeName। का उपयोग node.NodeType === Node.TEXT_NODEकरना बेहतर होगा। (3) जब कोई मूल्य नहीं है, तो खाली स्ट्रिंग लौटना null, और अधिक सच है यदि नहीं पाठ नोड लौटाता है। यदि कोई टेक्स्ट नोड नहीं मिला है, तो किसी को एक बनाने की आवश्यकता हो सकती है! यदि आप एक खाली स्ट्रिंग लौटाते हैं "", तो आप गलत धारणा दे सकते हैं कि एक टेक्स्ट नोड मौजूद है और सामान्य रूप से हेरफेर किया जा सकता है। संक्षेप में, एक खाली स्ट्रिंग वापस करना एक सफेद झूठ है और सबसे अच्छा बचा जाता है।
[...node.childNodes]बदलने के लिए उपयोग करने के लिए बेहतर है
$('.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
aतत्व के भीतर भी पाठ प्राप्त करेगा : jsfiddle.net/ekHJH
.अपने चयनकर्ता की शुरुआत में गायब हैं , जिसका अर्थ है कि आप वास्तव में titleतत्व का पाठ प्राप्त करते हैं , तत्वों के साथ नहींclass="title"
.innerTextकेवल हाल ही में अपनाया गया एक पुराना IE सम्मेलन है। मानक DOM स्क्रिप्टिंग के संदर्भ में, node.nodeValueयह है कि कोई टेक्स्ट नोड के पाठ को कैसे पकड़ता है।
यह व्हाट्सएप को नजरअंदाज करेगा, साथ ही, आपको कभी भी ब्लैंक टेक्स्टनॉड्स नहीं मिलेंगे.. कोर जावास्क्रिप्ट का उपयोग करके।
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;
}
}
इसे jsfiddle पर देखें: - http://jsfiddle.net/webx/ZhLep/
curNode.nodeType === Node.TEXT_NODEबेहतर होगा। स्ट्रिंग तुलना और लूप के भीतर एक नियमित अभिव्यक्ति का उपयोग करना कम प्रदर्शन वाला समाधान है, विशेष रूप से oDiv.childNodes.lengthवृद्धि के परिमाण के रूप में । यह एल्गोरिथ्म ओपी के विशिष्ट प्रश्न को हल करता है, लेकिन, संभवतः, एक भयानक प्रदर्शन लागत पर। यदि पाठ नोड्स की व्यवस्था, या संख्या में परिवर्तन होता है, तो सटीक समाधान वापस करने के लिए इस समाधान की गारंटी नहीं दी जा सकती है। दूसरे शब्दों में, आप इच्छित टेक्स्ट नोड को लक्षित नहीं कर सकते। आप HTML संरचना और वहां पाठ की व्यवस्था की दया में हैं।
आप text()केवल पाठ नोड्स प्राप्त करने के लिए XPath के नोड परीक्षण का उपयोग कर सकते हैं । उदाहरण के लिए
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;
}
ES6 में यह मेरा समाधान है कि सभी चाइल्डनोड्स (पुनरावर्ती) के संक्षिप्त पाठ को नियंत्रित करने के लिए एक स्ट्रिंग बनाएं । ध्यान दें कि चाइल्डनॉड्स के शैंड्रोट का भी दौरा करें।
function text_from(node) {
const extract = (node) => [...node.childNodes].reduce(
(acc, childnode) => [
...acc,
childnode.nodeType === Node.TEXT_NODE ? childnode.textContent.trim() : '',
...extract(childnode),
...(childnode.shadowRoot ? extract(childnode.shadowRoot) : [])],
[]);
return extract(node).filter(text => text.length).join('\n');
}
यह समाधान https://stackoverflow.com/a/41051238./1300775 के समाधान से प्रेरित था ।