基于菜单项的URL路径结构创建一个嵌套的UL菜单
Create a nested UL menu based on the URL path structure of menu items
我有一个菜单项数组,每个包含Name和URL,如下所示:
var menuItems = [
{
name : "Store",
url : "/store"
},
{
name : "Travel",
url : "/store/travel"
},
{
name : "Gardening",
url : "/store/gardening"
},
{
name : "Healthy Eating",
url : "/store/healthy-eating"
},
{
name : "Cook Books",
url : "/store/healthy-eating/cook-books"
},
{
name : "Single Meal Gifts",
url : "/store/healthy-eating/single-meal-gifts"
},
{
name : "Outdoor Recreation",
url : "/store/outdoor-recreation"
},
{
name : "Hiking",
url : "/store/outdoor-recreation/hiking"
},
{
name : "Snowshoeing",
url : "/store/outdoor-recreation/hiking/snowshoeing"
},
{
name : "Skiing",
url : "/store/outdoor-recreation/skiing"
},
{
name : "Physical Fitness",
url : "/store/physical-fitness"
},
{
name : "Provident Living",
url : "/store/provident-living"
}
]
我一直在尝试没有成功地将其呈现为一个无序列表,其中包含一个嵌套的UL结构,遵循URL路径结构,如下所示:
<ul>
<li><a href="/store">Store</a>
<ul>
<li><a href="/store/travel">Travel</a></li>
<li><a href="/store/gardening">Gardening</a></li>
<li><a href="/store/healthy-eating">Healthy Eating</a>
<ul>
<li><a href="/store/healthy-eating/cook-books">Cook Books</a></li>
<li><a href="/store/healthy-eating/single-meal-gifts">Single Meal Gifts</a></li>
</ul>
</li>
<li><a href="/store/outdoor-recreation">Outdoor Recreation</a>
<ul>
<li><a href="/store/outdoor-recreation/hiking">Hiking</a>
<ul>
<li><a href="/store/outdoor-recreation/hiking/snowshoeing">Snowshoeing</a></li>
</ul>
</li>
<li><a href="/store/outdoor-recreation/skiing">Skiing</a></li>
</ul>
</li>
<li><a href="/store/physical-fitness">Physical Fitness</a></li>
<li><a href="/store/provident-living">Provident Living</a></li>
</ul>
</li>
</ul>
我所见过的所有示例都以反映父子关系的数据结构开始(例如xml或JSON),但是我很难将其从URL中取出并使用它来呈现新结构。
如果有人可以引导我在正确的方向上如何使用jQuery做到这一点,我真的很感激。我意识到我可能需要使用一些递归函数或jQuery模板,但这些东西对我来说仍然有点新。
由于
我认为最好的解决方案是首先将数据结构转换为具有父/子关系的树结构。呈现这个结构会更容易,因为UL本身有一个树状结构。
您可以使用以下几个函数来转换菜单项
// Add an item node in the tree, at the right position
function addToTree( node, treeNodes ) {
// Check if the item node should inserted in a subnode
for ( var i=0; i<treeNodes.length; i++ ) {
var treeNode = treeNodes[i];
// "/store/travel".indexOf( '/store/' )
if ( node.url.indexOf( treeNode.url + '/' ) == 0 ) {
addToTree( node, treeNode.children );
// Item node was added, we can quit
return;
}
}
// Item node was not added to a subnode, so it's a sibling of these treeNodes
treeNodes.push({
name: node.name,
url: node.url,
children: []
});
}
//Create the item tree starting from menuItems
function createTree( nodes ) {
var tree = [];
for ( var i=0; i<nodes.length; i++ ) {
var node = nodes[i];
addToTree( node, tree );
}
return tree;
}
var menuItemsTree = createTree( menuItems );
console.log( menuItemsTree );
结果menuItemsTree将是一个像这样的对象
[
{
"name":"Store",
"url":"/store",
"children":[
{
"name":"Travel",
"url":"/store/travel",
"children":[
]
},
{
"name":"Gardening",
"url":"/store/gardening",
"children":[
]
},
{
"name":"Healthy Eating",
"url":"/store/healthy-eating",
"children":[
{
"name":"Cook Books",
"url":"/store/healthy-eating/cook-books",
"children":[
]
},
{
"name":"Single Meal Gifts",
"url":"/store/healthy-eating/single-meal-gifts",
"children":[
]
}
]
},
{
"name":"Outdoor Recreation",
"url":"/store/outdoor-recreation",
"children":[
{
"name":"Hiking",
"url":"/store/outdoor-recreation/hiking",
"children":[
{
"name":"Snowshoeing",
"url":"/store/outdoor-recreation/hiking/snowshoeing",
"children":[
]
}
]
},
{
"name":"Skiing",
"url":"/store/outdoor-recreation/skiing",
"children":[
]
}
]
},
{
"name":"Physical Fitness",
"url":"/store/physical-fitness",
"children":[
]
},
{
"name":"Provident Living",
"url":"/store/provident-living",
"children":[
]
}
]
}
]
你提到你已经有了树的html渲染器,对吗?如果您需要进一步的帮助,请告诉我们!
12行简单代码:
var rootList = $("<ul>").appendTo("body");
var elements = {};
$.each(menuItems, function() {
var parent = elements[this.url.substr(0, this.url.lastIndexOf("/"))];
var list = parent ? parent.next("ul") : rootList;
if (!list.length) {
list = $("<ul>").insertAfter(parent);
}
var item = $("<li>").appendTo(list);
$("<a>").attr("href", this.url).text(this.name).appendTo(item);
elements[this.url] = item;
});
http://jsfiddle.net/gilly3/CJKgp/虽然我喜欢gilly3的脚本,但脚本生成的<li>
和<ul>
的元素嵌套与最初要求的不同。所以不是
<li><a href="/store">Store</a>
<ul>
<li><a href="/store/travel">Travel</a></li>
...
</ul>
</li>
它产生
<li><a href="/store">Store</a>
</li>
<ul>
<li><a href="/store/travel">Travel</a></li>
...
</ul>
这可能会导致使用这种生成菜单和生成带有动画的交互式菜单(例如superfish.js)的实用程序或框架不兼容。所以我更新了12行脚本
var rootList = $("<ul>").appendTo("body");
var elements = {};
$.each(menuItems, function() {
var parent = elements[this.url.substr(0, this.url.lastIndexOf("/"))];
var list = parent ? parent.children("ul") : rootList;
if (!list.length) {
list = $("<ul>").appendTo(parent);
}
var item = $("<li>").appendTo(list);
$("<a>").attr("href", this.url).text(this.name).appendTo(item);
elements[this.url] = item;
});
http://jsfiddle.net/tomaton/NaU4E/它不在jQuery中,但这可能会有所帮助。我在网上寻找你想要的东西后开发了这个。
http://www.chapleau.info/article/ArrayofUrlsToASitemap.html或者完整的jQuery插件http://jsfiddle.net/9FGRC/
(编辑)先前版本的更新http://jsfiddle.net/9FGRC/1/
此版本支持以下大小写
var menuItems = [
{
name : "Store",
url : "/store"
},
{
name : "Cook Books",
url : "/store/healthy-eating/cook-books"
},
{
name : "Single Meal Gifts",
url : "/store/healthy-eating/single-meal-gifts"
}
]
因为有省略
{
name : "Healthy Eating",
url : "/store/healthy-eating"
},
它将生成以下html
<ul>
<li><a href="/store">Store</a>
<ul>
<li><a href="/store/healthy-eating/cook-books">Cook Books</a></li>
<li><a href="/store/healthy-eating/single-meal-gifts">Single Meal Gifts</a></li>
</ul>
</li>
</ul>
我想不会是这样的,但可能对某人有帮助
试试这样做。
function Directory(parentNode) {
//Structure for directories. Subdirectories container as a generic object, initially empty
this.hasSubdirectories = false;
this.subdirectories = {};
//Render in steps. Until subdirectories or a link are added, all it needs is an LI and a blank anchor
this.nodeLi = document.createElement("li");
parentNode.appendChild(this.nodeLi);
this.nodeA = document.createElement("a");
this.nodeLi.appendChild(this.nodeA);
//if a subdirectory is added, this.nodeUl will be added at the same time.
}
Directory.prototype.setLabel = function (sLabel) {
this.nodeA.innerHTML = sLabel;
}
Directory.prototype.setLink = function (sLink) {
this.nodeA.href = sLink;
}
Directory.prototype.getSubdirectory = function (sPath) {
//if there were no previous subdirectories, the directory needs a new UL node.
if (!this.hasSubdirectories) {
this.nodeUl = document.createElement("ul");
this.nodeLi.appendChild(this.nodeUl);
this.hasSubdirectories = true;
}
//split the path string into the base directory and the rest of the path.
var r = /^'/?(?:((?:'w|'s|'d)+)'/)(.*)$/;
var path = r.exec(sPath);
//if the desired path is in a subdirectory, find or create it in the subdirectories container.
var subDirName = path[1] || path[2];
var subDir;
if (this.subdirectories[subDirName] === undefined) this.subdirectories[subDirName] = new Directory(this.nodeUl);
subDir = this.subdirectories[subDirName];
if (path[1] && path[2]) {
return subDir.getSubdirectory(path[2]);
} else {
return subDir;
}
}
function main(whichNode, aMenuItems) {
//whichNode is the node that is to be the parent of the directory listing.
//aMenuItems is the array of menu items.
var i;
var l = aItems.length;
var topDir = new Directory(whichNode);
//for each menu item, add a directory and set its properties.
var dirToAdd;
for (i = 0; i < l; i++) {
dirToAdd = topDir.getSubdirectory(aMenuItems[i].url);
dirToAdd.setLabel(aMenuItems[i].name);
dirToAdd.setLink(aMenuItems[i].url);
}
//and that's it.
}
这是怎么回事?
相关文章:
- 每行中都有一个嵌套表的数据表
- 如果“上一个”为空,则清除下一个嵌套的选择标记
- 如何将嵌套模型与骨干表单列表一起使用?我想用自定义模板制作一个嵌套模型
- MongoDB/Mongoose:MarkModified一个嵌套对象
- Ember路由从一个嵌套对象转换到另一个
- Jquery以查找最后一个嵌套元素
- 如何使用Angular js把一个嵌套对象放入数据库中?
- 如何选择一个嵌套在td、类名和id名中的输入?
- 编写一个嵌套的for循环
- JS搜索通过一个嵌套的JSON结构,深度增加随着时间的推移
- Angularjs,等待一个嵌套的承诺
- 如何使用ExtJS读取一个嵌套的json文件
- 访问一个嵌套在一个带有聚合物的对象中的数组中的一个对象的值
- 角:$范围.$watch一个嵌套的集合
- Jquery数据表:如何创建一个嵌套的表数据
- js:设置一个属性,它的值是一个嵌套对象
- 我有一个嵌套if的函数.我怎样才能做出'这个'指向构造函数.父
- 我如何使用lodash过滤一个嵌套的值数组对象
- 如何测试Javascript对象在最后一个嵌套层是否只有空对象?
- 从Javascript数组创建一个嵌套对象