event.preventDefault()导致:悬停伪类以粘贴

时间:2015-04-29 11:45:53

标签: javascript jquery html css twitter-bootstrap

我正在尝试实现一个文档导航,类似于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,然后当您从页面上的该部分滚动时,菜单会相应更新。

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

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

鼠标在浏览器窗口外的任何位置点击,可以解决问题。

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

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

我在Firefox和IE10中测试了这个。

1 个答案:

答案 0 :(得分:5)

问题不是: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),但之后会执行链接{{1} }并滚动到目标href。它发生得如此之快,似乎直接进入了目标位置。
  • 使用offset执行代码(滚动到e.preventDefault()),浏览器不执行offset - 100操作(因此它保持在href)。