我想获得一个元素的所有后代文本节点,作为一个 jQuery 集合。最好的方法是什么?
如何使用 jQuery 选择文本节点?
IT技术
javascript
jquery
dom
2021-01-12 20:28:36
6个回答
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 中它们会被自动过滤掉)。
更新:修正了当 includeWhitespaceNodes 为假时的错误。
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);
Jauco 在评论中发布了一个很好的解决方案,所以我在这里复制它:
$(elem)
.contents()
.filter(function() {
return this.nodeType === 3; //Node.TEXT_NODE
});
$('body').find('*').contents().filter(function () { return this.nodeType === 3; });
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);
});
其它你可能感兴趣的问题