我正在开发一个导航系统,我希望家长ul
和所有孩子uls
的宽度达到100%,当您点击带有li
的{{1}}时父母向左滑动,孩子从右侧滑入。这是我到目前为止所做的:
ul
$(function() {
$('.list-container ul > li.has-child').each(function() {
$(this).find('ul').prepend('<li class="back">< Back</li>');
});
$(document).on('click', '.list-container ul > li', function(e) {
e.stopPropagation();
var children = $(this).find('ul');
if (!$(this).hasClass('back')) {
if (children.length > 0) {
$(this).parent().css('left','-100%');
$(this).find('ul > li').css('display','block');
$(this).find('ul').css('left','100%');
}
}
});
$(document).on('click','li.back', function(e) {
e.stopPropagation();
$(this).parent().parent().parent().css('left','0');
$(this).parent().css('left','200%');
});
});
html,body {
height:100%;
margin:0;
}
.list-container {
overflow:hidden;
width:100%;
}
ul {
width:100%;
list-style-type:none;
padding:0;
margin:0;
position:absolute;
transition: all 0.5s ease;
}
li {
padding:10px 0 10px 15px;
border-bottom:1px solid black;
}
li.has-child:after {
display:inline-block;
content:">";
float:right;
margin-right:15px;
}
li > ul {
display:block;
left:200%;
top:0;
}
li > ul > li {
display:none;
}
此代码按照预期用于第一级/第二级项目,但是一旦您尝试点击进入第3级(即“测试1子菜单”),它就会搞砸了。我现在意识到使用<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="list-container">
<ul>
<li class="has-child">Test 1
<ul>
<li class="has-child">Test 1 sub-menu
<ul>
<li>Test 1 sub-sub-menu</li>
</ul>
</li>
<li>Test 1 sub-menu a</li>
</ul>
</li>
<li class="has-child">Test 2
<ul>
<li>Test 2 sub-menu</li>
<li class="has-child">Test 2 sub-menu a
<ul>
<li>Test 2 sub-sub-menu</li>
</ul>
</li>
</ul>
</li>
<li class="has-child">Test 3
<ul>
<li>Test 3 sub-menu</li>
<li class="has-child">Test 3 sub-menu a
<ul>
<li>Test 3 sub-sub-menu</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
而不是divs
可能会更好,但是有人可以建议如何在不修改HTML结构的情况下使其工作吗?如果有更好的方法来完成此功能,请打开以完全更改jQuery / CSS。
答案 0 :(得分:1)
此代码适用于第一/第二级项目, 但是一旦你尝试点击进入第3级(即“测试1” 子菜单“)它搞砸了。
这是因为,您将ul
移动常数200%
,而子ul
移动常数+/-100%
。同时,您在ul
处重置了主0
。除此之外,当您使用显示块显示菜单时,您不会隐藏它们。虽然这适用于第一级,但它从第二级开始分离。
我现在意识到使用div可能会更好 这不是uls
是的,使用div
可能会更好一些,因为对于分层ul
来说,处理这些更容易。但是,ul
对于层次结构来说更具语义性。
如果您不想更改HTML结构,那么最简单和最好的选择是指定每个子菜单所在的level
。这可以通过简单地添加{{1}来完成每个data-
上包含更多子项的属性,您可以摆脱li
类。获得.has-child
属性中定义的级别后,您可以使用这些级别将每个级别移动相应的因子。
以下是粗略的演示。请注意,虽然您已使用data-
标记了此内容,但我使用普通的旧版vanila JavaScript创建了此演示,因为这对我来说更简单,更快捷。如果您愿意,可以将其转换为jQuery,但除此之外,这应该可以正常工作。
演示小提琴:https://jsfiddle.net/abhitalks/euLzo2dg/
演示代码段
jQuery
// keep things outside the global scope
(function (window, document) {
var attachTo = document.getElementsByClassName('list-container')[0];
prepareNav(attachTo); // attach nav to the div
function prepareNav(nav) {
// prepare nav by creating back links, setting styles, and click handler
var
navBar = nav.firstElementChild,
navElems = nav.querySelectorAll('li[data-level] > ul')
;
for (i=0; i < navElems.length; i++) {
var backLink = document.createElement('li');
backLink.className = 'back';
backLink.textContent = '\u3008' + ' Back';
navElems[i].insertBefore(backLink, navElems[i].firstElementChild);
}
navBar.style.left = '0%';
nav.addEventListener('click', function(e) {
startNav(e, navBar, navElems);
}, false);
}
function startNav(e, navBar, navElems) {
// click handler
if (e.target.dataset && e.target.dataset.level) {
// move main ul by negative multiples of level
navBar.style.left = -(e.target.dataset.level * 100) + '%';
// reset all menus by hiding those
[].forEach.call(navElems, function(ne) { ne.classList.remove('show'); });
// show the parent menu
e.target.parentNode.classList.add('show');
// show the current menu
e.target.firstElementChild.classList.add('show');
}
if (e.target.className === 'back') {
// move back the main ul by 100 (not to 100)
var leftPos = parseInt(navBar.style.left);
navBar.style.left = (leftPos + 100) + '%';
}
}
})(window, document);
* { box-sizing: border-box; margin: 0; padding: 0; font-family: sans-serif; }
html, body { height:100%; }
.list-container {
overflow: hidden; position: relative;
width: 100%; min-height: 128px;
}
.list-container ul {
width: 100%; background-color: #eee;
list-style-type: none;
position: absolute; left: 0%; top: 0%;
transition: all .5s ease;
}
.list-container li {
padding: 10px 0 10px 15px;
cursor: pointer; border: 1px solid #aaa;
}
.list-container li:first-child { border-bottom: none; }
.list-container li:last-child { border-top: none; }
.list-container li.back + li:last-child { border-top: 1px solid #aaa; }
.list-container li[data-level]::after {
display: inline-block; content: '\003009';
float: right; margin-right: 15px;
}
.list-container li[data-level]:hover,
.list-container li.back:hover { background-color: #ddd; }
.list-container li[data-level] > ul { left: 100%; top: 0; display: none; }
.list-container li[data-level] > ul.show { display: block; }