我正在尝试实现一个文档导航,类似于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中测试了这个。
答案 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
)。