我正在努力清理锚点的工作方式。我有一个固定在页面顶部的标题,所以当你链接到页面中其他位置的锚点时,页面会跳转,所以锚点位于页面顶部,将内容留在固定标题后面(我希望那讲得通)。我需要一种方法来将锚点从头部的高度偏移 25px。我更喜欢 HTML 或 CSS,但 Javascript 也可以接受。
您可以在没有任何 JavaScript 的情况下使用 CSS。
给你的锚一个班:
<a class="anchor" id="top"></a>
然后,您可以将锚点设置为高于或低于页面实际显示位置的偏移量,方法是将其设置为块元素并相对定位。 -250px 将锚定位置为 250px
a.anchor {
display: block;
position: relative;
top: -250px;
visibility: hidden;
}
我找到了这个解决方案
<a name="myanchor">
<h1 style="padding-top: 40px; margin-top: -40px;">My anchor</h1>
</a>
这不会在内容中产生任何差距,并且锚链接工作非常好。
由于这是演示的关注点,纯 CSS 解决方案将是理想的。然而,这个问题是在 2012 年提出的,尽管已经提出了相对定位 / 负边际解决方案,但这些方法看起来相当笨拙,产生了潜在的流量问题,并且无法动态响应 DOM / 视口的变化。
考虑到这一点,我相信使用 JavaScript 仍然是(2017 年 2 月)最好的方法。下面是一个 vanilla-JS 解决方案,它将响应锚点击并在加载时解析页面哈希(参见 JSFiddle) 。如果需要动态计算,请修改.getFixedOffset()
方法。如果您正在使用 jQuery, 这里是一个经过修改的解决方案,具有更好的事件委派和平滑滚动 。
(function(document, history, location) {
var HISTORY_SUPPORT = !!(history && history.pushState);
var anchorScrolls = {
ANCHOR_REGEX: /^#[^ ]+$/,
OFFSET_HEIGHT_PX: 50,
/**
* Establish events, and fix initial scroll position if a hash is provided.
*/
init: function() {
this.scrollToCurrent();
window.addEventListener('hashchange', this.scrollToCurrent.bind(this));
document.body.addEventListener('click', this.delegateAnchors.bind(this));
},
/**
* Return the offset amount to deduct from the normal scroll position.
* Modify as appropriate to allow for dynamic calculations
*/
getFixedOffset: function() {
return this.OFFSET_HEIGHT_PX;
},
/**
* If the provided href is an anchor which resolves to an element on the
* page, scroll to it.
* @param {String} href
* @return {Boolean} - Was the href an anchor.
*/
scrollIfAnchor: function(href, pushToHistory) {
var match, rect, anchorOffset;
if(!this.ANCHOR_REGEX.test(href)) {
return false;
}
match = document.getElementById(href.slice(1));
if(match) {
rect = match.getBoundingClientRect();
anchorOffset = window.pageYOffset + rect.top - this.getFixedOffset();
window.scrollTo(window.pageXOffset, anchorOffset);
// Add the state to history as-per normal anchor links
if(HISTORY_SUPPORT && pushToHistory) {
history.pushState({}, document.title, location.pathname + href);
}
}
return !!match;
},
/**
* Attempt to scroll to the current location's hash.
*/
scrollToCurrent: function() {
this.scrollIfAnchor(window.location.hash);
},
/**
* If the click event's target was an anchor, fix the scroll position.
*/
delegateAnchors: function(e) {
var elem = e.target;
if(
elem.nodeName === 'A' &&
this.scrollIfAnchor(elem.getAttribute('href'), true)
) {
e.preventDefault();
}
}
};
window.addEventListener(
'DOMContentLoaded', anchorScrolls.init.bind(anchorScrolls)
);
})(window.document, window.history, window.location);