我必须实现一种在页面顶部调用水平导航栏的设计。此导航栏中可能包含未知数量的项目。如果酒吧用完房间,超限的链接将填入“更多”下拉列表。
视觉:
|page |
|nav item 1 nav item 2 nav item 3 MORE v |
| |
在“更多”内,将有“导航项目4”和“导航项目5”。它会随屏幕尺寸而变化。
我的想法是使用JavaScript一次将链接移动到下拉列表,直到导航栏的边界框是可接受的大小。然而,随着屏幕闪烁和跨浏览器JS问题,这个想法让我成为一个悲伤的熊猫。有没有更好的办法?如果你遇到过这种事情的框架或纯粹的基于CSS的解决方案,或者不像我的想法那么严重的话,请告诉我。
与此同时,我会试着说服权力人士只使用下拉菜单,而不是在屏幕上出现不一致的情况。
答案 0 :(得分:4)
http://jsfiddle.net/mblase75/cM7sU/
我知道你没有要求jQuery,但它使代码变得更短。但是,如果没有它,就没有任何东西可以做到。
您可以看到代码如何工作,希望 - 在菜单中向后循环,看看最后一项的垂直偏移是否与第一项的垂直偏移不同。如果是这样,将其推送到“更多”下拉菜单并继续循环;如果没有,突破循环。它包含在一个与window.resize
事件和document.ready
事件相关联的函数中。
显然,从功能方面来说,这段代码中有很多缺失,但它应该让你开始。
function shorterMenu() {
$('#moreitems').children().unwrap().first().remove();
$items = $('#menu div');
$more = $('<div id="moreitems" class="menuitem"></div>');
for (var i = $items.length; i--;) {
$this = $items.eq(i);
if ($this.offset().top > $items.eq(0).offset().top || $more.offset().top > $items.eq(0).offset().top) {
$('#menu').append($more);
$more.prepend($this);
} else {
i = 0; // end for
}
}
if ($more.children().length) {
$more.prepend('<div id="more" class="menuitem">More</div>');
}
}
$(document).ready(shorterMenu);
$(window).resize(shorterMenu);
答案 1 :(得分:0)
对于任何需要它的人,我已使用香草javascript https://jsfiddle.net/xobea9cm/
从@Blazemonger重写了此方法的原始Jquery解决方案。const parser = new DOMParser()
function dealWithMenu(menu) {
let $items = menu.querySelectorAll('div')
let $more = parser.parseFromString('<div class="more-items"></div>',
'text/html').body.firstChild
for (var i = $items.length; i--;) {
let $this = $items[i]
if ($this.offsetTop > ($items[0]).offsetTop || $more.offsetTop > ($items[0]).offsetTop) {
menu.appendChild($more)
$more.insertBefore($this, $more.firstChild)
} else {
i = 0
}
}
if ($more.children.length) {
$more.insertBefore(
parser.parseFromString('<div id="more" class="more-item menuitem">More</div>', 'text/html').body.firstChild,
$more.firstChild)
}
}
function shorterMenu() {
const moreItems = document.querySelector('.more-items')
const moreDivs = Array.from(document.querySelectorAll('.more-item'))
moreDivs.forEach(moreDiv => moreDiv.remove())
if (moreItems != undefined && moreItems.children && moreItems.children.length > 0) {
Array.from(moreItems.children).forEach(child => moreItems.parentElement.appendChild(child))
moreItems.remove()
}
const menus = Array.from(document.querySelectorAll('.menu'))
menus.forEach(dealWithMenu)
}
let throttled = false
const delay = 100
shorterMenu()
window.addEventListener('resize', () => shorterMenu())
答案 2 :(得分:-1)
如果您需要更多的灵活性并且担心跨浏览器支持,那么这可以完全在css(google css下拉菜单中找到很多教程)中完成,然后Jquery可以很好地处理这类事情。
希望有所帮助。