CSS或JS修改(替换)网页上的每个单词

时间:2018-01-17 22:17:08

标签: javascript html css

对于复活节彩蛋,我希望能够用常量字符串替换网页上的每个单词。现有问题的重点是替换某些单词,不包含许多其他元素的元素,或使用诸如JQuery之类的库。应保留结构,即<li>Some text <span>link</span> more text</li>应成为<li>Lorem Lorem <span>Lorem</span> Lorem Lorem</li>

如果我像这样走DOM:

recur (el) {
  if (typeof el === 'undefined') {
    el = document.body
  }
  for (let e of el.childNodes) {
    if (e.nodeType === 1) {
      recur(e)
    } else if (e.nodeType === 3) {
      console.log(e)
    }
  }
}

我获得了许多#text元素和看起来像字符串的东西。我怎么能真正改变它们?我尝试分配父数组中的相应元素,但这不起作用:

Uncaught TypeError: Failed to set an indexed property on 'NodeList': Index property setter is not supported.

修改此类文本节点的父节点上的innerHTML属性是否更好?

或者你会推荐一种不同的方法吗?仅限CSS的解决方案也很棒。

3 个答案:

答案 0 :(得分:4)

多么有趣!您可以获取并分配给文本节点的nodeValue。正则表达式将至少与/[\w\x7f-\xff]+/g非常接近(十六进制值与特殊字符的很大一部分匹配)。   See here

(function recur (el) {
  if (typeof el === 'undefined') {
    el = document.body
  }
  for (let e of el.childNodes) {
    if (e.nodeType === Node.ELEMENT_NODE) {
      recur(e)
    } else if (e.nodeType === Node.TEXT_NODE) {
      e.nodeValue = e.nodeValue.replace(/[\w\x7f-\xff]+/g, 'lorem')
    }
  }
})();
<html>
<head>
<title>
A Simple HTML Document
</title>
</head>
<body>
<p>This is a very schön HTML document</p>
<p>It only has <b>two</b> paragraphs</p>
</body>
</html>

答案 1 :(得分:2)

我强烈建议您考虑使用TreeWalker,一个用于此目的的DOM API - 遍历DOM树。它可以找到文档中的所有文本节点,并且非常有效地找到它们,因为现代浏览器在本机代码中运行这样的API调用。

第一个参数是您要开始搜索的节点,第二个参数是要查找的节点类型。在这种情况下,我们从document.body开始寻找所有textNode。然后,在while循环中,您在节点上执行所需的任何操作,然后转到下一个。

通过这种植入,你不必处理尴尬的内部标签或空白区域 - 所有文本都很好地捆绑在一起。并且,它将比您在客户端JS中为树遍历编写的任何内容都快。

const matchAllExceptWhitespace = /\w+/g;
const treeWalker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, null, false);
const word = 'Lorem';

let node;

while (node = treeWalker.nextNode()) {
  node.textContent = node.textContent.replace(matchAllExceptWhitespace, word);
}
<h1>A paragraph</h1>
<p>This is a sentence.</p>
<ul>
    <li>Some text <span>link</span> more text</li>.
</ul>

答案 2 :(得分:1)

这是最简单的方法之一(从this answer借来一些帮助):

&#13;
&#13;
IsWin64
&#13;
function ReplaceChildText(node, replaceText) {
    //Is this a text node?
    if (node.nodeType === 3) {
      //Simply replace the value with your regex:
      node.nodeValue = node.nodeValue.replace(/\w+/g, replaceText);
    } else {
        //Loop through all the children, to look for more text nodes
        for (let child of node.childNodes) {
            //Yay, recursion
            ReplaceChildText(child, replaceText);
        }
    }
}

ReplaceChildText(document.body, 'Loreum');
&#13;
&#13;
&#13;