【问题标题】:Making a drop-down menu keyboard and mouse browsable使下拉菜单键盘和鼠标可浏览
【发布时间】:2015-04-08 05:22:03
【问题描述】:

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

目前,我的解决方案几乎可以完美运行,但有一个问题:第一次单击下拉菜单时,它会闪烁打开然后再次关闭。我敢肯定我的 JavaScript 和 jQuery 有一个简单的小故障!

所需的功能是这样的:

  1. 用户必须能够单击以打开下拉菜单。 (完成,但有问题)
  2. 用户必须能够单击另一个菜单,并关闭前一个菜单并打开新菜单。 (完成)
  3. 用户必须能够单击页面上的任何其他位置并关闭打开的菜单。 (完成)
  4. 用户必须能够沿菜单栏进行切换,突出显示每个链接,并在切换到菜单时打开菜单。 (完成)
  5. 然后,在进入下一个菜单或链接、关闭上一个菜单之前,该选项卡必须向下跳动整个菜单。 (完成)

正如我在这里所说,我几乎完全可以正常工作,但键盘焦点识别也会检测鼠标焦点,这意味着当我点击时,它会在鼠标点击后立即触发键盘焦点,然后再次关闭它。

至少我是这么认为的。请帮忙!

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>

目前的设计

【问题讨论】:

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


    【解决方案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 的toggleClass 进行简化

    function toggle(select) {
        closeAll(select);
        select.toggleClass('expanded');
    }
    

    【讨论】:

    • 这看起来很有希望!我只是想完成它的工作,目前使用该代码下拉菜单不会在点击时再次关闭。
    • @ProbabilityWolf,很好,我认为我的编辑会解决这个问题。在我的版本中(现在从内存中工作,因为这里没有它),我使用blur 事件作为退出点,它聚焦下一个元素并关闭下一个元素。这可以替换您的 closeAll 函数,但如果它适合您,则无需修复它。
    • 我一定是在某个地方犯了一个严重的错误,当我点击它时它仍然弹开和关闭,尽管焦点有点工作。
    • 如果您可以将代码放在 JSFiddle 中,我会尝试找出问题
    • 祝你好运!我对这个问题有某种心理障碍。 http://jsfiddle.net/cfnhgyht/
    猜你喜欢
    • 1970-01-01
    • 2014-03-02
    • 2014-04-24
    • 2021-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多