gpt4 book ai didi

javascript - 当一个元素或其任何后代失去焦点时,删除一个类

转载 作者:行者123 更新时间:2023-11-27 22:51:58 24 4
gpt4 key购买 nike

我正在努力让我的导航系统更易于访问,但我很难弄清楚其中的一部分。这是我想要的功能列表

  • 可通过键盘导航。这工作正常。
  • 在子菜单前的按钮上单击/按 Enter 键可切换其事件状态。这工作正常。
  • 当子菜单或其任何子菜单失去焦点时关闭子菜单。这就是我遇到麻烦的地方。

问题是我似乎无法准确地确定该元素或其子元素是否具有焦点。第一次按“键盘”上的“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>

JS Fiddle .

理想情况下,我希望使用普通 JavaScript 而不是 jQuery 来完成这一切,但我认为一旦核心概念发挥作用,我就可以回去进行重构。

最佳答案

非常简单,您可以这样做:

此外,将事件监听器附加到 .menu-list 并将 blur 事件从 .menu-list_link 委托(delegate)给它,这样您就赢了最终不会有很多事件监听器。

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");
}
});

仅当失去焦点的项目是其相应子菜单上的最后一个项目时,它才会关闭子菜单菜单。

演示: https://jsfiddle.net/r0kz0g69/2/

<小时/>

此外,如果将整个菜单放入容器中,您可以将事件监听器附加到它而不是 .menu-list,例如一个 .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");
}
});

演示 3: https://jsfiddle.net/r0kz0g69/4/

关于javascript - 当一个元素或其任何后代失去焦点时,删除一个类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37975046/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com