我正在寻找一种方法来收集jQuery包装集中的所有文本,但我需要在它们之间没有文本节点的兄弟节点之间创建空格。
例如,请考虑以下HTML:
<div>
<ul>
<li>List item #1.</li><li>List item #2.</li><li>List item #3.</li>
</ul>
</div>
如果我只是使用jQuery的text()
方法来收集<div>
的文本内容,就像这样:
var $div = $('div'), text = $div.text().trim();
alert(text);
产生以下文字:
列表项目#1。列表项目#2。列表项目#3。
因为每个<li>
元素之间没有空格。我真正想要的是这个(注意每个句子之间的单一空格):
列出项目#1。列出项目#3。列出项目#3。
这告诉我,我需要遍历包装集中的DOM节点,将每个文本附加到字符串,然后是空格。我尝试了以下代码:
var $div = $('div'), text = '';
$div.find('*').each(function() {
text += $(this).text().trim() + ' ';
});
alert(text);
但是这产生了以下文字:
这是列表项#1。这是列表项#2。这是列表项#3。这是列表项#1。这是列表项#2。这是列表项目#3。
我认为这是因为我正在遍历<div>
的每个后代并附加文本,所以我在<ul>
和每个<li>
中都获得了文本节点孩子,导致重复的文字。
我想我可能会找到/编写一个简单的JavaScript函数来递归遍历包装集的DOM,收集和附加文本节点 - 但有没有更简单的方法来使用jQuery?跨浏览器的一致性非常重要。
感谢您的帮助!
答案 0 :(得分:7)
jQuery主要处理元素,其文本节点功能相对较弱。您可以获得contents()
所有孩子的列表,但是您仍然必须检查类型,这与使用普通DOM childNodes
完全没有区别。没有方法可以递归地获取文本节点,因此您必须自己编写一些内容,例如。类似的东西:
function collectTextNodes(element, texts) {
for (var child= element.firstChild; child!==null; child= child.nextSibling) {
if (child.nodeType===3)
texts.push(child);
else if (child.nodeType===1)
collectTextNodes(child, texts);
}
}
function getTextWithSpaces(element) {
var texts= [];
collectTextNodes(element, texts);
for (var i= texts.length; i-->0;)
texts[i]= texts[i].data;
return texts.join(' ');
}
答案 1 :(得分:2)
这是我能想到的最简单的解决方案:
$("body").find("*").contents().filter(function(){return this.nodeType!==1;});
答案 2 :(得分:0)
您可以使用jQuery contents()方法获取所有节点(包括文本节点),然后将您的集合过滤到仅文本节点。
$("body").find("*").contents().filter(function(){return this.nodeType!==1;});
从那里你可以创建你需要的任何结构。