使用Jquery的锚点偏移

时间:2019-01-30 15:10:30

标签: javascript jquery

在我的网站上,我有一个粘性标头,因此当我使用锚链接时,标头会覆盖它们。

我找到了一些脚本来解决我的问题...我发现的唯一问题是它只能工作一次...如果我滚动回到顶部并再次单击链接,标题将覆盖它。 。如果我在同一页面上点击了另一个锚链接,那么它会起作用,然后返回到上一个链接,它将起作用...仅当我两次单击同一链接时。

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

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

        if ($anchor.length > 0) {

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

        }

    };

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

})(jQuery, window);

我在另一个问题上找到了此代码,这是唯一接近我需要的东西。我尝试过的其他一些脚本会影响使用id的Bootstrap下拉列表。我想使用CSS解决方案,例如...

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

唯一的问题是,如果目标具有任何顶部填充,则它将不起作用。

所以我的问题是,是否有一种方法可以使脚本在触发后进行以上重置,以便可以多次在同一链接上运行(再次在这里offsetting an html anchor to adjust for fixed header找到它?您能看到任何潜在的可能性吗?使用该脚本存在问题吗?有没有人有可以实际使用的纯CSS解决方案(我已经尝试过此页面http://nicolasgallagher.com/jump-links-and-viewport-positioning/demo/上的所有内容)?我使用内容管理器管理一个大型网站,所以我无法控制锚点是否有边距或填充在顶部..所以解决方案必须灵活。就像我说的上述代码是到目前为止我发现的最佳解决方案。谢谢!

1 个答案:

答案 0 :(得分:0)

// smoothscroll for anchor links and hashed URLs (works with id and name attributes)
;
(function($, window) {

  var defaultOptions = {
    // The selector of the fixed element
    headerSelector: '.header',
    // the offset to the fixed element at the end of the scroll
    offsetTop: 10,
    // the scroll duration
    duration: 1000
  }
  fixedOptions = {
  }
  
  function smoothScroll(options) {
    options = $.extend({}, defaultOptions, options, fixedOptions)
    headerSelector = options.headerSelector
    offsetTop = options.offsetTop
    duration = options.duration
    $(function($) {
      readyFunc();
    });

    if ("onhashchange" in window) {
      $(window).on('hashchange', hashChangeFunc);
    }

    // Every Link that has a hash in it, but isn't just a hash
    $('a[href*="#"]:not([href="#"])').on('click', clickFunc);
  }
  
  window.smoothScroll = smoothScroll;
  var hash = document.location.hash;
  // if we have a fixed position header element
  var headerSelector;
  // always add this offset
  var offsetTop;
  // scrollTime
  var duration;
  var target;

  // set scroll to all top on doc load
  var readyFunc = function() {
    if (document.location.hash) {
      setTimeout(function() {
        window.scrollTo(0, 0);
      }, 1);
      scrollFunc($(document.location.hash), headerSelector);
    }
  }

  // don't follow hash links
  var hashChangeFunc = function(e) {
    e.preventDefault();
    return false;
  }

  var clickFunc = function(e) {
    // check if link is on the same page
    if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
      e.preventDefault();
      target = $(this.hash);
      target = target.length ? target : $('[name="' + this.hash.slice(1) + '"]');

      if (target.length) {
        scrollFunc(target, headerSelector);
      }
      if (window.history && window.history.pushState) {
        history.pushState(null, null, this.hash);
      } else {
        document.location.hash = this.hash;
      }
    }
  }

  var scrollFunc = function(elem, fixed) {
    if ($(elem).css('position') == 'fixed') {
      var top = $(elem).position().top;
    } else {
      var top = $(elem).offset().top;
    }

    if ($(fixed).css('position') == 'fixed') {
      var offset = $(fixed).outerHeight();
    } else {
      var offset = 0;
    }
    top = Math.max(0, top - offset - offsetTop);
    $('html, body')
      .stop()
      .animate({
        scrollTop: top
      }, duration)
      .end();
  }

}(jQuery, window));

smoothScroll()
.header {
  position: fixed;
  background: silver;
  border-bottom: 1px solid gold;
  width: 100%;
  padding: 10px;
  top: 0;
}

body {
  margin: 0;
  margin-top: 70px;
}

#myid,
.src {
  padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="header">Header<br>Header<br>Header</div>
<div id="top"></div>

<div class="src">
  <a href="#myid">link scroll 1</a><br>
  <a href="#myname">link scroll 2</a>

  <br />
  <br />
  <br />
  <br /> Some content
  <br />
  <br />
  <br />
  <br />
  <br /> Some content
  <br />
  <br />
  <br />
  <br />
  <br /> Some content
  <br />
  <br />
  <br />
  <br />
  <br /> Some content
  <br />
  <br />
  <br />
  <br />
  <br /> Some content
  <br />
  <br />
  <br />
  <br /> Some content
  <br />
  <br />
  <br /> Some content
  <br />
  <br />
  <br />
  <br />
  <br />
  <br /> Some content
  <br />
  <br />
  <br />
  <br />
  <br />
  <br />
  <br />
  <br /> Some content
  <br />
  <br />
  <br />
  <br />
  <br />
  <br />
  <br />
  <br />
  <br />
  <br />
  <br /> Some more content
  <br />
  <br />
  <br />
  <br />
  <br />
  <br />
  <br />
  <br />
  <br />
  <br />
</div>
<div id="myid"></div>
Scroll 1
<a href="#top">Top</a>
<br />
<br /> Some more content
<br />
<br /> Some more content
<br />
<br /> Some more content
<br />
<br /> Some more content
<br />
<br /> Some more content
<br />
<br /> Some more content
<br />
<br /> Some more content
<br />
<br /> Some more content
<br />
<br /> Some more content
<br />
<br /> Some more content
<br />
<br /> Some more content
<br />
<br /> Some more content
<br />
<br /> Some more content
<br />
<br />
<br /> Some more content
<br />
<br />
<br /> Some more content
<br />
<div name="myname"></div>
Scroll 2
<a href="#top">Top</a>
<br />
<br /> Some more content
<br />
<br />
<br /> Some more content
<br />
<br />
<br /> Some more content
<br />
<br />
<br /> Some more content
<br />
<br />
<br /> Some more content
<br />
<br />
<br /> Some more content
<br />
<br />
<br /> Some more content
<br />
<br />
<br /> Some more content
<br />
<br />
<br /> Some more content
<br />
<br />
<br /> Some more content
<br />
<br />
<br /> Some more content
<br />
<br />
<br /> Some more content
<br />
<br />
<br /> Some more content
<br />
<br />
<br /> Some more content
<br />
<br />
<br /> Some more content
<br />
<br />
<br /> Some more content
<br />
<br />
<br /> Some more content
<br />
<br />
<br /> Some more content
<br />
<br />
<br /> Some more content
<br />
<br />
<br /> Some more content
<br />
<br />
<br /> Some more content
<br />
<br />
<br /> Some more content
<br />
<br />
<br />
<b>This is the end</b><br>
<a href="#top">Top</a>
<br />
<br />