检测下拉导航是否会关闭屏幕并重新定位 [英] Detect if dropdown navigation would go off screen and reposition it

查看:100
本文介绍了检测下拉导航是否会关闭屏幕并重新定位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有您典型的下拉导航,我想确保下拉菜单链接始终可访问和可见:

I've got your typical dropdown navigation, and I'm trying to make sure the drop menu links are always accessible and visible:

<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确实没有什么特别的(删除了颜色和背景):

The CSS really isn't anything special (colors and backgrounds removed):

.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来补偿:

There are an unknown number of top level links (they are created by the user). The problem I'm having is that sometimes the drop menus (which go to the right) will go off screen if the top level link is too far to the right. I added this bit of CSS to compensate:

.dropdown > li:last-child ul { /* ...or use a class on the last link for IE */
    right:0;
}

现在最后一个是向左而不是离屏,但有一些问题:

Now the last one goes to the left instead of off screen, which is nice, but there are a few issues:


  1. 我不总是需要这些样式的最后一个链接,因为它不总是在(如果只有3个链接)。

  2. 当浏览器窗口调整大小时,链接堆叠在彼此之上(按设计)。

  3. 有时,最后一个链接的菜单也会出现在边界之外。有时,链接中间的链接会出现在右边缘,并且它们的下拉菜单会被切断。

在此演示中调整面板大小以查看我的意思(红色区域被认为是屏幕外 strong> http://jsfiddle.net/G7qfq/

Resize the panel in this demo to see what I mean (the red area is considered "off screen") http://jsfiddle.net/G7qfq/

我'与这个令人讨厌的常见问题斗争多年,从未找到一个令人满意的解决方案。有什么办法检查下拉菜单是否会关闭屏幕,如果是,添加/删除名称或东西,所以我可以保持它在屏幕上的CSS?

I've struggled with this annoyingly common problem for years and have never found a satisfactory solution. Is there any way to check if the drop menu would go off screen, and if so, add/remove a class name or something so I can keep it on screen with CSS?

我可以使用的一个线索是,如果菜单 离开屏幕,它总是在窗口底部产生一个垂直滚动条,但我不知道如何使用这些知识。我尝试接受此问题的答案,了解如何检测垂直滚动bar,但由于某种原因,它总是返回 true ,并且总是添加edge类(可能有一个时间问题):

One clue I might use is that if a menu does go off screen, it always produces a vertical scroll bar at the bottom of the window, but I'm not sure how to use that knowledge. I tried the accepted answer to this question about detecting vertical scroll bars, but for some reason it always returns true, and always adds the "edge" class (maybe there's an issue with the timing?):

$(".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/

Demo with the javascript: http://jsfiddle.net/G7qfq/2/

真的,我不想看到一个垂直滚动条,即使是一秒钟,所以我不知道这是要走,加上可能会有假阳性(滚动条为某些其他原因)。

Really, I don't want to see a vertical scroll bar even for a split second so I'm not sure that's the way to go, plus there could be false positives (scroll bar for some other reason).

我也试过在这个答案的解决方案,我承认,我不太明白,无法使其正常工作: http://jsfiddle.net/G7qfq/3/

I also tried the solution in this answer which I admit, I don't quite understand, and couldn't get it to work: 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,但我没有一个线索如何解决这个问题。任何想法?

I assume the solution requires javascript, and I am using jQuery, but I haven't got a clue how to approach the problem. Any ideas?

推荐答案

我想你几乎在那里...

I think you were almost there...

你真的只需要对宽度中涉及的计算感兴趣。如果下拉元素的宽度和该元素的偏移量大于容器的宽度,则您要切换菜单。

You should really only be interested in the calculations involved in the width. If the width of the dropdown element and the offset of that element is greater than the width of the container, you want to switch your menu.

$(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');
            }
        }
    });
});

http: //jsfiddle.net/G7qfq/582/

这篇关于检测下拉导航是否会关闭屏幕并重新定位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆