如何使用 JavaScript(但不是标签或属性)替换字符串中所有匹配的纯文本字符串

how to replace all matching plain text strings in string using javascript (but not tags or attributes)?

本文关键字:字符串 文本 替换 JavaScript 何使用 属性 标签      更新时间:2023-09-26

想象页面上的这个html

<div id="hpl_content_wrap">
<p class="foobar">this is one word and then another word comes in foobar and then more words and then foobar again.</p>
<p>this is a <a href="http://foobar.com" data-bitly-type="bitly_hover_card">link with foobar in an attribute</a> but only the foobar inside of the link should be replaced.</p>
</div>

使用JavaScript,如何在不更改HTML标签内部的情况下将所有"foobar"单词更改为"herpderp"?

即只应更改纯文本。

所以成功的 html 更改将是

<div id="hpl_content_wrap">
<p class="foobar">this is one word and then another word comes in herpderp and then more words and then herpderp again.</p>
<p>this is a <a href="http://foobar.com" data-bitly-type="bitly_hover_card">link with herpderp in an attribute</a> but only the herpderp inside of the link should be replaced.    </p>
</div>

这是你需要做的...

  1. 获取对一堆元素的引用。
  2. 递归遍历子节点,仅替换文本节点中的文本。

抱歉耽搁了,在添加代码之前我就被分心了。

var replaceText = function me(parentNode, find, replace) {
    var children = parentNode.childNodes;
    for (var i = 0, length = children.length; i < length; i++) {
        if (children[i].nodeType == 1) {
            me(children[i], find, replace);            
        } else if (children[i].nodeType == 3) {
            children[i].data = children[i].data.replace(find, replace);
        }
    }
    return parentNode;
}
replaceText(document.body, /foobar/g, "herpderp");​​​

jsFiddle。

这是一个简单的问题:

  • 识别 DOM 树中的所有文本节点,
  • 然后替换其中的所有 foobar 字符串。

以下是完整代码:

// from: https://stackoverflow.com/questions/298750/how-do-i-select-text-nodes-with-jquery
var getTextNodesIn = function (el) {
    return $(el).find(":not(iframe)").andSelf().contents().filter(function() {
        return this.nodeType == 3;
    });
};
var replaceAllText = function (pattern, replacement, root) {
    var nodes = getTextNodesIn(root || $('body'))
    var re    = new RegExp(pattern, 'g')
    nodes.each(function (i, e) {
        if (e.textContent && e.textContent.indexOf(pattern) != -1) {
           e.textContent = e.textContent.replace(re, replacement);
        }
    });
};

// replace all text nodes in document's body
replaceAllText('foobar', 'herpderp');
// replace all text nodes under element with ID 'someRootElement'
replaceAllText('foobar', 'herpderp', $('#someRootElement'));

请注意,我对 foobar 进行了预检查,以避免使用正则表达式处理疯狂的长字符串。可能是也可能不是一个好主意。

如果你不想使用jQuery,而只想使用纯JavaScript,请点击代码片段中的链接(如何使用jQuery选择文本节点?),在那里你还会找到一个仅限JS的版本来获取节点。然后,您只需以类似的方式迭代返回的元素。