我想看看以下是否可能:
- 由于性能原因,在不使用文档级全局选择器(如
$(document)
、$(body)
、$(window)
等)的情况下确定焦点是否出现在元素外部 - 如果没有全局选择器是不可能实现的,请用一个可证明的理由来解释自己。重要的是,我要理解为什么用今天的最新技术无法做到这一点
- 奖励回合:确定任务的最高效(计算时间)选择器/事件处理程序/插件
我的实现由一个非常简单的HTML导航栏组成,如下面的代码段所示。我在每个<a>
标签之间进行本机键盘导航。第一个列表元素是标题,包含可见的锚点,第二个元素
<ul class="test">
<li>
<a href="#">Title</a>
</li>
<li>
<ul>
<li>
<a href="#">Some link</a>
</li>
<li>
<a href="#">Some link</a>
</li>
<li>
<a href="#">Some link</a>
</li>
<li>
<a href="#">Some link</a>
</li>
</ul>
</li>
</ul>
这个导航栏的目标很简单:
- 本机键盘选项卡或shift+选项卡从一个锚点转到另一个锚点
- 在关注内部锚点元素时显示下拉菜单
- 当不关注任何内部锚点元素时,隐藏下拉菜单
我有1和2,但3是棘手的,因为上面列出的要求。我知道使用全局选择器可以很容易地完成这项工作,但这项挑战是要弄清楚并理解是否可以用其他方式完成。
$(document).ready(function() {
dropdownMenu = $(".test > ul");
dropdownMenu.hide();
$(".test").focusin(function() {
if (dropdownMenu.is(":hidden")) {
dropdownMenu.show();
}
});
// Some selector for some event here to handle the focus/clicks outside the $(".test") element
});
重要:我认为event.stopPropagation();
,如CSS技巧-停止事件传播的危险中所解释的,在这个问题的范围内是一种危险的技术,但是,如果使用所述技术导致最有效的方法,那么我将欢迎它。
我不确定我是否百分之百地回答了这个问题,但我想我明白了。
您可以使用focusin
事件将event.target
与closest
一起使用。
$(document).on('focusin', function (event) {
var $target = $(event.target);
if (!$target.closest('.bar').length) {
console.log('You focused outside of .bar!');
}
});
这是一把小提琴:https://jsfiddle.net/crswll/qk14r7c7/2/
在没有全局选择器的情况下,这里的一个选项是短暂延迟关闭操作:
var isVisible = false;
$(".test").focusin(function() {
if (dropdownMenu.is(":hidden")) {
dropdownMenu.show();
}
isFocused = true;
});
$(".test").focusout(function() {
isFocused = false;
setTimeout(function() {
if (!isFocused && dropdownMenu.is(":visible")) {
dropdownMenu.hide();
}
}, 100);
});
这有点麻烦,但可以保护您在切换时不会出现错误关闭。看见https://jsfiddle.net/d5fa5o8q/4/