使下拉菜单键盘和鼠标可浏览

时间:2015-02-08 11:24:26

标签: javascript jquery css drop-down-menu javascript-events

我正在为一个需要自定义下拉菜单的客户端开发一个项目,可以通过单击打开它来访问,或者使用键盘选中它。

目前,我的解决方案几乎完美,但有一个问题:第一次单击下拉菜单时,它会闪烁然后再次关闭。我确定我的JavaScript和jQuery在这里有一个简单的故障!

所需的功能是:

  1. 用户必须能够点击打开下拉菜单。 (完成,但有问题)
  2. 用户必须能够单击另一个菜单,并关闭前一个菜单并打开新菜单。 (DONE)
  3. 用户必须能够点击页面上的任何其他位置并关闭打开的菜单。 (DONE)
  4. 用户必须能够沿菜单栏选项卡,突出显示每个链接,并在选项卡打开时打开菜单。 (DONE)
  5. 然后,在离开下一个菜单或链接,关闭上一个菜单之前,标签必须向下按整个菜单。 (DONE)
  6. 正如我在这里所说,我几乎完全正常工作,但键盘焦点识别也能检测到鼠标聚焦,这意味着当我点击时,它会在鼠标移动后立即触发键盘焦点,再次关闭它。

    或者我认为。请帮忙!

    JavaScript代码

    $(document).ready(function() {
    function toggle(select) {
        closeAll(select);
        if(select.hasClass("expanded")) {
            select.removeClass("expanded");
        } else {
            select.addClass("expanded");
        }
    }
    function closeAll(select) {
        var close = $(document).find("#navigation li.select.expanded");
        if(select != null) {
            close = close.not(select);
        }
        close.removeClass("expanded")
    }
    
    $("#navigation > ul > li.select > a").click(function(event) {
        event.preventDefault();
        toggle($(this).parent());
    });
    $(document).mouseup(function(event) {
        var select = $("#navigation > ul > li.select.expanded");
        if(!select.is(event.target) && select.has(event.target).length === 0) {
            closeAll();
        }
    });
    $(document).on("focus", "#navigation > ul > li > a", function () {
        closeAll();
        if($(this).parent().hasClass("select")) {
            toggle($(this).parent());
        }
    });
    });
    

    HTML代码

        <div id="navigation">
            <ul>
                <li><a href="#"><i class="fa fa-home"></i> Home</a></li>
                <li class="select">
                    <a href="#"><i class="fa fa-users"></i> Find a Society</a>
                    <ul>
                        <li><a href="#">Scotland</a></li>
                        <li><a href="#">North West</a></li>
                        <li><a href="#">North East</a></li>
                        <li><a href="#">Midlands</a></li>
                        <li><a href="#">Eastern Counties</a></li>
                        <li><a href="#">Central Counties</a></li>
                        <li><a href="#">Wales</a></li>
                        <li><a href="#">South West Counties</a></li>
                        <li><a href="#">Southern Counties</a></li>
                        <li><a href="#">South East Counties</a></li>
                        <li><a href="#">Greater London</a></li>
                    </ul>
                </li>
            </ul>
        </div>
    

    当前设计

    The current user-interface design

1 个答案:

答案 0 :(得分:1)

我最近不得不创建一个类似的下拉列表,其中包含类型列表过滤等一些复杂功能,并在此过程中解决了这个问题。

诀窍是只有一个入口点进入下拉菜单,其他每个方法都必须调用同一个事件。在你的情况下,它是标签焦点,所以你想在点击时触发它:

编辑:根据OP评论修复打开/关闭

$("#navigation > ul > li.select > a").click(function(event) {
    event.preventDefault();
    if($(this).hasClass('expanded')){
        closeAll()
    }
    else {
        $(this).focus(); #Here the magic happens :)
    }
});

现在点击事件会触发标签焦点事件,然后切换下拉列表的可见性。

使用事件委派和css :not()选择器可以简化在外部点击时关闭下拉列表。这也应该比你当前的实现略快,尽管css选择器的长度可能意味着不多。

$(document).on('mouseup',':not(#navigation > ul > li.select.expanded)',(function(event) {
    closeAll();
});

顺便说一下,使用Jquery&#39; s toggleClass

可以简化你的切换功能
function toggle(select) {
    closeAll(select);
    select.toggleClass('expanded');
}