我试图让我的导航系统更易于访问,而且我很难搞清楚其中的一部分。这是我喜欢的功能列表
问题在于,我似乎无法准确地判断出这个元素或它的孩子是否有焦点。第一次按" tab"它可以正常工作在键盘上,"但在突出显示子列表中的第二个元素后,菜单将关闭。
这里是我的所有JS以及一些CSS和HTML示例。
JS:
// toggle the is-active class and aria values on button click
jQuery(".menu-list_toggle").bind("click", function(e) {
e.preventDefault();
if (jQuery(this).next(".menu-list[aria-hidden]").attr("aria-hidden") === "true") {
// mark all sibling menus as inactive
jQuery(this).closest(".menu-list_item").siblings().removeClass("is-active");
// mark menu list as active
jQuery(this).closest(".menu-list_item").addClass("is-active");
jQuery(this).next(".menu-list[aria-hidden]").attr("aria-hidden", "false");
} else {
// mark menu list as inactive
jQuery(this).closest(".menu-list_item").removeClass("is-active");
jQuery(this).next(".menu-list[aria-hidden]").attr("aria-hidden", "true");
}
});
// remove is-active and aria values on blur - HAVING TROUBLE HERE!
jQuery(".menu-list").bind("focusout", function() {
if (jQuery(this).has(document.activeElement).length === 0) {
jQuery(this).closest(".menu-list_item").removeClass("is-active");
jQuery(this).attr("aria-hidden", "true");
}
});
CSS:
[aria-hidden=true] {
display: none;
}
.is-active {
background: teal;
}
HTML:
<ul class="menu-list">
<li class="menu-list_item">
<a class="menu-list_link" href="#">Some Link</a>
<button class="menu-list_toggle">Toggle Menu</button>
<ul class="menu-list" aria-hidden="true">
<li class="menu-list_item">
<a class="menu-list_link" href="#">Some Link</a>
</li>
<li class="menu-list_item">
<a class="menu-list_link" href="#">Some Link</a>
<button class="menu-list_toggle">Toggle Menu</button>
<ul class="menu-list" aria-hidden="true">
<li class="menu-list_item">
<a class="menu-list_link" href="#">Some Link</a>
</li>
<li class="menu-list_item">
<a class="menu-list_link" href="#">Some Link</a>
</li>
<li class="menu-list_item">
<a class="menu-list_link" href="#">Some Link</a>
</li>
</ul>
</li>
<li class="menu-list_item">
<a class="menu-list_link" href="#">Some Link</a>
</li>
<li class="menu-list_item">
<a class="menu-list_link" href="#">Some Link</a>
</li>
</ul>
</li>
<li class="menu-list_item">
<a class="menu-list_link" href="#">Some Link</a>
</li>
<li class="menu-list_item">
<a class="menu-list_link" href="#">Some Link</a>
</li>
</ul>
理想情况下,我希望用vanilla JavaScript而不是jQuery来完成所有这些操作,但我想我可以在核心概念运行后再回过头来进行重构。
答案 0 :(得分:1)
这很简单,你可以这样做:
此外,将事件监听器附加到.menu-list
并将blur
事件从.menu-list_link
委托给它,这样您就不会有很多事件监听器。
jQuery(".menu-list").on("blur", ".menu-list_link", function(e) {
var tThis = jQuery(this);
var tThisParent = tThis.closest('.menu-list_item');
var tThisGrandParent = tThisParent.closest('.menu-list');
var tThisGreatGrandParent = tThisGrandParent.closest('.menu-list_item');
if (tThisParent.is(':last-child')) {
tThisGrandParent.attr("aria-hidden", "true");
tThisGreatGrandParent.removeClass("is-active");
}
});
仅当丢失focus
的项目是其相应子菜单中的最后一项时,它才会关闭子菜单菜单。
演示: https://jsfiddle.net/r0kz0g69/2/
此外,如果您将整个菜单放在容器中,您可以将事件监听器附加到它而不是.menu-list
s,例如一个.menu-container
,所以你在DOM元素上只有一个事件监听器。
jQuery(".menu-container").on("blur", ".menu-list_link", function() {
var tThis = jQuery(this);
var tThisParent = tThis.closest('.menu-list_item');
var tThisGrandParent = tThisParent.closest('.menu-list');
var tThisGreatGrandParent = tThisGrandParent.closest('.menu-list_item');
if (tThisParent.is(':last-child')) {
tThisGrandParent.attr("aria-hidden", "true");
tThisGreatGrandParent.removeClass("is-active");
}
});
演示2: https://jsfiddle.net/r0kz0g69/3/
如果失去焦点的项目是最外面的子菜单,那么不要隐藏菜单列表,这样一点点改进,所以最外面的菜单保持可见。
jQuery(".menu-container").on("blur", ".menu-list_link", function() {
var tThis = jQuery(this);
var tThisParent = tThis.closest('.menu-list_item');
var tThisGrandParent = tThisParent.closest('.menu-list');
var tThisGreatGrandParent = tThisGrandParent.closest('.menu-list_item');
if (tThisParent.is(':last-child')) {
if(!tThisGrandParent.is('.menu-container > .menu-list')) {
tThisGrandParent.attr("aria-hidden", "true");
}
tThisGreatGrandParent.removeClass("is-active");
}
});