"False" 导致问题的文本节点

"False" text node causing trouble

我正在研究 DOM 遍历类型的脚本,我快完成了。但是,我遇到了一个问题,在我的一生中,我不知道该怎么做才能解决它。请原谅我的无能,因为我是 JS/JQuery 的新手,而且我还在学习技巧。

基本上,我使用 Javascript/JQuery 创建一个 "outline",表示 HTML 页面的结构,并将 "outline" 附加到页面的底部网页。例如,如果 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;
    }
}

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

<head><title>

它读取正确,将 head 添加为无序列表元素,然后为嵌套在 header 中的标题创建新的 "unordered list"。但是,如果它是

<head>
    <title>

它生成新的无序列表及其元素 "head",但随后跳转到执行 items.push(</ul>) 的 else 语句。我如何让它忽略回车return?我试着测试一下 nodeValue 是否等于回车 return, \r,但这似乎没有用。

我很难理解您要跳过哪些文本节点。如果你只是想跳过一个只有空格的文本节点,你可以这样做:

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 ...

或者,也许您只想 trim 在显示文本节点之前从文本节点中删除任何多个前导或尾随空格,因为它可能不会在 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");
        } ....

进一步描述您在各种形式的不同文本节点的输出中究竟要实现什么,将有助于我们更好地理解您的要求。