Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么$(“a:focus”)长度的计算结果为0,除非用setTimeout()包装?_Javascript_Jquery_Settimeout_Onblur_Onfocus - Fatal编程技术网

Javascript 为什么$(“a:focus”)长度的计算结果为0,除非用setTimeout()包装?

Javascript 为什么$(“a:focus”)长度的计算结果为0,除非用setTimeout()包装?,javascript,jquery,settimeout,onblur,onfocus,Javascript,Jquery,Settimeout,Onblur,Onfocus,我正在将键盘导航添加到我网站的主菜单中,我希望当用户在主菜单外单击时,任何打开的子菜单都会关闭。所以我有以下功能: var $nav = $(".navigation nav.main"), $navItems = $nav.find("a"); $navItems.on("blur", function() { if ($nav.find("a:focus").length === 0) { closeMenu(); } }); 我希望这样做的方式如

我正在将键盘导航添加到我网站的主菜单中,我希望当用户在主菜单外单击时,任何打开的子菜单都会关闭。所以我有以下功能:

var $nav = $(".navigation nav.main"),
    $navItems = $nav.find("a");

$navItems.on("blur", function() {
    if ($nav.find("a:focus").length === 0) {
        closeMenu();
    }
});
我希望这样做的方式如下:

  • 每当菜单中的任何链接失去焦点时
  • 如果菜单中没有具有焦点的链接,请关闭菜单
  • 但实际发生的是
    $(nav.find(“a:focus”).length)
    总是计算为
    0
    ,即使我可以直接在屏幕上看到菜单中确实有一个与焦点的链接

    但是,如果我将一个
    setTimeout()
    包装在条件的周围,那么它的工作方式与我预期的一样:

    var $nav = $(".navigation nav.main"),
        $navItems = $nav.find("a");
    
    $navItems.on("blur", function() {
        setTimeout(function() {
            if ($nav.find("a:focus").length === 0) {
                closeMenu();
            }
        });
    });
    
    现在,
    $nav.find(“a:focus”).length
    在我每次点击Tab键时都会计算为
    1
    ,直到我在菜单外单击Tab键,此时它计算为
    0
    ,并将其关闭

    这正是我希望它工作的方式,但是为什么需要
    setTimeout()

    为什么不起作用

    正如Epasarello在评论中指出的,你的
    模糊
    发生在下一个元素聚焦之前

    为什么
    setTimeout()
    ,即使有
    0毫秒的延迟,也能工作

    我相信这与渲染引擎有关。执行
    setTimeout()
    时,函数在渲染引擎的UI更新后“排队”(该更新集中于下一个元素)。尽管没有时间上的差异,但是
    setTimeout()
    确保在UI更新之后进行检查

    事件顺序:

    1. Fire blur event
    2. Update UI
    
    带有
    setTimeout()的事件顺序

    
    
    为什么不起作用

    正如Epasarello在评论中指出的,你的
    模糊
    发生在下一个元素聚焦之前

    为什么
    setTimeout()
    ,即使有
    0毫秒的延迟,也能工作

    我相信这与渲染引擎有关。执行
    setTimeout()
    时,函数在渲染引擎的UI更新后“排队”(该更新集中于下一个元素)。尽管没有时间上的差异,但是
    setTimeout()
    确保在UI更新之后进行检查

    事件顺序:

    1. Fire blur event
    2. Update UI
    
    带有
    setTimeout()的事件顺序

    
    
    因为事件的顺序。模糊发生在下一个之前focus@GetOffMyLawn不是因为事件的顺序。模糊发生在下一个之前focus@GetOffMyLawn不