在HTML文档中替换的文本被包装在多级标签中

时间:2017-07-27 11:13:45

标签: javascript html dom replace

我想加粗范围 [\u4e00-\ua000] 中的所有文字。 Chrome会成功替换它,但有些方法会将我的角色包含在多级标记内。

贝娄是我的代码。第一个片段是我的HTML和javascript。第二个是Chrome产生的。

注意:代码段说脚本中有错误,但真正的浏览器会愉快地运行它。

代码:

<script>
    function walkText(node) {
        if (node.nodeType == 3) {
            node.parentNode.innerHTML = node.parentNode.innerHTML.replace(/[\u4e00-\ua000]/g,
                function(a) {
                    return '<b class="myChineseChar">' + a + '</b>';
                }
            );
            return;
        }
        if (node.nodeType == 1 && node.nodeName != "SCRIPT") {
            for (var i = 0; i < node.childNodes.length; i++) {
                walkText(node.childNodes[i]);
            }
        }
    }
    walkText(document.body);


    function test(a) {
        alert(a.innerHTML);
    }


    var x = document.getElementsByClassName("myChineseChar");
    var i;
    for (i = 0; i < x.length; i++) {
        x[i].addEventListener("wheel", test);
    }
</script>
<html><body><div>We call it 一天一夜。<br/>Something like that</div></body></html>

结果

以下是Chrome浏览器的结果。不知道为什么它会让我的角色包裹得那么多:

<html>
<head></head>
<body>
	<div>We call it 
		<b class="myChineseChar">
			<b class="myChineseChar">
				<b class="myChineseChar">
					<b class="myChineseChar">
						<b class="myChineseChar">一</b>
					</b>
				</b>
			</b>
		</b>
		<b class="myChineseChar">
			<b class="myChineseChar">
				<b class="myChineseChar">
					<b class="myChineseChar">
						<b class="myChineseChar">天</b>
					</b>
				</b>
			</b>
		</b>
		<b class="myChineseChar">
			<b class="myChineseChar">
				<b class="myChineseChar">
					<b class="myChineseChar">
						<b class="myChineseChar">一</b>
					</b>
				</b>
			</b>
		</b>
		<b class="myChineseChar">
			<b class="myChineseChar">
				<b class="myChineseChar">
					<b class="myChineseChar">
						<b class="myChineseChar">夜</b>
					</b>
				</b>
			</b>
		</b>
		<br>Something like that
	</div> 
</body>
</html>

期望的结果:

<html>
	<body>
	<div>We call it 
		<b class="myChineseChar">一</b>
		<b class="myChineseChar">天</b>
		<b class="myChineseChar">一</b>
		<b class="myChineseChar">夜</b>。
		<br>Something like that
	</div>
	</body>
</html> 

问题:我的代码中的错误在哪里以及如何解决它以获得所需的结果?

注意:我的答案中的代码可以部分解决问题,但不会输出相同的所需输出。我还在寻找更好的答案。

注意:我需要替换文档中的所有文本,无论它位于什么标记中,但是:

  • 它必须只替换内部文本节点,而不是替换其他地方的文本,例如在javascript中。

2 个答案:

答案 0 :(得分:0)

我已经修改了一下代码:) 现在它起作用。
问题在于遍历每个子元素的父元素并替换一个字符。你最终得到了n个替换

&#13;
&#13;
<html>

<head>
  <link rel="stylesheet" href="style.css">
  <script src="script.js"></script>
</head>

<body>
  <div id='ssss'>We call it 一 天 一 夜
    <br>Something like that
  </div>
  <script>
    function walkText(node) {
      node.innerHTML = node.innerHTML.replace(/[\u4e00-\ua000]/g,
        function(a) {
          return '<b class="myChineseChar">' + a + '</b>';
        }
      );
      return;
    }

    walkText(document.body);


    function test(a) {
      alert(a.innerHTML);
    }


    var x = document.getElementsByClassName("myChineseChar");
    var i;
    for (i = 0; i < x.length; i++) {
      x[i].addEventListener("wheel", test);
    }
  </script>
</body>

</html>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

此代码可以部分解决问题:

代码:

< script >
function walkText(node) {
	if (node.nodeType == 1 && node.nodeName != "SCRIPT") {
	for (var i = 0; i < node.childNodes.length; i++) {
		if (node.childNodes[i].nodeType == 3 && /[\u4e00-\ua000]/.test(node.childNodes[i].data)) {
		var elmnt = document.createElement("span");
		elmnt.innerHTML = node.childNodes[i].data.replace(/[\u4e00-\ua000]/g,
			function(a) {
			return '<b class="myChineseChar">' + a + "</b>";
			}
		);
		node.replaceChild(elmnt, node.childNodes[i]);
		} else walkText(node.childNodes[i]);
	}
	}
	return 0;
}
walkText(document.body);


function test(a) {
alert(a.innerHTML);
}


var x = document.getElementsByClassName("myChineseChar");
var i;
for (i = 0; i < x.length; i++) {
x[i].addEventListener("wheel", test);
} < /script>
<html>

<body>
  <div>
    We call it 一天一夜。
    <br/> Something like that
    <div>
      We call it 一天一夜。
      <p>
        We call it 一天一夜。
      </p>
    </div>
  </div>
</body>

</html>

它输出的结果不会像我的问题那样是多级包装,但它会将所有文本放在 SPAN 标记内,这是可以接受的,但并不完美:

结果:

<html>
   <head></head>
   <body>
      <div>
         <span>
         We call it 
         <b class="myChineseChar">一</b>
         <b class="myChineseChar">天</b>
         <b class="myChineseChar">一</b>
         <b class="myChineseChar">夜</b>。
         </span>
         <br/>
         Something like that
         <div>
            <span>
            We call it 
            <b class="myChineseChar">一</b>
            <b class="myChineseChar">天</b>
            <b class="myChineseChar">一</b>
            <b class="myChineseChar">夜</b>。
            </span>
            <p>
               <span>
               We call it 
               <b class="myChineseChar">一</b>
               <b class="myChineseChar">天</b>
               <b class="myChineseChar">一</b>
               <b class="myChineseChar">夜</b>。
               </span>
            </p>
         </div>
      </div>
   </body>
</html>