"假"文本节点导致问题

时间:2016-03-29 00:17:23

标签: javascript jquery dom traversal

我正在研究DOM遍历类型的脚本,我几乎已经完成了它。但是,我遇到了一个问题,对于我的生活,我无法弄清楚如何解决这个问题。请原谅我的无能,因为我是JS / JQuery的新手,而且我还在学习绳索。

基本上,我使用Javascript / JQuery创建一个"大纲",表示HTML页面的结构,并附加"大纲"到网页的底部。例如,如果HTML是这个......

<html>
    <head>
    </head>
    <body>
        <h1>Hello World</h1>
        <script src=”http://code.jquery.com/jquery-2.1.0.min.js” type=”text/javascript”>
        </script>
        <script src=”outline.js” type=”text/javascript”></script>
    </body>
</html>

然后输出应该是这样的无序列表:

这是我到目前为止所得到的:

var items=[];
$(document).ready(function(){
    $("<ul id = 'list'></ul>").appendTo("body");

    traverse(document, function (node) { 
        if(node.nodeName.indexOf("#") <= -1){
            items.push("<ul>"+"<li>"+node.nodeName.toLowerCase());
        }
        else {
            var x = "text("+node.nodeValue+")";
            if(node.nodeValue == null) {
                items.push("<li> document");
            }
            else if(/[a-z0-9]/i.test(node.nodeValue) && node.nodeValue != null) {
                items.push("<ul><li>"+ x +"</ul>");
            }
            else {
                items.push("</ul>");
            }
        }
    });
    $('#list').append(items.join(''));
});

function traverse(node, func) {
    func(node);
    node = node.firstChild;
    while (node) {
        traverse(node, func);
        node = node.nextSibling;
    }
}

它几乎完美地工作,除了它似乎将回车读作文本节点。例如,如果有

<head><title>

它正确读取,将head添加为无序列表元素,然后创建一个新的&#34;无序列表&#34;对于标题,它嵌套在标题内。但是,如果它是

<head>
    <title>

它生成新的无序列表及其元素&#34; head&#34;,然后跳转到执行items.push(</ul>)的else语句。如何让它忽略回车?我尝试测试以查看nodeValue是否等于回车符\ r,但这似乎没有做到这一点。

1 个答案:

答案 0 :(得分:0)

我很难确切地了解您要跳过哪些文本节点。如果您只想跳过只有空格的文本节点,可以这样做:

var onlyWhitespaceRegex = /^\s*$/;

traverse(document, function (node) { 
    if (node.nodeType === 3 && onlyWhitespaceRegex.test(node.nodeValue) {
        // skip text nodes that contain only whitespace
        return;
    }
    else if (node.nodeName.indexOf("#") <= -1){
        items.push("<ul>"+"<li>"+node.nodeName.toLowerCase());
    } else ...

或许,您可能只想在显示文本节点之前修剪任何多个前导或尾随空格,因为它可能不会以HTML格式显示。

var trimWhitespaceRegex = /^\s+|\s+$/g;

traverse(document, function (node) { 
    if(node.nodeName.indexOf("#") <= -1){
        items.push("<ul>"+"<li>"+node.nodeName.toLowerCase());
    } else {
        var text = node.nodeValue;
        if (node.nodeType === 3) {
            text = text.replace(trimWhitespaceRegex, " ");
        }
        var x = "text("+text+")";
        if(node.nodeValue == null) {
            items.push("<li> document");
        } ....

进一步描述您在各种形式的不同文本节点的输出中尝试实现的内容将有助于我们更好地了解您的要求。