jQuery 树遍历 - 将无序列表元素嵌套到 JSON
Posted
技术标签:
【中文标题】jQuery 树遍历 - 将无序列表元素嵌套到 JSON【英文标题】:jQuery tree traversal - Nested Unordered list elements to JSON 【发布时间】:2010-07-03 20:22:12 【问题描述】:好的,现在我这里有一个无序列表:
<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实体上
我上面的列表的 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 解决方案: Traversing unordered lists using javascript/Jquery
^ 这可能有效,但我需要的 JSON 输出格式如上所示,而不是此脚本输出的格式:(
其他参考资料:
How do I put unordered list items into an array
https://jsfiddle.net/yS6ZJ/1/
https://jsfiddle.net/CLLts/
https://jsfiddle.net/cWnwt/
请大家帮忙:( 很多个不眠之夜都让我头疼..(P.s - 我花了大约 40 多分钟的时间来编写整个页面以及代码)
【问题讨论】:
正在处理它。顺便说一句,您生成的 JSON 是一个对象数组,因此您应该有周围的 [ 和 ] 括号。[ , , ]
谢谢 Samuel,但我的应用程序似乎使用了无效的 JSON,并且它使用了上述格式 :) 感谢您的输入 :)
【参考方案1】:
啊,一个有趣的小递归练习。我有一点时间,这就是我将如何做到的。这可以递归地工作很多层次,但假设您的数据不够深而无法爆炸内存(如果太深,浏览器中的递归会中断)。至少10级左右应该没问题。
我已经测试过了,似乎它可以工作,只需将它保存在 html 文件中就可以了。
抱歉,没有太多的 cmets(嗯,从技术上讲,根本没有 :),这假设您可以很好地阅读 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>
【讨论】:
抱歉,Jaanus,我不在办公桌前。非常感谢您的努力,您提供的代码简直完美无缺,您是我变相的祝福,您为我省去了很多头痛!非常感谢!!! :) 你也应该标记接受的答案,无论你接受哪个,成为一个好的 *** 公民:) 但是,它没有以我的格式输出 JSON?例如,我在属性上有引号,例如:“name”:“something”“title”:“something”相反,我需要它像name:“something”title:“something”谢谢 JSON 标准规定对象键必须用双引号括起来。我正在使用 Douglas Crockford 的标准 JSON 输出器,这是将 Javascript 对象转换为 JSON 字符串的行业标准。因此,您要求的是非标准的无效 JSON。为什么需要它? 1) 不用担心,我们曾经都是新手 :) 2) 我明白你的意思。像 JSON 这样的标准的要点是应用程序以标准方式输入和输出它。正确的做法是修复您的应用程序,使其接受标准的有效 JSON。如果那不可能,您也许可以让 tvanfonsson 的代码工作。您可以看到它如何将自定义 JSON 输出为字符串,并且您可以修改它来生成您需要的内容。但实际上,您应该修复这个其他应用程序。还有其他方法,但它们确实是倒退的坏习惯。【参考方案2】:似乎使用一个函数用于列表元素(子)集合和一个用于列表元素的递归解决方案将起作用。请注意,我假设您希望将其格式化为字符串,并且它实际上表示为数组。
$(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, '\\\"' );
【讨论】:
这会输出无效的 JSON,因为:1) 你没有引用属性值 2) 你没有转义字符串中的 ' 或 " 字符,你会引用属性值。否则很好。跨度> @Jaanus -- 是的,只是一个快速的答案并且完全未经测试。我在属性周围添加了引号,并在字符串中引用了引号。 你现在的做法,你可能会得到太多的引用..不确定是否必须在 JSON "blah ' blah" 字符串中引用 ' ? :) @Jaanus -- 可能是对的,只需要引用双引号。不过我不认为它会受到伤害。 @tv - 我检查了 JSON 标准和 Doug Crockford 的 JSON stringifier。 JSON 标准明确讨论了双引号,因此双引号是唯一需要在字符串中转义的引号,而不是单引号。会很痛,因为输出中会有额外的反斜杠字符。【参考方案3】:以下源代码是我的解决方案。我认为已经足够清楚地展示了将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>
【讨论】:
以上是关于jQuery 树遍历 - 将无序列表元素嵌套到 JSON的主要内容,如果未能解决你的问题,请参考以下文章
jQuery - live() 不能与附加 div 中的 next() 一起使用