Document.body.innerHTML.replace不能使用变量正则字符串

Document.body.innerHTML.replace not working with variable regex string

本文关键字:变量 字符串 body innerHTML replace 不能 Document      更新时间:2023-09-26

下面的代码应该通过使用前一个标题标签的href链接替换wikipedia页面上特定标题标签文本的每个实例来工作。然而,似乎没有任何东西可以取代任何东西。当用硬编码的值测试这段代码时,它工作得非常好。控制台日志显示一切都应该正常工作,但事实并非如此。任何帮助都会很感激。

if (document.title.indexOf("Wikipedia") != -1) {
    var pageHTML = document.body.innerHTML;
    for(var i = 0, l=document.links.length; i<l; i++) {
      //doSomething(document.links[i].href);
      var link = document.links[i].href;
      var title = document.links[i].title;
      if(title != ""){
        var a = document.createElement('a');
        var linkText = document.createTextNode(title);
        a.appendChild(linkText);
        a.title = title;
        a.href = link;
        console.log(typeof title)
        pageHTML = document.body.innerHTML.replace(new RegExp(title,"g"), a);
      }
    }
    //var finalHTML = "<h1>HELLO<h1>"
    //Appending to DOM
    document.open();
    document.write(pageHTML);
    document.close();
}

除了每次迭代用单个值覆盖pageHTML之外,目前您可以替换整个页面HTML并破坏其javascript事件,例如单击/悬停处理程序和许多其他通过addEventListener或.on属性附加的事件。此外,您将覆盖整个页面,从而迫使浏览器完全解析它并重新绘制。

正确的方法是只替换包含标题文本的节点:

// title-to-href map used for bulk regexp-replacement
var linkMap = {};
var linkTitles = [];
for (var i = 0, link; (link = document.links[i++]); ) {
    if (link.title) {
        linkTitles.push(escapeForRegex(link.title));
        linkMap[link.title] = link.href;
    }
}
// regexp that matches all titles
var titlesRx = new RegExp(linkTitles.join('|'), 'g');
// iterate all text nodes and build a list of elements that contain titles
var nodesToReplace = [];
var walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);
while (walker.nextNode()) {
    var node = walker.currentNode;
    var newHTML = node.nodeValue.replace(titlesRx, function(title) {
        return '<a href="' + linkMap[title] + '" title="' + title + '">' + title + '</a>';
    });
    if (newHTML != node.nodeValue) {
        nodesToReplace.push({node: node, html: newHTML});
    }
}
// replace the contents of affected elements
var scratchpad = document.createElement('div');
nodesToReplace.forEach(function(info) {
    scratchpad.innerHTML = info.html;
    for (var i = 0, child; (child = scratchpad.children[i++]); ) {
       info.node.parentNode.insertBefore(child, info.node);
    }
    info.node.remove();
});
function escapeForRegex(s) { return s.replace(/[{}()'[']'/''.+?^$:=*!|]/g, "''$&"); }

也许你错过了这个:-

pageHTML = document.body.innerHTML.replace(new RegExp(title,"igm"), a);

如果您的意思是将title属性的值替换为父链接的href属性的值,则此解决方案肯定有效

pageHTML = document.body.innerHTML.replace(title, link);