我正在努力清理我的锚的工作方式。我有一个固定在页面顶部的标题,所以当你链接到页面其他地方的锚时,页面跳转,锚位于页面顶部,留下固定标题后面的内容(我希望这是有意义的)。我需要一种方法来抵消锚的25px从头部的高度。我更喜欢HTML或CSS,但Javascript也可以接受。


当前回答

我也在寻找这个问题的解决方案。对我来说,这很简单。

我有一个列表菜单与所有的链接:

<ul>
<li><a href="#one">one</a></li>
<li><a href="#two">two</a></li>
<li><a href="#three">three</a></li>
<li><a href="#four">four</a></li>
</ul>

下面是标题。

<h3>one</h3>
<p>text here</p>

<h3>two</h3>
<p>text here</p>

<h3>three</h3>
<p>text here</p>

<h3>four</h3>
<p>text here</p>

现在,因为我在页面顶部有一个固定的菜单,我不能让它去我的标签,因为它会在菜单后面。

相反,我在标签中放入了一个span标签,并带有正确的id。

<h3><span id="one"></span>one</h3>

现在使用2行CSS来正确定位它们。

h3{ position:relative; }
h3 span{ position:absolute; top:-200px;}

更改顶部值以匹配固定标题的高度(或更多)。 现在我认为这也适用于其他元素。

其他回答

对于同样的问题,我使用了一个简单的解决方案:在每个锚上放置40px的填充顶部。

我找到了这个解决方案:

<a name="myanchor">
    <h1 style="padding-top: 40px; margin-top: -40px;">My anchor</h1>
</a>

这不会在内容和锚链接中产生任何差距,效果非常好。

这将从以前的答案中提取许多元素并组合成一个微小的(194字节缩小)匿名jQuery函数。调整fixedElementHeight为您的菜单或块元素的高度。

    (function($, window) {
        var adjustAnchor = function() {

            var $anchor = $(':target'),
                    fixedElementHeight = 100;

            if ($anchor.length > 0) {

                $('html, body')
                    .stop()
                    .animate({
                        scrollTop: $anchor.offset().top - fixedElementHeight
                    }, 200);

            }

        };

        $(window).on('hashchange load', function() {
            adjustAnchor();
        });

    })(jQuery, window);

如果你不喜欢这个动画,替换它

$('html, body')
     .stop()
     .animate({
         scrollTop: $anchor.offset().top - fixedElementHeight
     }, 200);

:

window.scrollTo(0, $anchor.offset().top - fixedElementHeight);

糟蹋版本:

 !function(o,n){var t=function(){var n=o(":target"),t=100;n.length>0&&o("html, body").stop().animate({scrollTop:n.offset().top-t},200)};o(n).on("hashchange load",function(){t()})}(jQuery,window);

我在每个h1元素之前添加了40px-height .vspace元素。

<div class="vspace" id="gherkin"></div>
<div class="page-header">
  <h1>Gherkin</h1>
</div>

CSS中:

.vspace { height: 40px;}

它工作得很好,空间也没有堵塞。

由于这是表示的问题,纯CSS解决方案将是理想的。然而,这个问题是在2012年提出的,尽管已经提出了相对定位/负边际的解决方案,但这些方法看起来相当俗气,会产生潜在的流量问题,并且不能动态响应DOM /视口的变化。

考虑到这一点,我相信使用JavaScript仍然是(2017年2月)最好的方法。下面是一个香草- 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);