为所有哈希链接/调用的滚动位置添加自动偏移量

时间:2012-07-08 21:21:43

标签: javascript jquery hash scroll position

我有以下问题:

就像在Facebook上一样,我在页面顶部有一个始终可见的菜单栏(position: fixed;)。当我现在点击我页面上的哈希链接(或在网址中加载带有哈希的新页面)跳转到页面上的某个元素时,浏览器总是将此元素滚动到页面的最顶部,这意味着之后,元素位于顶部菜单栏后面。

我想添加一些Javascript(jQuery或普通Javascript),自动为此滚动位置添加(负)偏移,以便链接元素位于顶部菜单栏单击链接或加载页面时。但我不只是想将事件监听器添加到所有处理这个问题的链接。我还想要一个有效的解决方案,如果页面使用浏览器的地址栏在URL中加载了哈希部分(或者链接到网址末尾带有哈希的不同页面)。

您可以在http://loud.fm/tmp/details.html找到我的网页的点击数据。单击左侧图像右上角的评论气泡跳转到评论。如果您的浏览器窗口足够小,则应在列出注释之前跳转到灰色的“COMMENTS”标题和分页。在点击跳转链接后,我希望标题和分页在顶部菜单下显示

你能帮我解决这个问题吗?提前致谢! :)

此致 勒

10 个答案:

答案 0 :(得分:24)

我实际上找到了一个适用于我的解决方案,仅使用css:

我在跳转链接所指向的元素中添加了margin-top: -40px;padding-top: 40px;。这适用于所有主流浏览器:IE(7-9),Firefox,Opera,Chrome和Safari。

唯一的问题:如果此元素位于浮动元素之后,则负边距不起作用(意味着正填充变为可见)。如果有人知道解决方案/解决方法,请发表评论。我会更新我的帖子。谢谢!

答案 1 :(得分:3)

为了添加解决方案,我发现将显示设置为none解决了在浮动元素中使用时填充可见的问题。

所以:

.symbol-target {
    padding-top: 40px;
    margin-top: -40px;
    width: 1px; /* '0' will not work for Opera */
    display: hidden;
}

我还将此样式作为空div放在我的目标内容之上。

答案 2 :(得分:3)

我发现在css中添加:before这种方式似乎运行良好。

h2:before { 
  display: block; 
  content: " "; 
  margin-top: -285px; 
  height: 285px; 
  visibility: hidden; 
}

更多CSS Tricks website

答案 3 :(得分:2)

作为示例,请考虑适用于所有主流浏览器的D bootDoc解决方案:

CSS(插入标题栏高度而不是40px):

.symbol-target {
    padding-top: 40px;
    margin-top: -40px;
    width: 1px; /* '0' will not work for Opera */
    display: inline-block;
}

HTML:

<h3>
    <span class="symbol-target" id="myTarget">&nbsp;</span>
    <a href="#myTarget">My text</a>
</h3>

真实页面示例:

std.array.uninitializedArray documentation using bootDoc

注意:

它不适用于IE 6。

答案 4 :(得分:1)

最适合我的是这样做:

  1. 将指定的ID(您在URL中想要的内容)提供给所需元素中的其他元素。
  2. 将新元素设为绝对值并将其移动到所需元素上方X像素,其中X是固定标题的高度。

答案 5 :(得分:1)

其他人都给出了 CSS 答案,但问题是针对 JS 的

@assmmahmud 的回答通过一个小调整起作用:gotoSpecificPosition 需要在第一条语句中更改为 offsetAnchor。

这对于调整粘性标题的所有 id 链接非常有帮助。

/* go to specific position if you load the page directly from address bar */
var navbarHeight = document.getElementById('mynavbar').clientHeight;
function offsetAnchor() {
  if (window.location.hash.length !== 0) {
    window.scrollTo(window.scrollX, window.scrollY - navbarHeight );
  }
}

/* Captures click events on all anchor tag with a hash tag */
$(document).on('click', 'a[href^="#"]', function(event) {
  // Click events are captured before hashchanges. Timeout
  // causes offsetAnchor to be called after the page jump.
  window.setTimeout(function() {
    offsetAnchor();
  }, 0);
});

window.setTimeout(offsetAnchor, 0);

答案 6 :(得分:0)

不幸的是(至少使用Firefox)padding和margin都没有帮助(将它们放在包含除菜单栏之外的所有内容的'main'div);滚动到一个锚点总是把它放在页面的最顶层,固定的元素被诅咒。

我认为您将不得不采用您最初的想法,但请记住,通过使用委托,您可以设置一个处理程序,该处理程序将与您的菜单栏中的所有链接一起使用,包括动态添加的链接。

答案 7 :(得分:0)

使用纯JavaScript,您可以执行以下操作。它将监听所有锚标记的点击事件,并滚动到页面中的所需位置(使用jquery):

/* go to specific position if you load the page directly from address bar */
var navbarHeight = document.getElementById('mynavbar').clientHeight;
function gotoSpecificPosition() {
  if (window.location.hash.length !== 0) {
    window.scrollTo(window.scrollX, window.scrollY - navbarHeight );
  }
}

/* Captures click events on all anchor tag with a hash tag */
$(document).on('click', 'a[href^="#"]', function(event) {
  // Click events are captured before hashchanges. Timeout
  // causes offsetAnchor to be called after the page jump.
  window.setTimeout(function() {
    offsetAnchor();
  }, 0);
});

window.setTimeout(offsetAnchor, 0);

以上代码将处理所有技巧。

答案 8 :(得分:0)

 h1, h2, h3, h4, h5, h6 {
   scroll-margin-top: 80px;
 }

这个想法来自 React 文档。

答案 9 :(得分:-1)

尝试在页面顶部放置填充以占据菜单栏后面的区域。类似于:padding-top:80px;(而不是80px,你应该放置你的菜单栏的高度)。