jQuery 树遍历 - 将无序列表元素嵌套到 JSON

发布于 2024-09-07 22:55:19 字数 3211 浏览 4 评论 0原文

好的,现在我这里有一个无序列表:

<ul id="mycustomid">
    <li><a href="url of Item A" title="sometitle">Item A</a>
        <ul class="children">
           <li><a href="url of Child1 of A" title="sometitle">Child1 of A</a>
               <ul class="children">
                 <li><a href="url of Grandchild of A" title="sometitle">Grandchild of A</a>
                    <ul class="children">
                       <li><a href="url of Grand Grand child of A" title="sometitle">Grand Grand child of A</a></li>
                    </ul>
                </li>
               </ul>
           </li>
        </ul>
    </li>
    <li><a href="url of Item B" title="sometitle">Item B</a></li>
    <li><a href="url of Item C" title="sometitle">Item C</a></li>
</ul>

基本上,我只想将此数据转换为 JSON 实体。我想在 jQuery 中完成这项工作,但我认为我很难做到这一点。上面的列表只是一个例子,实际上,我的列表理想情况下应该有更多数量的孩子,并且可能有“n”层深(意思是,它将有孙子的孙子的孙子的孙子的孙子……或更多)我已经失去了无数我为此睡了几个小时,我认为我不会去任何地方:(

我想提取这些内容:锚点内的文本、锚点的 url 和锚点的标题,并将它们放入 JSON 实体

< strong>上面列表的 JSON 格式是这样的:

{
        name: "Item A",
        url: "url of Item A",
        title: "sometitle",
        children: [{
                   name: "Child1 of A",
                   url: "url of Child1 of A",
                   title: "sometitle",
                   children: [{
                                name: "Grandchild of A",
                                url: "url of Grandchild of A",
                                title: "sometitle",
                                children: [{
                                           name: "Grand Grand child of A",
                                           url: "url of Grand Grand child of A",
                                           title: "sometitle",
                                           children: []
                                           }]
                              }]
                   }]
},
           {
            name: "Item B",
            url: "url of Item B",
            title: "sometitle",
            children: []
           },
           {
            name: "Item C",
            url: "url of Item C",
            title: "sometitle",
            children: []
           }

一些有用的参考:

Javascript 解决方案: 使用 Javascript/Jquery 遍历无序列表

^ 这可能有效,但格式我需要的 JSON 输出如上所示,而不是此脚本输出的内容:(

其他参考:

如何将无序列表项放入数组

https://jsfiddle.net/yS6ZJ/1/

https://jsfiddle. net/CLLts/

https://jsfiddle.net/cWnwt/

有人请帮忙:(
很多个不眠之夜让我伤透了脑筋..(Ps - 我花了大约 40 多分钟才写下整个页面和代码)

Okay, Now I have an unordered list here:

<ul id="mycustomid">
    <li><a href="url of Item A" title="sometitle">Item A</a>
        <ul class="children">
           <li><a href="url of Child1 of A" title="sometitle">Child1 of A</a>
               <ul class="children">
                 <li><a href="url of Grandchild of A" title="sometitle">Grandchild of A</a>
                    <ul class="children">
                       <li><a href="url of Grand Grand child of A" title="sometitle">Grand Grand child of A</a></li>
                    </ul>
                </li>
               </ul>
           </li>
        </ul>
    </li>
    <li><a href="url of Item B" title="sometitle">Item B</a></li>
    <li><a href="url of Item C" title="sometitle">Item C</a></li>
</ul>

Basically, I want to just convert this data into a JSON entity. I want to get this done in jQuery and I think I'm having a really tough time doing it. The above list is just an example and in reality, my list would ideally have more number of children and probably be 'n' levels deep (Meaning, it will have grandchildren of grandchildren of grandchildren...or more) I've lost countless hours of sleep on this and I don't think I'm going anywhere :(

I want to extract these things: The text inside the anchor, the url of the anchor and the title of the anchor and put them onto a JSON entity

The JSON format for my list above is something like this:

{
        name: "Item A",
        url: "url of Item A",
        title: "sometitle",
        children: [{
                   name: "Child1 of A",
                   url: "url of Child1 of A",
                   title: "sometitle",
                   children: [{
                                name: "Grandchild of A",
                                url: "url of Grandchild of A",
                                title: "sometitle",
                                children: [{
                                           name: "Grand Grand child of A",
                                           url: "url of Grand Grand child of A",
                                           title: "sometitle",
                                           children: []
                                           }]
                              }]
                   }]
},
           {
            name: "Item B",
            url: "url of Item B",
            title: "sometitle",
            children: []
           },
           {
            name: "Item C",
            url: "url of Item C",
            title: "sometitle",
            children: []
           }

Some useful references:

Javascript solution:
Traversing unordered lists using Javascript/Jquery

^ This one probably works, but the format of the JSON output I need is as shown above and not what this script outputs :(

Other references:

How do I put unordered list items into an array

https://jsfiddle.net/yS6ZJ/1/

https://jsfiddle.net/CLLts/

https://jsfiddle.net/cWnwt/

Someone please help :(
Been breaking my head for many many sleepless nights..(P.s - It took me about 40+ mins to write this entire page along with the code)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

鱼窥荷 2024-09-14 22:55:19

啊,一个有趣的小递归练习。我有一个时间来做这件事,这就是我将如何做的。这可以递归地进行很多级别的深度工作,但假设您的数据不够深,不足以爆炸内存(如果太深,浏览器中的递归会中断)。至少10级左右应该没问题。

我对此进行了测试,似乎可行,只需将其保存在 HTML 文件中就可以了。

抱歉,没有太多评论(好吧,从技术上讲,根本没有:),这假设您可以很好地阅读 jQuery 和 JS 代码。如果您有疑问,请在评论中提问,我很乐意解释。

<!DOCTYPE HTML>
<html>
<head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <title>Recursive list processor example</title>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
    <script type="text/javascript">

$(document).ready(function() {

    var out = [];

    function processOneLi(node) {       

        var aNode = node.children("a:first");
        var retVal = {
            "title": aNode.attr("title"),
            "url": aNode.attr("href"),
            "name": aNode.text()
        };

        node.find("> .children > li").each(function() {
            if (!retVal.hasOwnProperty("children")) {
                retVal.children = [];
            }
            retVal.children.push(processOneLi($(this)));
        });

        return retVal;
    }

    $("#mycustomid").children("li").each(function() {
        out.push(processOneLi($(this)));
    });


    console.log("got the following JSON from your HTML:", JSON.stringify(out));

});

    </script>
</head>
<body>
<ul id="mycustomid">
    <li><a href="http://example.com/urlOfItemA" title="sometitle">Item A</a>
        <ul class="children">
           <li><a href="http://example.com/urlOfItemAChild1" title="sometitle">Child1 of A</a>
               <ul class="children">
                 <li><a href="http://example.com/urlOfItemAGrandchild" title="sometitle">Grandchild of A</a>
                    <ul class="children">
                       <li><a href="http://example.com/urlOfItemAGrandGrandChild" title="sometitle">Grand Grand child of A</a></li>
                    </ul>
                </li>
               </ul>
           </li>
        </ul>
    </li>
    <li><a href="http://example.com/urlOfItemB" title="sometitle2">Item '"" B</a></li>
    <li><a href="http://example.com/urlOfItemC" title="sometitle3">Item C</a></li>
</ul>
</body>
</html>

Ah, a fun little recursive exercise. I had a moment for this and here’s how I would do it. This works many levels deep recursively, but assumes that your data is not deep enough to explode the memory (recursion breaks in browsers if it is too deep). Should be fine for at least 10 levels or so.

I tested this out, seems it works, just save this in a HTML file and you should be fine.

Sorry there are not too many comments (well, technically speaking, none at all :) , this assumes you read jQuery and JS code fine. If you have questions, just ask in a comment and I’d be happy to explain.

<!DOCTYPE HTML>
<html>
<head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <title>Recursive list processor example</title>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
    <script type="text/javascript">

$(document).ready(function() {

    var out = [];

    function processOneLi(node) {       

        var aNode = node.children("a:first");
        var retVal = {
            "title": aNode.attr("title"),
            "url": aNode.attr("href"),
            "name": aNode.text()
        };

        node.find("> .children > li").each(function() {
            if (!retVal.hasOwnProperty("children")) {
                retVal.children = [];
            }
            retVal.children.push(processOneLi($(this)));
        });

        return retVal;
    }

    $("#mycustomid").children("li").each(function() {
        out.push(processOneLi($(this)));
    });


    console.log("got the following JSON from your HTML:", JSON.stringify(out));

});

    </script>
</head>
<body>
<ul id="mycustomid">
    <li><a href="http://example.com/urlOfItemA" title="sometitle">Item A</a>
        <ul class="children">
           <li><a href="http://example.com/urlOfItemAChild1" title="sometitle">Child1 of A</a>
               <ul class="children">
                 <li><a href="http://example.com/urlOfItemAGrandchild" title="sometitle">Grandchild of A</a>
                    <ul class="children">
                       <li><a href="http://example.com/urlOfItemAGrandGrandChild" title="sometitle">Grand Grand child of A</a></li>
                    </ul>
                </li>
               </ul>
           </li>
        </ul>
    </li>
    <li><a href="http://example.com/urlOfItemB" title="sometitle2">Item '"" B</a></li>
    <li><a href="http://example.com/urlOfItemC" title="sometitle3">Item C</a></li>
</ul>
</body>
</html>
桜花祭 2024-09-14 22:55:19

似乎一种递归解决方案可以使用一个函数用于列表元素(子元素)的集合,另一个函数用于列表元素。注意我假设您希望将其格式化为字符串并且它实际上表示为数组。

$(function() {
    var json = formatListElements( $('#mycustomid > li') );
});

function formatListElements( elems )
{
    var contents = [] 
    $.each( elems, function( index, elem ) {
        contents[index] = formatListElement( elem );
    }
    return '[' + contents.join(', ') + ']';
}

function formatListElement( elem )
{
   var anchor = $(elem).children('a:first');
   return '{ "name": "' + quote( anchor.text() )
                + '", "url": "' + quote( anchor.attr('href') )
                + '", "title": "' + quote( anchor.attr('title') )
                + '", "children": ' + formatListElements( $(elem).find('> ul > li')
        + '}';
}

function quote( str )
{
    return str.replace( /"/g, '\\\"' );
}

Seems like a recursive solution using one function for collections of list elements (children) and one for a list element would work. Note I'm assuming that you want it formatted as a string and that it's really represented as an array.

$(function() {
    var json = formatListElements( $('#mycustomid > li') );
});

function formatListElements( elems )
{
    var contents = [] 
    $.each( elems, function( index, elem ) {
        contents[index] = formatListElement( elem );
    }
    return '[' + contents.join(', ') + ']';
}

function formatListElement( elem )
{
   var anchor = $(elem).children('a:first');
   return '{ "name": "' + quote( anchor.text() )
                + '", "url": "' + quote( anchor.attr('href') )
                + '", "title": "' + quote( anchor.attr('title') )
                + '", "children": ' + formatListElements( $(elem).find('> ul > li')
        + '}';
}

function quote( str )
{
    return str.replace( /"/g, '\\\"' );
}
眉目亦如画i 2024-09-14 22:55:19

以下源代码是我的解决方案。我认为它已经足够清楚地展示了将 ul 转换为 json 对象的原理。祝你好运 :)

$(function() {

  function buildJSON($li) {
    var subObj = { "name": $li.contents().eq(0).text().trim() };
    $li.children('ul').children().each(function() {
      if (!subObj.children) { subObj.children = []; }
      subObj.children.push(buildJSON($(this)));
    });
    return subObj;
  }
    
  var obj = buildJSON($("#ul-data").children());
  $('body').append('<pre>').find('pre').append(JSON.stringify(obj, null, 2));

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="ul-data">
  <li><a href="#">AAA</a>
    <ul>
      <li><a href="#">DDD</a>
        <ul>
          <li><a href="#">EEE</a>
            <ul>
              <li><a href="#">FFF</a></li>
            </ul>
          </li>
        </ul>
      </li>
      <li><a href="#">BBB</a></li>
      <li><a href="#">CCC</a></li>
    </ul>
  </li>
</ul>

The following source code is my solution. I think it's clear enough to show the principle to covert ul to json object. Good Luck :)

$(function() {

  function buildJSON($li) {
    var subObj = { "name": $li.contents().eq(0).text().trim() };
    $li.children('ul').children().each(function() {
      if (!subObj.children) { subObj.children = []; }
      subObj.children.push(buildJSON($(this)));
    });
    return subObj;
  }
    
  var obj = buildJSON($("#ul-data").children());
  $('body').append('<pre>').find('pre').append(JSON.stringify(obj, null, 2));

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="ul-data">
  <li><a href="#">AAA</a>
    <ul>
      <li><a href="#">DDD</a>
        <ul>
          <li><a href="#">EEE</a>
            <ul>
              <li><a href="#">FFF</a></li>
            </ul>
          </li>
        </ul>
      </li>
      <li><a href="#">BBB</a></li>
      <li><a href="#">CCC</a></li>
    </ul>
  </li>
</ul>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文