मैं एक jQuery संग्रह के रूप में एक तत्व के सभी वंशज पाठ नोड्स प्राप्त करना चाहता हूं। उसे करने का सबसे अच्छा तरीका कौन सा है?
मैं एक jQuery संग्रह के रूप में एक तत्व के सभी वंशज पाठ नोड्स प्राप्त करना चाहता हूं। उसे करने का सबसे अच्छा तरीका कौन सा है?
जवाबों:
jQuery के पास इसके लिए सुविधाजनक कार्य नहीं है। आपको गठबंधन करने की आवश्यकता है contents()
, जो सिर्फ बच्चे को नोड्स देगा, लेकिन इसमें टेक्स्ट नोड्स भी शामिल हैं find()
, जिसके साथ सभी वंशज तत्व हैं लेकिन कोई टेक्स्ट नोड्स नहीं है। यहाँ मैं क्या लेकर आया हूँ:
var getTextNodesIn = function(el) {
return $(el).find(":not(iframe)").addBack().contents().filter(function() {
return this.nodeType == 3;
});
};
getTextNodesIn(el);
नोट: यदि आप jQuery 1.7 या पहले का उपयोग कर रहे हैं, तो ऊपर दिया गया कोड काम नहीं करेगा। इसे ठीक करने के लिए, के addBack()
साथ बदलें andSelf()
। 1.8 से आगे के andSelf()
पक्ष में पदावनत किया जाता है addBack()
।
यह शुद्ध DOM तरीकों की तुलना में कुछ अक्षम है और इसमें jQuery के अपने contents()
फ़ंक्शन के ओवरलोडिंग के लिए एक बदसूरत वर्कअराउंड को शामिल करना है (यह इंगित करने के लिए टिप्पणियों में @rabidsnail के लिए धन्यवाद), इसलिए यहां एक साधारण पुनरावर्ती फ़ंक्शन का उपयोग करके गैर-jQuery समाधान है। includeWhitespaceNodes
पैरामीटर नियंत्रण किया जाए या नहीं खाली स्थान के पाठ नोड्स उत्पादन में शामिल हैं (jQuery में वे स्वचालित रूप से फ़िल्टर किए जाते हैं)।
अद्यतन: फिक्स्ड बग जब शामिल हैंवॉटस्पेसनोड्स मिथ्या है।
function getTextNodesIn(node, includeWhitespaceNodes) {
var textNodes = [], nonWhitespaceMatcher = /\S/;
function getTextNodes(node) {
if (node.nodeType == 3) {
if (includeWhitespaceNodes || nonWhitespaceMatcher.test(node.nodeValue)) {
textNodes.push(node);
}
} else {
for (var i = 0, len = node.childNodes.length; i < len; ++i) {
getTextNodes(node.childNodes[i]);
}
}
}
getTextNodes(node);
return textNodes;
}
getTextNodesIn(el);
document.getElementById()
यदि आप जो चाहते हैं, तो आप सबसे पहले कॉल कर सकते हैं :var div = document.getElementById("foo"); var textNodes = getTextNodesIn(div);
.contents()
वैसे भी इसका उपयोग iframe के माध्यम से खोज करेगा। मैं नहीं देखता कि यह बग कैसे हो सकता है।
Jauco ने एक टिप्पणी में एक अच्छा समाधान पोस्ट किया है, इसलिए मैं इसे यहां कॉपी कर रहा हूं:
$(elem)
.contents()
.filter(function() {
return this.nodeType === 3; //Node.TEXT_NODE
});
jQuery.contents()
jQuery.filter
सभी बाल पाठ नोड्स को खोजने के लिए इस्तेमाल किया जा सकता है । थोड़े से मोड़ के साथ, आप पोते-पोतियों को भी पा सकते हैं। कोई पुनरावृत्ति आवश्यक नहीं:
$(function() {
var $textNodes = $("#test, #test *").contents().filter(function() {
return this.nodeType === Node.TEXT_NODE;
});
/*
* for testing
*/
$textNodes.each(function() {
console.log(this);
});
});
div { margin-left: 1em; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="test">
child text 1<br>
child text 2
<div>
grandchild text 1
<div>grand-grandchild text 1</div>
grandchild text 2
</div>
child text 3<br>
child text 4
</div>
मुझे स्वीकृत फ़िल्टर फ़ंक्शन के साथ बहुत सारे खाली पाठ नोड्स मिल रहे थे। यदि आप केवल ऐसे टेक्स्ट नोड्स का चयन करने में रुचि रखते हैं, जिनमें गैर-व्हाट्सएप हो, तो nodeValue
अपने filter
फ़ंक्शन को एक साधारण की तरह सशर्त जोड़ने का प्रयास करें $.trim(this.nodevalue) !== ''
:
$('element')
.contents()
.filter(function(){
return this.nodeType === 3 && $.trim(this.nodeValue) !== '';
});
या अजीब स्थितियों से बचने के लिए जहां सामग्री व्हाट्सएप की तरह दिखती है, लेकिन ऐसा नहीं है (जैसे कि नरम हाइफ़न ­
चरित्र, नए अंक \n
, टैब, आदि), आप एक नियमित अभिव्यक्ति का उपयोग करने का प्रयास कर सकते हैं। उदाहरण के लिए, \S
किसी भी गैर-व्हाट्सएप पात्रों से मेल खाएगा:
$('element')
.contents()
.filter(function(){
return this.nodeType === 3 && /\S/.test(this.nodeValue);
});
यदि आप यह अनुमान लगा सकते हैं कि सभी बच्चे या तो तत्व नोड्स या टेक्स्ट नोड्स हैं, तो यह एक समाधान है।
एक संग्रह के रूप में सभी बाल पाठ नोड्स प्राप्त करने के लिए:
$('selector').clone().children().remove().end().contents();
हटाए गए गैर-पाठ बच्चों के साथ मूल तत्व की एक प्रति प्राप्त करने के लिए:
$('selector').clone().children().remove().end();
किसी कारण से contents()
मेरे लिए काम नहीं किया, इसलिए अगर यह आपके लिए काम नहीं करता है, तो यहां एक समाधान मैंने बनाया है, मैंने jQuery.fn.descendants
टेक्स्ट नोड्स शामिल करने के विकल्प के साथ बनाया या नहीं
प्रयोग
पाठ नोड्स और तत्व नोड्स सहित सभी वंशज प्राप्त करें
jQuery('body').descendants('all');
केवल पाठ नोड्स लौटने वाले सभी वंशज प्राप्त करें
jQuery('body').descendants(true);
केवल तत्व नोड्स लौटने वाले सभी वंशज प्राप्त करें
jQuery('body').descendants();
कॉफ़ीस्क्रिप्ट मूल :
jQuery.fn.descendants = ( textNodes ) ->
# if textNodes is 'all' then textNodes and elementNodes are allowed
# if textNodes if true then only textNodes will be returned
# if textNodes is not provided as an argument then only element nodes
# will be returned
allowedTypes = if textNodes is 'all' then [1,3] else if textNodes then [3] else [1]
# nodes we find
nodes = []
dig = (node) ->
# loop through children
for child in node.childNodes
# push child to collection if has allowed type
nodes.push(child) if child.nodeType in allowedTypes
# dig through child if has children
dig child if child.childNodes.length
# loop and dig through nodes in the current
# jQuery object
dig node for node in this
# wrap with jQuery
return jQuery(nodes)
जावास्क्रिप्ट संस्करण में छोड़ें
var __indexOf=[].indexOf||function(e){for(var t=0,n=this.length;t<n;t++){if(t in this&&this[t]===e)return t}return-1}; /* indexOf polyfill ends here*/ jQuery.fn.descendants=function(e){var t,n,r,i,s,o;t=e==="all"?[1,3]:e?[3]:[1];i=[];n=function(e){var r,s,o,u,a,f;u=e.childNodes;f=[];for(s=0,o=u.length;s<o;s++){r=u[s];if(a=r.nodeType,__indexOf.call(t,a)>=0){i.push(r)}if(r.childNodes.length){f.push(n(r))}else{f.push(void 0)}}return f};for(s=0,o=this.length;s<o;s++){r=this[s];n(r)}return jQuery(i)}
अनवांटेड जावास्क्रिप्ट संस्करण: http://pastebin.com/cX3jMfuD
यह क्रॉस ब्राउज़र है, एक छोटा Array.indexOf
पॉलीफ़िल कोड में शामिल है।
इस तरह भी किया जा सकता है:
var textContents = $(document.getElementById("ElementId").childNodes).filter(function(){
return this.nodeType == 3;
});
उपरोक्त कोड दिए गए तत्व के सीधे बच्चे चाइल्ड नोड्स से टेक्स्टनोड्स को फ़िल्टर करता है।
यदि आप सभी टैग को हटाना चाहते हैं, तो यह प्रयास करें
समारोह:
String.prototype.stripTags=function(){
var rtag=/<.*?[^>]>/g;
return this.replace(rtag,'');
}
उपयोग:
var newText=$('selector').html().stripTags();
मेरे लिए, सादे पुराने .contents()
पाठ नोड्स को वापस करने के लिए काम करते दिखाई दिए, बस आपको अपने चयनकर्ताओं से सावधान रहना होगा ताकि आपको पता चले कि वे पाठ नोड्स होंगे।
उदाहरण के लिए, इसने टीडी के सभी पाठ सामग्री को pre
टैग के साथ मेरी तालिका में लपेटा और कोई समस्या नहीं थी।
jQuery("#resultTable td").content().wrap("<pre/>")
मेरे पास एक ही समस्या थी और इसे हल किया:
कोड:
$.fn.nextNode = function(){
var contents = $(this).parent().contents();
return contents.get(contents.index(this)+1);
}
उपयोग:
$('#my_id').nextNode();
की तरह है, next()
लेकिन पाठ नोड्स भी लौटाता है।