javascript - 将无序列表转换为 JSON

标签 javascript json

我正在尝试从 Javascript 中的 UL 元素构建一个 JSON 对象。

我有这个列表结构:

<ul id="trainingmenu">
    <li class="tmnode"><span id="M5lx9n" class="tmname">menu 1</span>
        <ul>
            <li class="tmnode"><span id="M66p48" class="tmname">menu 2</span>
                <ul>
                    <li class="tmnode"><span class="tmname" id="Mschr">menu 3</span>
                    </li>
                </ul>
            </li>
            <li class="tmnode"><span id="Mu03e0" class="tmname">menu 4</span></li>
        </ul>
    </li>
</ul>

这是 JS:

var treeObject = {};

    function treeHTML(element, object) {
        if (element.tagName=="UL") { element=element.firstChild; }
        object["id"] = element.firstChild.id;
        object["name"] = element.firstChild.innerHTML;
        var nodeList = element.getElementsByTagName('LI');
        if (nodeList[0]) {
            object["nodes"] = [];
            for (var i = 0; i < nodeList.length; i++) {
                object["nodes"].push({});
                treeHTML(nodeList[i], object["nodes"][object["nodes"].length - 1]);
            }
        }
    }
    treeHTML(document.getElementById("trainingmenu"), treeObject);
    alert(JSON.stringify(treeObject));

..这是我得到的输出:

{"id":"M5lx9n","name":"menu 1","nodes":[{"id":"M66p48","name":"menu 2","nodes":[{"id":"Mschr","name":"menu 3"}]},{"id":"Mschr","name":"menu 3"},{"id":"Mu03e0","name":"menu 4"}]}

这是部分工作,这是我想要的格式 - 从每个 LI 元素的 childNode 中挑选出 id 和 name 字段。但它是重复节点 - 菜单 3 出现两次

这是一个 fiddle

我可能搞砸了递归,但盯着它看了 2 天还没有搞清楚是怎么回事。谁能帮忙?

最佳答案

正如 Alnitak 提到的,您应该使用 .children.childNodes 属性而不是 .getElementsByTagName() 方法。以下代码段使用 Array 原型(prototype)的 .filter() 方法过滤 ul 子级,并使用 .forEach() 进行迭代。

function treeHTML(element) {
    var o = {};
    o.id = element.firstElementChild.id; 
    o.name = element.firstElementChild.innerHTML;
    o.nodes = []; 
    [].slice.call(element.children).filter(function(e) {
        return e.tagName.toLowerCase() === 'ul';
    }).forEach(function(ul) {
        [].slice.call(ul.children).forEach(function(li) {
           o.nodes.push(treeHTML(li));
        });
    });
    return o;    
}
var treeObj = treeHTML(document.getElementById("trainingmenu")
                               .firstElementChild);

这是一个替代解决方案,它也应该适用于旧版本的 IE:

function children(node, selector) {
    var res = [], nodes = node.childNodes, l = nodes.length;
    for (var i = 0; i < l; i++) {
        if (nodes[i].nodeType === 1) {
            if (selector && nodes[i].tagName.toLowerCase() === selector) {
               res.push(nodes[i]);   
            } else if (!selector) {
               res.push(nodes[i]);
            }  
        }
    }
    return res;
}

function treeHTML(element) {
    var o = {};
    var span = children(element, 'span');
    o.id = span[0].id; 
    o.name = span[0].innerHTML;
    o.nodes = []; 
    var ul = children(element, 'ul'), n = ul.length;
    for (var i = 0; i < n; i++) {
        var li = children(ul[i]), l = li.length;
        for (var j = 0; j < l; j++) {
           o.nodes.push(treeHTML(li[j]));
        }
    }

    return o;    
}

var root = document.getElementById("trainingmenu");
var treeObj = treeHTML(children(root)[0]);

http://jsfiddle.net/XZ54G/

关于javascript - 将无序列表转换为 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21041226/

相关文章:

javascript - 如何在纯javascript中点击时获取li元素内的文本

json - 是否有用于从一张表中读取行的 RESTful Google Sheets API?

javascript - Angular http响应长度未定义

javascript - React 16.4 支持从状态更改调用 getDerivedStateFromProps。如何应对?

javascript - 在网站中处理 SQL 响应的位置

javascript - 如何创建 for 循环以从 JSON 数组中获取数据

Android JsonObject 到数组示例

iphone - 有人有使用 YAJL 的 Objective-C 绑定(bind)的经验吗?

javascript - Json请求未正确执行

javascript - 如何使用 AngularJS 将 list 中的值存储为对象中的数组?