【发布时间】:2018-08-09 11:04:09
【问题描述】:
我知道这是一个常见问题,但我所看到的答案都没有解决我的问题,如果我错过了一个,很抱歉,这显然可以删除/标记为重复...
标记
<div class="has-dropdown">
<button class="js-dropdown-trigger">
Dropdown
</button>
<div class="dropdown">
<div class="dropdown__item">
Some random text with a <a href="#" class="stop-propagation">link</a> in it.
</div>
<div class="dropdown__divider"></div>
<div class="dropdown__item">
<a href="#">Item One</a>
</div>
<div class="dropdown__item">
<a href="#">Item Two</a>
</div>
<div class="dropdown__item">
<a href="#">Item Three</a>
</div>
</div>
</div>
脚本
$('.has-dropdown').off().on('click', '.js-dropdown-trigger', (event) => {
const $dropdown = $(event.currentTarget).next('.dropdown');
if (!$dropdown.hasClass('is-active')) {
$dropdown.addClass('is-active');
} else {
$dropdown.removeClass('is-active');
}
});
$('.has-dropdown').on('focusout', (event) => {
const $dropdown = $(event.currentTarget).children('.dropdown');
$dropdown.removeClass('is-active');
});
样式
.has-dropdown {
display: inline-flex;
position: relative;
}
.dropdown {
background-color: #eee;
border: 1px solid #999;
display: none;
flex-direction: column;
position: absolute;
top: 100%;
left: 0;
width: 300px;
margin-top: 5px;
}
.dropdown.is-active {
display: flex;
}
.dropdown__item {
padding: 10px;
}
.dropdown__divider {
border-bottom: 1px solid #999;
}
小提琴
http://jsfiddle.net/joemottershaw/3yzadmek/
非常简单,单击js-dropdown-trigger 可以很好地切换is-active 下拉类,在has-dropdown 容器外部单击也会删除is-active 下拉类。
除了,我期望发生的是关注has-dropdown 元素的后代元素(单击或标签),这意味着不应触发 focusout 事件处理程序,因为您仍然专注于后代has-dropdown 容器的元素。
focusout事件被发送到一个元素,或任何元素 里面,失去焦点。这与中的模糊事件不同 它支持检测失去对后代元素的关注
我知道我可以删除 focusout 事件处理程序并使用类似的东西:
$(document).on('click', (event) =>{
const $dropdownContainer = $('.has-dropdown');
if (!$dropdownContainer.is(event.target) && $dropdownContainer.has(event.target).length === 0) {
$dropdownContainer.find('.dropdown').removeClass('is-active');
}
});
这可行,但如果您要单击触发器,然后按 Tab 浏览链接,则当您按 Tab 越过最后一个链接时,下拉菜单仍然可见。只是在努力寻找最佳解决方案来保持事物的可访问性。
如果可能的话,我想坚持使用focusout 方法。
根据darshanags 回答更新
虽然更新后的脚本适用于单个元素,但将其他元素添加到 body 会导致 focusout 不再按预期工作。我认为这是因为 if 声明似乎是正确的,即使焦点应用于 has-dropdown 容器之后的任何元素,而不仅仅是后代?因为如果您要更新 HTML 并在下拉菜单后添加更多可聚焦元素,例如输入。当从 has-dropdown 容器内的最后一个可聚焦元素切换到输入时,下拉菜单保持活动状态。它仅在下拉列表是 DOM 中的最后一个元素时才有效,并且仅在焦点完全失去 DOM 时触发。
【问题讨论】:
标签: jquery dropdown jquery-focusout