使锚链接在链接到的位置上方一些像素

IT技术 javascript html css anchor
2021-02-03 13:56:33

我不确定询问/搜索这个问题的最佳方式:

当您单击锚链接时,它会将您带到页面的该部分,链接区域现在位于页面的顶部。我希望锚链接将我发送到页面的那部分,但我希望顶部有一些空间。就像,我不希望它把我发送到顶部的链接到部分,我希望那里有 100 个左右像素的空间。

这有意义吗?这可能吗?

编辑以显示代码 - 它只是一个锚标签:

<a href="#anchor">Click me!</a>

<p id="anchor">I should be 100px below where I currently am!</p>
6个回答
window.addEventListener("hashchange", function () {
    window.scrollTo(window.scrollX, window.scrollY - 100);
});

这将允许浏览器为我们完成跳转到锚点的工作,然后我们将使用该位置进行偏移。

编辑 1:

正如@erb 所指出的,这仅在更改哈希时您在页面上时才有效。使用#somethingURL 中已有的进入页面不适用于上述代码。这是处理该问题的另一个版本:

// The function actually applying the offset
function offsetAnchor() {
    if(location.hash.length !== 0) {
        window.scrollTo(window.scrollX, window.scrollY - 100);
    }
}

// This will capture hash changes while on the page
window.addEventListener("hashchange", offsetAnchor);

// This is here so that when you enter the page with a hash,
// it can provide the offset in that case too. Having a timeout
// seems necessary to allow the browser to jump to the anchor first.
window.setTimeout(offsetAnchor, 1); // The delay of 1 is arbitrary and may not always work right (although it did in my testing).

注意:要使用 jQuery,您可以将示例中的window.addEventListenerwith替换$(window).on谢谢@Neon。

编辑2:

正如一些人指出的那样,如果您连续两次或多次单击同一个锚链接,上述操作将失败,因为没有hashchange事件强制偏移。

此解决方案是@Mave 建议的略微修改版本,并为简单起见使用了 jQuery 选择器

// The function actually applying the offset
function offsetAnchor() {
  if (location.hash.length !== 0) {
    window.scrollTo(window.scrollX, window.scrollY - 100);
  }
}

// Captures click events of all <a> elements with href starting with #
$(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);
});

// Set the offset when entering page with hash present in the url
window.setTimeout(offsetAnchor, 0);

此示例的 JSFiddle在这里

谢谢@erb。OP 的问题不需要这种情况,但为了帮助其他人,我添加了另一个版本的实现。
2021-03-18 13:56:33
你可以去$('a[href^="#"]').on('click', function() { offsetAnchor(); });这样,如果href一个的a元素有开始#,您调用相同的功能。
2021-03-18 13:56:33
仍然缺少一个小细节。如果您单击一个锚点,然后向上滚动,然后再次单击同一个锚点,则没有哈希更改,因此不会使用偏移量。想法?
2021-03-21 13:56:33
这仅在用户已经在页面上时才有效,例如当用户example.com/#anchorexample.com/about/.
2021-03-23 13:56:33
不需要 jQuery - 只需替换$(window).on("hashchange",window.addEventListener("hashchange",
2021-04-08 13:56:33

仅使用 css 您可以向锚定元素添加填充(如上面的解决方案)为了避免不必要的空白,您可以添加相同高度的负边距:

#anchor {
    padding-top: 50px;
    margin-top: -50px;
}

我不确定这是否是任何情况下的最佳解决方案,但对我来说效果很好。

我的页面变得疯狂...... *_*
2021-03-19 13:56:33
如果它上方 50 像素内有一个链接,它可能会被掩盖并且无法点击我相信
2021-03-28 13:56:33
@Andrew 这在 IE10 或 Chrome 上似乎不是问题。
2021-03-29 13:56:33
@AleksDorohovich - 您可以将其作为单独的答案发布,因为它是现有答案所独有的。
2021-03-31 13:56:33
您可以使用position: relativecss 属性执行相同的操作所以,它会像position: relative; top: -50px;
2021-04-12 13:56:33

这是 2020 年的答案:

#anchor {
  scroll-margin-top: 100px;
}

因为它得到了广泛的支持

被否决是因为虽然这很好,但它并没有得到广泛支持。Opera mobile/mini 和 safari 浏览器/ios,甚至第一个 Edge 都不完全支持这一点。
2021-03-19 13:56:33
略低于 90% 的所有浏览器(包括带有 scroll-snap-margin-top 的 iOS)应该足以选择退出 javascript 解决方案,特别是如果用户影响只是不得不滚动。但是,嘿,让我们在这种方法伤害某人之前对其进行否决。
2021-03-20 13:56:33
这样一个简单而有效的答案。很快就会达到 100% 的支持(对于现代浏览器)。
2021-03-25 13:56:33
我会建议scroll-padding而不是scroll-margin因为 Safariscroll-snap-margin根据 caniuse.com使用非标准名称
2021-04-14 13:56:33

更好的解决方案:

<p style="position:relative;">
    <a name="anchor" style="position:absolute; top:-100px;"></a>
    I should be 100px below where I currently am!
</p>

只需在<a>相对定位的对象内使用绝对定位来定位标签。

在进入页面或通过页面内的哈希更改时有效。

@CZorio如果我做对了,它(巧妙地)创建了一个锚元素(可能是其他东西,例如“span”而不是“a”)并将其定位在相对下方,以便其中的锚点href="#anchor"指向那里,而不是<p>直接指向元素。但有一个警告:使用id而不是name在 HTML5 中,请参阅:stackoverflow.com/questions/484719/html-anchors-with-name-or-id
2021-03-20 13:56:33
我不明白这个答案。您是将此链接引用到对象还是对象本身?
2021-03-21 13:56:33
对引导固定顶部导航栏非常有用
2021-04-03 13:56:33
我更喜欢你的解决方案,因为它不使用 javascript。谢谢!
2021-04-13 13:56:33
真正更好的解决方案:)
2021-04-13 13:56:33

最佳解决方案

<span class="anchor" id="section1"></span>
<div class="section"></div>

<span class="anchor" id="section2"></span>
<div class="section"></div>

<span class="anchor" id="section3"></span>
<div class="section"></div>

<style>
.anchor{
  display: block;
  height: 115px; /*same height as header*/
  margin-top: -115px; /*same height as header*/
  visibility: hidden;
}
</style>
为什么这是最好的解决方案?此外,如果您给出一定程度的解释/推理和答案,它会更有帮助。
2021-03-19 13:56:33
无论如何,当您添加 HTML 以制作锚点时,添加跨度并没有太大区别。然后只需添加一点 CSS,您就可以解决这个问题而不会产生任何错误;就像其他一些解决方案一样。
2021-03-28 13:56:33
此选项的一个问题是锚点类元素可能会覆盖其上方的元素,从而阻止鼠标和触摸与其进行交互。我尝试使用 z-index,但它没有解决这个问题。
2021-04-12 13:56:33