是否有一个简单的 JQuery 过程来替换页面上每段内部文本的字符串

Is there a simple JQuery procedure for a string replacement across every piece of inner text on the page?

本文关键字:段内部 文本 换页 字符串 替换 简单 有一个 JQuery 过程 是否      更新时间:2023-09-26

不要问我为什么需要这个。我需要的是一些简单的过程,如果有的话,用另一个单词替换一个单词的每个实例。我对 JQuery 没有经验,但我知道它相当于

$(document).ready(function(){
    var allElements = $('*');
    for each (var thisElement in allElements)
    {
        var newText = thisElement.text().replace("foo", "bar"); 
        thisElement.text(newText);     
    }
});

这样行得通吗?有没有更好的方法?如果可能的话,给我一个 1 行。

您尝试过的内容不起作用,因为它会从父元素中删除所有 HTML(从而删除所有子元素)。 如果使用 .text() ,则只需在textNodes上执行替换操作,以避免意外杀死子节点,从而杀死文档的结构。

在您的代码中,您替换的第一个父元素将从中获取.text()(仅返回文本,不返回子元素),然后重新设置.text()。 这最终会从文档中删除所有子元素,这不是您想要执行的操作。

我知道这样做的唯一方法是遍历文档中的所有单个文本节点,并对每个节点进行替换。

由于您要求使用jQuery方法来执行此操作,因此这里有一个(我认为它不是特别有效),但它似乎有效:

$(document.body).find("*").contents().each(function() {
    if (this.nodeType === 3) {
        this.nodeValue = this.nodeValue.replace(/foo/g, "bar");
    }
});
而且,如果你

真的想把它放在一行上(如果你问我,这会破坏可读性),你可以这样做:

$(document.body).find("*").contents().filter(function() {return this.nodeType === 3}).each(function() {this.nodeValue = this.nodeValue.replace(/foo/g, "bar")});
这将查找正文中的所有元素,然后

获取每个元素的所有子节点,然后迭代每个节点,仅查找要替换的文本节点。

工作演示:http://jsfiddle.net/jfriend00/qw8va10y/


一个可能更有效的方法可以在普通的Javascript中完成。

这段代码使用我之前开发的树遍历函数,它允许您循环访问父节点中的所有节点,并知道跳过不应迭代的某些类型的标签。 它需要一个回调,然后可以检查每个节点并决定要做什么:

var treeWalkFast = (function() {
    // create closure for constants
    var skipTags = {"SCRIPT": true, "IFRAME": true, "OBJECT": true, 
        "EMBED": true, "STYLE": true, "LINK": true, "META": true};
    return function(parent, fn, allNodes) {
        var node = parent.firstChild, nextNode;
        while (node && node != parent) {
            if (allNodes || node.nodeType === 1) {
                if (fn(node) === false) {
                    return(false);
                }
            }
            // if it's an element &&
            //    has children &&
            //    has a tagname && is not in the skipTags list
            //  then, we can enumerate children
            if (node.nodeType === 1 && node.firstChild && !(node.tagName && skipTags[node.tagName])) {
                node = node.firstChild;
            } else  if (node.nextSibling) {
                node = node.nextSibling;
            } else {
                // no child and no nextsibling
                // find parent that has a nextSibling
                while ((node = node.parentNode) != parent) {
                    if (node.nextSibling) {
                        node = node.nextSibling;
                        break;
                    }
                }
            }
        }
    }
})();
treeWalkFast(document.body, function(node) {
    // process only text nodes
    if (node.nodeType == 3) {
        node.nodeValue = node.nodeValue.replace(/foo/g, "bar");
    }
}, true);

工作演示:http://jsfiddle.net/jfriend00/Lvbr4a00/

我知道这不起作用的唯一情况是文本中间有 HTML 标签(因此它被拆分为多个文本节点)。 这是一个相当复杂的问题,因为你必须弄清楚如何处理你替换文本的东西中间的HTML格式。


而且,这是一个获取textNodes的jQuery插件(使用treeWalkFast()函数):

jQuery.fn.textNodes = function() {
    var nodes = [];
    this.each(function() {
        treeWalkFast(this, function(node) {
            if (node.nodeType === 3) {
                nodes.push(node);
            }
        }, true);
    });
    return this.pushStack(nodes, "textNodes");
}

而且,一个jQuery插件使用它来执行查找/替换:

// find text may be regex or string
// if using regex, use the g flag so it will replace all occurrences
jQuery.fn.findReplace = function(find, replace) {
    var fn;
    if (typeof find === "string") {
        fn = function(node) {
            var lastVal;
            // loop calling replace until the string doesn't change any more
            do {
                lastVal = node.nodeValue;
                node.nodeValue = lastVal.replace(find, replace);
            } while (node.nodeValue !== lastVal);
        }
    } else if (find instanceof RegExp) {
        fn = function(node) {
            node.nodeValue = node.nodeValue.replace(find, replace);
        }
    } else {
        throw new Error("find argument must be string or RegExp");
    }
    return this.each(function() {
        $(this).textNodes().each(function() {
            fn(this);
        });
    });
}

因此,一旦安装了这些插件和treeWalkFast()支持代码,您就可以这样做:

$(document.body).findReplace("foo", "bar");

工作演示:http://jsfiddle.net/jfriend00/7g1Lfvcm/