Js

去除空白文本节点(空白符)

Posted by Leonsux on April 12, 2016

什么事空白符

空白文本节点是指在编写代码时缩进所造成的换行和空格。 可以借助下面的小demo和图解理解下

<!-- My document -->
<html>
<head>
  <title>My Document</title>
</head>
<body>
  <h1>Header</h1>
  <p>
    Paragraph
  </p>
</body>
</html>

图片来自:https://developer.mozilla.org

处理

理解了空白符现在要了解为什么要去除他。

在开发中可能需要获取一个元素的所有子元素(包括纯文本),就比如:

<div id="list">
  <li>1</li>
  <h2>5</h2>
  <li>2</li>
  <li>3</li>
  <p>4</p>
  hello word!
</div>

现在要获取list里的所有元素,包括那句hello word!,如果直接使用 list.childNodes 获取,就会把空白符也加进去,如下:

var list = document.getElementById("list");
var nodes = list.childNodes;
document.write("去除之前:" + nodes.length + "<br>");  //获取的长度为11,而我们需要的是6

其实如果需求中没有获取文本元素的要求的要,解决这个问题最方便的方法是使用:list.children,这个方法可以得到父节点的所有子节点,而且没有空白符,但是 hello word! 也会被清除掉 。

下面是两种清除空白符的方法

第一种方法是通过遍历所有子节点,过滤掉空白符,把满足条件的节点放到一个新的伪数组(不能使用正常数组的方法)里。

第二种方法是直接删除子节点中的空白符。

关于空白符的过滤,nodes.nodeType 是指节点类型,元素节点的nodeType 属性返回 1,属性节点返回 2,文本内容返回 3,空白符属于文本内容,所以用3判断,再就是 /^\s+$/.test(nodes[i].nodeValue),用正则表达式判断节点值是否全是空格。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        #list{
            background: red;
        }
    </style>
</head>
<body>
    <div id="list">
        <li>1</li>
        <h2>5</h2>
        <li>2</li>
        <li>3</li>
        <p>4</p>
        hello word!
    </div>
    <script type="text/javascript">
        /*去除空白文本节点
        */
        var list = document.getElementById("list");
        var nodes = list.childNodes;

        document.write("去除之前:" + nodes.length + "<br>");
        
        //方法一
        function ignoreSpace(nodes){
            var arr = new Array();
            for(var i = 0; i < nodes.length; i++){
                if (nodes[i].nodeType == 3 && /^\s+$/.test(nodes[i].nodeValue)) {
                    continue;
                } else {
                    arr.push(nodes[i]);
                }
            }
            return arr;
        }
        nodes = ignoreSpace(nodes);
        document.write("去除之后:" + nodes.length + "<br>");
        
        //方法二(推荐)
        function deleteSpace(obj){
            var nodes = obj.childNodes;
            for (var i = 0; i < nodes.length; i++) {
                if (nodes[i].nodeType == 3 && /^\s+$/.test(nodes[i].nodeValue)) {
                    obj.removeChild(nodes[i]);
                }
            }
            return obj; //这里其实不用返回也可以,因为传的值为对象的地址,在函数里操作的就是原obj
        }
        deleteSpace(list);
        document.write("去除之后:" + list.childNodes.length);
    </script>
</body>
</html>