我想获得一个元素的所有后代文本节点,作为一个jQuery集合。什么是最好的方法来做到这一点?
一个很好的解决方案
$(elem)
.contents()
.filter(function() {
return this.nodeType === 3; //Node.TEXT_NODE
});
Query没有一个方便的功能。你需要结合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()。andSelf()被弃用,addBack()从1.8开始。
与纯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);