遍历和更新 DOM

Traverse and Update DOM

我有下面的示例 html 页面。我想使用普通 JavaScript 遍历 DOM 并将单词 www.demourl.com 替换为 www.betaurl.com.

<!doctype html>
<html>
    <head>
      <meta charset="utf-8">
      <title>DOM replace</title>
      <script>
        function process(node){
            var nodes = node.childNodes;
            for (var i = 0; i <nodes.length; i++){
                if(!nodes[i]){
                    continue;
                } else {
                    if (nodes[i].data.indexOf("www.demourl.com") != -1) {
                        nodes[i].data = nodes[i].data.replace(/www.demourl.com/g, 'www.betaurl.com')
                    }
                }

                if(nodes[i].childNodes.length > 0){
                    loop(nodes[i]);
                }
            }
        }
        window.onload = function() {
            process(document);
        }         
      </script>
    </head>
    <body>
        <div id="main">
            <div id="first">www.demourl.com</div>
            <div id="second">
                <p>www.demourl.com</p>
            </div>
            <a href="http://www.demourl.com/demo">View Demo</a>
        </div>
        <div id="container">
            <table>
                <tr>
                    <td>
                        <img src="http://www.demourl.com/assets/">
                    </td>
                </tr>
            </table>
        </div>
    </body>
</html>

出于某种原因 URL 未在页面上被替换。流程功能需要做哪些改动?

几个问题:

  • 将参数传递给初始调用
  • 递归调用应该是 process,而不是 loop
  • 使用 .nodeValue 而不是 .data
  • 检查节点是否为文本节点,例如通过检查 nodeValue 是否存在(注释节点也是如此...)
  • 文字点需要在正则表达式中转义。
  • 为了在属性中也进行替换,您需要额外的代码来迭代这些。

更正:

function process(node){
    var nodes = node.childNodes;
    for (var i = 0; i <nodes.length; i++){
        //console.log(nodes[i]);
        if(!nodes[i]) continue;
         // *** it's not data, but nodeValue. Add a check if property exists
        if (nodes[i].nodeValue && nodes[i].nodeValue.indexOf("www.demourl.com") != -1) {
            // regex with escaped dot:
            nodes[i].nodeValue = nodes[i].nodeValue.replace(/www\.demourl\.com/g, 'www.betaurl.com')
        }
        // *** additional code to do same for attributes
        var attr = nodes[i].attributes;
        if (attr) {
            for (var j = 0; j < attr.length; j++) {
                if (attr[j].value.indexOf("www.demourl.com") != -1) {
                    attr[j].value = attr[j].value.replace(/www\.demourl\.com/g, 'www.betaurl.com')
                }
            }
        }
        if(nodes[i].childNodes.length > 0){
            process(nodes[i]); // *** it's not loop
        }
    }
}
window.onload = function() {
    process(document.body); // *** pass argument
}         
<div id="main">
    <div id="first">www.demourl.com</div>
    <div id="second">
        <p>www.demourl.com</p>
    </div>
    <a href="http://www.demourl.com/demo">View Demo</a>
</div>
<div id="container">
    <table>
        <tr>
            <td>
                <img src="http://www.demourl.com/assets/">
            </td>
        </tr>
    </table>
</div>