问题描述
我想你快到了…
您实际上应该只对宽度所涉及的计算感兴趣。如果下拉元素的宽度和该元素的偏移量大于容器的宽度,则需要切换菜单。
$(function () {
$(".dropdown li").on('mouseenter mouseleave', function (e) {
if ($('ul', this).length) {
var elm = $('ul:first', this);
var off = elm.offset();
var l = off.left;
var w = elm.width();
var docH = $(".container").height();
var docW = $(".container").width();
var isEntirelyVisible = (l + w <= docW);
if (!isEntirelyVisible) {
$(this).addClass('edge');
} else {
$(this).removeClass('edge');
}
}
});
});
解决方法
我已经有了典型的下拉导航,并且试图确保下拉菜单链接始终可访问和可见:
<li><a href="#">Link 1</a>
<ul>
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
<li><a href="#">Link 3</a></li>
</ul>
</li>
<li><a href="#">Link 2</a>
<ul>
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
<li><a href="#">Link 3</a></li>
</ul>
</li>
<!-- etc. -->
</ul>
CSS确实没有什么特别的(删除了颜色和背景):
.dropdown,.dropdown li,.dropdown ul {
list-style:none;
margin:0;
padding:0;
}
.dropdown {
position:relative;
z-index:10000;
float:left;
width:100%;
}
.dropdown ul {
position:absolute;
top:100%;
visibility:hidden;
display:none;
width:16em;
}
.dropdown ul ul {
top:0;
left:100%;
}
.dropdown li {
position:relative;
float:left;
}
.dropdown li:hover{
z-index:910;
}
.dropdown ul:hover,.dropdown li:hover > ul,.dropdown a:hover + ul,.dropdown a:focus + ul {
visibility:visible;
display:block;
}
.dropdown a {
display:block;
padding:1em 2em;
}
.dropdown ul li {
width:100%;
}
顶级链接数量未知(由用户创建)。我遇到的问题是,如果顶层链接距离右侧太远,有时下拉菜单(位于右侧)将不在屏幕上。我添加了以下CSS来补偿:
.dropdown > li:last-child ul { /* ...or use a class on the last link for IE */
right:0;
}
现在,最后一个位于屏幕左侧,而不是离开屏幕,这很不错,但是存在一些问题:
- 对于上一个链接,我并不总是需要这些样式,因为它并不总是在屏幕的边缘(例如,只有3个链接)。
- 调整浏览器窗口的大小后,链接堆栈会彼此重叠(通过设计)。有时,序列中间的链接最终会出现在右侧,并且其下拉菜单会被切断。
- 有时,“倒数第二个”链接的菜单也会超出边界。
调整此演示中的面板大小,以了解我的意思 (红色区域被视为“屏幕外”)
多年来,我一直在努力解决这个令人讨厌的常见问题,但从未找到令人满意的解决方案。有什么方法可以检查下拉菜单是否会退出屏幕,如果可以,添加/删除class
名称或其他名称,以便可以使用CSS在屏幕上显示?
我可能会使用的一个提示是,如果菜单 确实
不在屏幕上,它将始终在窗口底部产生一个垂直滚动条,但是我不确定如何使用该知识。对于有关检测垂直滚动条的[问题,]我尝试了接受的答案,但是由于某种原因,它始终会返回true
,并始终添加“
edge”类(也许在计时方面存在问题?):
$(".dropdown li").on('mouseenter mouseleave',function (e) {
// Get the computed style of the body element
var cStyle = document.body.currentStyle||window.getComputedStyle(document.body,"");
// Check the overflow and overflowY properties for "auto" and "visible" values
hasVScroll = cStyle.overflow == "visible"
|| cStyle.overflowY == "visible"
|| (hasVScroll && cStyle.overflow == "auto")
|| (hasVScroll && cStyle.overflowY == "auto");
if (hasVScroll) {
$(this).addClass('edge');
} else {
$(this).removeClass('edge');
}
});
使用javascript进行演示:http :
//jsfiddle.net/G7qfq/2/
真的,我什至不希望看到一瞬间的垂直滚动条,所以我不确定那是要走的路,再加上可能会出现误报(滚动条由于其他原因)。
- 我在这个答案中也尝试了该解决方案,但我对此不太了解,因此无法正常工作:http
-
//jsfiddle.net/G7qfq/3/
$(“.dropdown li”).on(‘mouseenter mouseleave’,function (e) {
var elm = $('ul:first',this); var off = elm .offset(); var t = off.top; var l = off.left; var h = elm.height(); var w = elm.width(); var docH = $(window).height(); var docW = $(window).width(); var isEntirelyVisible = (t > 0 && l > 0 && t + h < docH && l+ w < docW); if ( ! isEntirelyVisible ) { $(this).addClass('edge'); } else { $(this).removeClass('edge'); }
});
我认为该解决方案需要javascript,并且我正在使用jQuery,但是我不知道如何解决该问题。有任何想法吗?