锚点点击后,可以滚动到指定的 Dom 元素,这个 dom 元素会贴近最顶部
但是顶部有个浮动的 Header,所以需要在滚动的时候进行偏移。
锚点偏移
网上的方法很多,暗锚、添加顶部占位,后来我发现了个牛逼方法,真的牛逼
offsetting an html anchor to adjust for fixed header
改了一下,如下
简单实现
function test() {
  const { document } = window
  const { history } = window
  const { location } = window
  const HISTORY_SUPPORT = !!(history && history.pushState)
  const anchorScrolls = {
    ANCHOR_REGEX: /^#[^ ]+$/,
    OFFSET_HEIGHT_PX: 64,
    /**
     * 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) {
      let 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() {
      console.log('滚动条')
      this.scrollIfAnchor(window.location.hash)
    },
    /**
     * If the click event's target was an anchor, fix the scroll position.
     */
    delegateAnchors: function(e) {
      const elem = e.target
      if (
        elem.nodeName === 'A' &&
        this.scrollIfAnchor(elem.getAttribute('href'), true)
      ) {
        e.preventDefault()
      }
    }
  }
  anchorScrolls.init()
}
test()
转载来源
修改之前的代码转载自 - https://stackoverflow.com/a/13067009