Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 是否有一个简单的JQuery过程来替换页面上每一段内部文本的字符串?_Javascript_Jquery - Fatal编程技术网

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

Javascript 是否有一个简单的JQuery过程来替换页面上每一段内部文本的字符串?,javascript,jquery,Javascript,Jquery,别问我为什么需要这个。我需要的是一些简单的过程,如果有的话,用另一个单词替换一个单词的每个实例。我对JQuery没有那么丰富的经验,但我知道它相当于 $(document).ready(function(){ var allElements = $('*'); for each (var thisElement in allElements) { var newText = thisElement.text().replace("foo", "bar");

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

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

这样行吗?有更好的办法吗?如果可能的话,给我一条一班轮的

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

在代码中,替换的第一个父元素将从中获取
.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")});
这将查找正文中的所有元素,然后获取这些元素中每个元素的所有子节点,然后迭代这些节点中的每个节点,只查找要替换的文本节点

工作演示:


一种可能更有效的方法可以在普通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);
工作演示:

<> P>我知道这不起作用的唯一的例子是如果文本中间有HTML标签(因此它被分割在一个以上的文本节点上)。这是一个相当复杂的问题需要解决,因为你必须弄清楚如何在你替换的文本中间处理HTML格式。
这里有一个jQuery插件,用于获取textNodes(使用
treeWalkFast()
函数):

还有一个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");

正在工作的演示:

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

在代码中,替换的第一个父元素将从中获取
.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")});
这将查找正文中的所有元素,然后获取这些元素中每个元素的所有子节点,然后迭代这些节点中的每个节点,只查找要替换的文本节点

工作演示:


一种可能更有效的方法可以在普通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);
工作演示:

<> P>我知道这不起作用的唯一的例子是如果文本中间有HTML标签(因此它被分割在一个以上的文本节点上)。这是一个相当复杂的问题需要解决,因为你必须弄清楚如何在你替换的文本中间处理HTML格式。
这里有一个jQuery插件,用于获取textNodes(使用
treeWalkFast()
函数):

还有一个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");

工作演示:

可以为您提供一行代码来替代整个html…但可能会破坏很多东西。不要担心代码长度和正确完成工作之间的关系。你可以用一行代码取代整个html,但可能会破坏很多东西。不要担心代码长度与正确完成任务之间的关系。添加的jQuery版本比普通Javascript版本短,但效率低得多。@charlietfl-很好。通过使
.replace()
使用带有
g
标志的正则表达式进行修复。如果OP不想使用正则表达式,也可以循环执行多个替换操作。为GRIN添加了一个线性版本(实际上只是将一系列链式操作塞进一行中)(这不是我最喜欢的表达代码的方式)。添加了jQuery插件,使其成为真正的一个线性版本(一旦安装了插件和支持代码)。添加了一个较短的jQuery版本,但比普通的Javascript版本效率低得多。@charlietfl-很好。通过生成<代码进行修复