我在根据页面元素创建动态菜单时遇到了一些问题。如何从中创建一个菜单?:
<div class="parent">
<div class="one child" id="first"></div>
</div>
<div class="parent">
<div class="one child" id="second"></div>
</div>
<div class="parent">
<div class="one child" id="third"></div>
</div>
<div class="parent">
<div class="one child" id="fourth"></div>
<div class="one child" id="fifth"></div>
<div class="one child" id="sixth"></div>
<div class="one child" id="seventh"></div>
</div>
<div class="parent">
<div class="one child" id="eight"></div>
</div>
因此,我希望jquery能够像这样构建一个菜单结构:
<ul class="navigation">
<li><a href="#first"></a></li>
<li><a href="#second"></a></li>
<li><a href="#third"></a></li>
<li>
<ul class="sub-navigation">
<li><a href="#fourth"></a></li>
<li><a href="#fifth"></a></li>
<li><a href="#sixth"></a></li>
<li><a href="#seventh"></a></li>
</ul>
</li>
<li><a href="#eight"></a></li>
</ul>
这是我一直在干预的小提琴(我试图让它发挥作用):http://jsfiddle.net/rt9Pm/
在某个地方,我失去了我的焦点,我无法完成这个小涂鸦。
答案 0 :(得分:0)
var $parents = $('.parent'),
$ul = $('<ul>'),
$li = $('<li>'),
$a = $('<a>'),
$nav = $('<nav>'),
$navul = $ul.clone().attr('class', 'navigation');
$nav.append($navul);
$parents.each(function ea(){
var $parent = $(this),
$children = $parent.children('.one.child'),
$anchor = $a.clone(),
$subul,
id;
if ($children.length == 1) {
id = $children.attr('id');
$anchor
.attr('href', '#' + id)
.text($children.attr('id'));
$navul.append($li.clone().append($anchor));
} else if ($children.length > 1) {
$subul = $ul.clone().attr('class', 'sub-navigation');
$children.each(function ea(){
var $child = $(this),
$anchor = $a.clone(),
id = $child.attr('id');
$anchor
.attr('href', '#' + id)
.text($child.attr('id'));
$subul.append($li.clone().append($anchor));
});
$navul.append($subul);
}
});
$parents.filter(':eq(0)').before($nav);
答案 1 :(得分:0)
我有一段时间,并认为这可能对您有用:
(function($){
$.fn.createMenu = function (opts){
var s = $.extend({
'menuID' : 'menu',
'navigationID' : 'navigation',
'navigationClass' : 'navigation',
'attachTo' : 'body'
}, opts),
nav = $('<nav />', {
'id' : s.navigationID
}),
menu = $('<ul />', {
'id' : s.menuID
}),
textProp = 'textContent' in document.body ? 'textContent' : 'innerText',
ulWrap = document.createElement('ul'),
liWrap = document.createElement('li'),
aWrap = document.createElement('a'),
liTmp,aTmp,
// defining a function to create the li-wrapped links:
createLinks = function (el, par, prefix) {
// if the 'par' is a jQuery object we'll use that,
// otherwise we assume it's a DOM node and we wrap that with jQuery:
var parent = par instanceof jQuery ? par : $(par);
// cloning created elements rather than re-creating elements:
aTmp = aWrap.cloneNode();
// creating the 'href' to link to the id:
aTmp.href = '#' + el.id;
aTmp[textProp] = el.id;
liTmp = liWrap.cloneNode();
// appending the cloned a element to the li element:
liTmp.appendChild(aTmp);
// adding the appropriate class to the parent 'ul' element,
// and appending the 'li':
parent.addClass(('undefined' === typeof prefix ? '' : prefix) + s.navigationClass).append(liTmp);
};
// appending the 'menu' to the 'nav':
nav.append(menu);
// prepending the nav to the specified element (from the options/defaults):
nav.prependTo(s.attachTo);
// iterating over the elements matched by the selector:
this.each(function(i,e){
// using this twice, so caching:
var $e = $(e);
// if there are no siblings:
if ($e.siblings().length === 0) {
// we create the links:
createLinks(e, menu);
}
// if there are previous siblings we do nothing:
else if ($e.prev().length) {
// do nothing, this is inelegant
// but I couldn't think of a better way
}
else {
// there are siblings (this should only be matched by the first
// sibling of a group.
// clone a new 'li' and 'ul' element:
var li = liWrap.cloneNode(),
ul = ulWrap.cloneNode(),
// find all childNodes of the element's parent:
items = e.parentNode.childNodes;
// append the cloned 'ul' to the cloned 'li':
li.appendChild(ul);
// iterate over the childNodes:
for (var i = 0, len = items.length; i < len; i++) {
// if the node has a nodeType *and* that nodeType is exactly 1
// (therefore the node is an HTMLElement):
if (items[i].nodeType && items[i].nodeType === 1) {
// create links from those elements:
createLinks(items[i], ul, 'sub-');
}
}
// append the created 'li' (above, before the for loop) to the menu:
menu.append(li);
}
});
// I tend to return the created elements, jQuery often, however, returns
// the elements of the original selector (which would be 'return this'):
return nav;
};
})(jQuery);
$('.one').createMenu();
参考文献: