【问题标题】:event.preventDefault() Causing :hover pseudo class to stickevent.preventDefault() 导致 :hover 伪类粘住
【发布时间】:2015-07-08 16:22:10
【问题描述】:

我正在尝试实现文档导航,类似于 Bootstrap 网站上的文档导航。我已经完成了它的整体工作,但它有一个小方面困扰着我。

就像在 Bootstrap 上一样,我正在使用 affix.js 和 scrollSpy.js 的组合,这很有效。请参阅以下内容 JSFiddle.

        $('#doc_nav').on( "click", "a", function( e ){
//            e.preventDefault();
            var target = this.hash;
            var $target = $(target);
            var offset = $target.offset().top;
            console.log(offset);
            offset = offset - 100;
            console.log(offset);

            $('html, body').scrollTop( offset );


        });

注释掉 e.preventDefault() 后,导航菜单的行为与预期一致。向下滚动窗口会导致显示的 div 在菜单上突出显示。单击菜单列表中的某个项目,直接将您带到页面上相应的 div,然后当您从页面上的该部分滚动离开时,菜单会相应更新。

在我的“真实”页面上,我有一个高度为 100 像素的固定页眉。因此,目前,当我单击菜单链接时,页面会跳转到所需的部分并将其放置在页眉稍微遮挡它的页面顶部。除非我使用 e.preventDefault(),否则上面代码的 scrollTop 部分似乎不起作用。如果您在小提琴中取消注释此行并再次运行它,单击菜单上的“标题 3”链接,您将看到它现在将标题 3 内容放在页面中,从顶部偏移 100 像素。完美。

但是,现在将页面向上滚动到顶部。您将看到“标题 3”列表项保持在其 :hover 状态,即使鼠标不在其附近也是如此。好像 e.preventDefault() 阻止了浏览器检测到鼠标不再悬停在项目上。

在浏览器窗口外的任意位置单击鼠标即可解决问题。

谁能解释我在这里做错了什么?如何防止锚点单击的默认行为,以便我可以控制页面滚动位置,而不会在此过程中停止正确的 CSS 绘制?

出现问题是因为我使用 e.preventDefault() 来阻止浏览器的默认行为,因为我想控制滚动到锚定元素。

我已经在 Firefox 和 IE10 中对此进行了测试。

【问题讨论】:

    标签: javascript jquery html css twitter-bootstrap


    【解决方案1】:

    问题不是:hover 状态,而是:focus 状态。

    当您单击一个链接时,该链接获得焦点,因此您应用 :focus 样式(与代码中的 :hover 样式相同)。通过阻止默认行为,该链接将保持活动状态并且不会失去焦点。

    一种快速的解决方案是使用:$(this).blur() 来取消聚焦/模糊元素。

    在您的代码中,它看起来像这样:

        $('#doc_nav').on( "click", "a", function( e ){
            e.preventDefault();
            var target = this.hash;
            var $target = $(target);
            var offset = $target.offset().top;
            console.log(offset);
            offset = offset - 100;
            console.log(offset);
            $(this).blur();
            $('html, body').scrollTop( offset );
        });
    

    您可以在此处查看演示:https://jsfiddle.net/z32rpe3b/30/


    为什么使用 e.preventDefault() 可以正常工作,但如果没有它则错误?

    这个问题的答案与执行顺序有关。 onclick 事件发生在浏览器中 href 重定向发生之前:

    • 没有e.preventDefault(),代码被执行,浏览器正确滚动到目标offset - 100位置(在onclick),但随后它执行链接href并滚动到目标@987654335 @。它发生得如此之快,以至于它似乎直接到达了目标位置。
    • 使用e.preventDefault(),代码被执行(滚动到offset - 100),浏览器不执行href操作(所以它停留在offset - 100)。

    【讨论】:

    • 嗨,阿尔瓦罗。谢谢。我在踢自己,这太容易了!我专注于它是 :hover 伪类,我错过了 :focus。你能回答谜题的另一部分吗,为什么除非我使用 e.preventDefault() 否则 scrollTop() 不起作用?
    • 这与事件执行的顺序有关。我更新了我的答案,解释了为什么会发生这种情况。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-08
    • 1970-01-01
    • 2017-08-08
    • 2010-10-25
    • 2017-11-29
    • 2019-07-04
    • 2011-02-22
    相关资源
    最近更新 更多