我想替换给定元素的所有后代元素(的文本)中的特定字符串。
无法使用 innerHTML
,因为此序列可以出现在属性中。我尝试过使用XPath,但看起来界面基本上是只读的。由于这仅限于一个元素,因此无法使用document.getElementsByTagName
等函数。
有人建议采取任何办法吗?任何jQuery或纯DOM方法都是可以接受的。
编辑:
一些答案表明我试图解决的问题:直接修改元素上的文本将导致所有非Text子节点被删除。
所以问题主要归结为如何有效地选择树中的所有Text节点。在XPath中,您可以轻松地将其作为//text()
执行,但当前的XPath接口不允许您更改这些Text节点。
执行此操作的一种方法是通过Bergi的answer中显示的递归。另一个way是使用jQuery的find('*')
选择器,但这有点贵。还在等着看是否有更好的解决方案。
答案 0 :(得分:4)
只需使用一个简单的自制DOM迭代器,它在所有节点上递归遍历:
(function iterate_node(node) {
if (node.nodeType === 3) { // Node.TEXT_NODE
var text = node.data.replace(/any regular expression/g, "any replacement");
if (text != node.data) // there's a Safari bug
node.data = text;
} else if (node.nodeType === 1) { // Node.ELEMENT_NODE
for (var i = 0; i < node.childNodes.length; i++) {
iterate_node(node.childNodes[i]); // run recursive on DOM
}
}
})(content); // any dom node
答案 1 :(得分:1)
解决方案可能是浏览所有可用节点(包括TextNodes)并对结果应用正则表达式模式。要同时抓取TextNodes,您需要调用jQuerys .contents()
。例如:
var search = "foo",
replaceWith = 'bar',
pattern = new RegExp( search, 'g' );
function searchReplace( root ) {
$( root ).contents().each(function _repl( _, node ) {
if( node.nodeType === 3 )
node.nodeValue = node.nodeValue.replace( pattern, replaceWith );
else searchReplace( node );
});
}
$('#apply').on('click', function() {
searchReplace( document.getElementById('rootNode') );
});
示例:http://jsfiddle.net/h8Rxu/3/
参考:.contents()
答案 2 :(得分:0)
抱歉,我自己拿到了:
$('#id').find('*').each(function(){
$.each(this.childNodes, function() {
if (this.nodeType === 3) {
this.data = this.data.toUpperCase();
}
})
})
我在这里使用了toUcapCase()来使结果更加明显,但任何String操作在那里都是有效的。
答案 3 :(得分:0)
使用jQuery:
$('#parent').children().each(function () {
var that = $(this);
that.text(that.text().replace('test', 'foo'));
});
如果您希望搜索所有孩子而不是直接孩子,请改用.find()
。