【发布时间】:2013-01-15 17:29:14
【问题描述】:
我正在尝试为带有下拉菜单的按钮创建一个简单的跨浏览器插件。当用户单击此类按钮时,下方会出现一个菜单,其中包含各种选项,用户随后可以从中选择一个选项或将其关闭。
我创建了一个simple JSFiddle,其中包含三个这样的按钮,这些按钮体现了我想要实现的目标。我的 JSFiddle 代码执行了一些我已从下面的代码中排除的额外事件日志记录,但运行 JSFiddle 很明显我正在记录事件发生时。
这是我的 HTML:
我实现代码的方式需要下拉菜单可聚焦,因此容器上的 tabindex 属性。
<div class="dropdown">
<a href="#" class="dropdown-toggle">Open sesame</a>
<ul class="dropdown-menu" tabindex="0">
<li><a href="#">Some option</a></li>
<li><a href="#">Option with longer text</a></li>
</ul>
</div>
我的脚本:
// menu opening and closing
$(".dropdown-toggle").mousedown(function(evt) {
evt.preventDefault();
var c = $(this).closest(".dropdown").toggleClass("open");
c.hasClass("open") && c.find(".dropdown-menu")[0].focus();
});
// menu closing when clicking anywhere
$(".dropdown-menu").focusout(function(evt) {
evt.stopPropagation();
$(this).closest(".dropdown").removeClass("open");
})
菜单的显示由 CSS 完成。如您所见,我几乎没有在容器上设置 CSS 类,并且当在容器上设置 open 类时,CSS 会提供自动可见性。
预期行为
这是它应该工作的正确方法:
- 用户单击按钮并出现菜单
- 单击同一个按钮应关闭菜单
- 点击菜单选项应该触发点击选项(并可选择保持菜单打开)
- 如果打开菜单,单击其他任何地方都会关闭菜单。
浏览器问题
不同的浏览器似乎以不同的方式和过度地触发事件。事件传播(冒泡)及其顺序阻止了上层步骤按预期执行。 Chrome 似乎不会触发过多的事件。
Chrome
Chrome 似乎按预期工作。所有四个步骤都按应有的方式执行。单击菜单中的链接时,不会触发 focusout 作为焦点容器(菜单本身)中的链接。
Firefox 和 IE9
似乎步骤 #1、#2 和 #4 按预期工作,但 #3 失败,因为在可以检测和执行菜单选项 click 之前,focusout 首先触发并关闭菜单。
IE8 和 IE7
任何拥有它们的人都可以为我测试并告诉我哪些较高的步骤有效,哪些失败。我还没有测试过,但我也很想知道。
问题
此脚本的主要问题是 focusout 事件过早且过于频繁地触发。我不能使用 blur 事件,因为它不会从菜单选项传播到菜单本身。
重要 - 将点击处理程序绑定到
document- 我知道我可以将 click 事件绑定到我的document,但我不能使用这种常用方法,因为:
1. 这将非常不可靠,因为我的表单上的一些其他控件可能会停止点击传播,因此当这些控件被点击时菜单不会关闭。
2 .我的应用程序在iframe中运行,因此在其外部单击也会使菜单保持打开状态。
有人想以跨浏览器的方式玩这些事件吗?
【问题讨论】:
标签: jquery drop-down-menu popupmenu