Javascript 替换整个文档源代码中的字符串
我有一个HTML文档,其中包含一个要替换的字符串。以下是字符串(Javascript 替换整个文档源代码中的字符串,javascript,Javascript,我有一个HTML文档,其中包含一个要替换的字符串。以下是字符串(9673): +5 9673 +5 9673 加载文档后,我想插入一个Javascript,将字符串9673替换为0000。我该怎么做?我只需要Javascript部分,它搜索整个HTMLL文档并替换字符串。您想要这样的内容吗 函数replace9673(){ $(“html”).html($(“html”).html().replaceAll(“9673”,“0000”); } +5 9673 +5 9673 点击我
9673
):
+5 9673
+5 9673
加载文档后,我想插入一个Javascript,将字符串
9673
替换为0000
。我该怎么做?我只需要Javascript部分,它搜索整个HTMLL文档并替换字符串。您想要这样的内容吗
函数replace9673(){
$(“html”).html($(“html”).html().replaceAll(“9673”,“0000”);
}
+5 9673
+5 9673
点击我
写得快,运行得慢的答案是滥用innerHTML
:
function replace_9673_everywhere() {
const documentHtml = document.documentElement.innerHTML;
const newDocumentHtml = documentHtml.replace( /9673/g, '0000' );
document.documentElement.innerHTML = newDocumentHtml;
}
…但这可能会破坏文档,因为它将使浏览器重新解析所有内容(因此任何包含DOM元素引用的当前页面脚本状态都将被破坏)
更好的方法是遍历DOM,因为这不会触发重新分析,前提是您操作元素.attributes
和元素.textContent
(和#text
节点分别),并避免完全使用innerHTML
/outerHTML
:
function replace_9673_everywhere() {
const rootNode = document.documentElement;
replace_9673_in_element( rootNode );
}
function replace_9673_in_element( el ) {
// Replace in attributes:
for( let i = 0; i < el.attributes.length; i++ ) {
const attr = el.attributes.item(i);
if( attr.value.includes( '9673' ) ) {
attr.value = attr.value.replace( /9673/g, '0000' );
}
}
// Replace in child nodes (not just Element children):
for( const childNode of el.childNodes ) {
if( childNode.nodeType === Node.TEXT_NODE ) {
if( childNode.textContent.includes( '9673' ) ) {
childNode.textContent = childNode.textContent.replace( /9673/g, '0000' );
}
}
else if( childNode.nodeType === Node.ELEMENT_NODE ) {
replace_9673_in_element( childNode );
}
}
}
function replace_9673_everywhere(){
const rootNode=document.documentElement;
替换_元素(rootNode)中的_9673_;
}
功能替换元件中的元件(el){
//在属性中替换:
for(设i=0;i
这里有另一种方法,使用TreeWalker
s,只针对文本节点和属性,而不影响实际的HTML结构
function*迭代节点(walker){
下一步
while(next=walker.nextNode()){
下一个屈服
}
}
const nodesUnder=(el,nodeFilters)=>{
const walker=文档
.createTreeWalker(el,节点过滤器)
常量节点=迭代节点(walker)
返回[…节点]
}
const htmlEl=document.documentElement
const textNodes=nodesUnder(htmlEl,NodeFilter.SHOW_TEXT)
const attrNodes=nodesUnder(htmlEl,NodeFilter.SHOW_元素)
.map(el=>[…el.attributes])
.flat()
;[…textNodes,…attrNodes].forEach(节点=>{
node.nodeValue=node.nodeValue.replace(/9673/g,'0000'))
})
console.log(document.querySelector(“#outer”).outerHTML)
*{font-family:sans-serif}
9673(更改)
不变的
您是在问如何“注入JavaScript”-还是在每个属性值和#text
节点中替换字符串值-还是两者都要问?而不是问如何注入JavaScript。Lemme编辑我的问题。你说的是解析html,对吗?你可以跳过regex,做一个简单的replaceAll()@shubhamsravastava浏览器支持String.prototype.replaceAll
(截至2020年9月,它只受Firefox 77+、Chromium 85浏览器(几周前发布)的支持)和Safari 13+,不包括当前版本的Opera和Android Firefox。childNode.nodeType
将始终是一个数字,而不是字符串,因此比较结果将始终为false
。您可以改为使用Node
下的枚举值:childNode.nodeType==Node.TEXT\u Node
和childNode.Nodeype===Node.ELEMENT\u Node
@LionelRowe-Derp,谢谢!对不起,我写我的答案时已经凌晨3点了。方法不错(+1)-但我感觉使用了扩展运算符[…nodes]
使用自定义生成器函数iterateNodes
无法使用延迟求值的生成器函数,因为这会立即将所有元素引用加载到内存中。为什么不简单地返回节点下的内部节点呢?其想法是可以延迟使用,但OP的用例不能需要它。公平地说,也许它对用例的设计有点过头了。
function replace_9673_everywhere() {
const rootNode = document.documentElement;
replace_9673_in_element( rootNode );
}
function replace_9673_in_element( el ) {
// Replace in attributes:
for( let i = 0; i < el.attributes.length; i++ ) {
const attr = el.attributes.item(i);
if( attr.value.includes( '9673' ) ) {
attr.value = attr.value.replace( /9673/g, '0000' );
}
}
// Replace in child nodes (not just Element children):
for( const childNode of el.childNodes ) {
if( childNode.nodeType === Node.TEXT_NODE ) {
if( childNode.textContent.includes( '9673' ) ) {
childNode.textContent = childNode.textContent.replace( /9673/g, '0000' );
}
}
else if( childNode.nodeType === Node.ELEMENT_NODE ) {
replace_9673_in_element( childNode );
}
}
}