【问题标题】:Accounting for a fixed header with animate.scrolltop and (target).offset().top;用 animate.scrolltop 和 (target).offset().top 计算一个固定的标题;
【发布时间】:2012-02-22 12:36:42
【问题描述】:

这应该是一个非常基本的问题,但我早上的大部分时间都在解决这个问题,此时我已经接近认输了。我什至没有一点 js foo ——但我发现了一段注释很好的代码,我希望用它来为锚链接设置动画:

$(document).ready(function() {
$('a[href*=#]').bind('click', function(e) {
e.preventDefault(); //prevent the "normal" behaviour which would be a "hard" jump

var target = $(this).attr("href"); //Get the target

var scrollToPosition = $(target).offset().top;

// perform animated scrolling by getting top-position of target-element and set it     as scroll target
$('html, body').stop().animate({ scrollTop: scrollToPosition}, 600, function() {
     location.hash = target;  //attach the hash (#jumptarget) to the pageurl
});

return false;

 });
});

我试图让它在 offset().top 上方 30 像素处着陆——我试过了

$('html, body').stop().animate({ scrollTop: scrollToPosition -30}, 600,

这几乎奏效了——它去了正确的地方,但随后又反弹回来。

我也试过了

scrollTop: $(target).offset().top - 20 },

我也试过

scrollTop: $(hash).offset().top + $('#access').outerHeight()

这似乎并没有改变任何东西。

似乎答案可能在这里:JQuery page scroll issue with fixed header 但我似乎不太明白。

我知道这与其他问题类似 - 但我已经完成了我能找到的内容,而且我是文盲,无法复制/粘贴任何解决问题的内容。

我将非常感谢您的解决方案。

非常感谢,

马丁

PS

我发现的另一段代码确实有效,但它正在剥离主题标签,这使得它几乎无用。

$(function(){
$('a[href*=#]').click(function() {
if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'')
    && location.hostname == this.hostname) {
        var $target = $(this.hash);
        $target = $target.length && $target || $('[name=' + this.hash.slice(1) +']');
        if ($target.length) {
            var targetOffset = $target.offset().top;
            $('html,body').animate({scrollTop: targetOffset - 30}, 1000);
            return false;
        }
    }
  });
});

【问题讨论】:

    标签: jquery jquery-animate target offset scrolltop


    【解决方案1】:

    已编辑: 您只需要检测固定标题的高度并从您正确执行的scrollToPosition 中减去它。问题是 window.location.hash = "" + target; 将页面跳转到具有该 ID 的元素的顶部。因此,如果您像以前那样在此处设置动画,然后更改为该哈希值,它将像您描述的那样“反弹”。这是我们解决这个问题的第一种方法:

    // Get the height of the header
    var headerHeight = $("div#header").height();
    
    // Attach the click event
    $('a[href*=#]').bind("click", function(e) {
        e.preventDefault();
    
        var target = $(this).attr("href"); //Get the target
        var scrollToPosition = $(target).offset().top - headerHeight;
    
        $('html').animate({ 'scrollTop': scrollToPosition }, 600, function(){
            window.location.hash = "" + target;
            // This hash change will jump the page to the top of the div with the same id
            // so we need to force the page to back to the end of the animation
            $('html').animate({ 'scrollTop': scrollToPosition }, 0);
        });
    
        $('body').append("called");
    });
    

    这是第一种方法的 jsfiddle:http://jsfiddle.net/yjcRv/1/

    进一步编辑: 控制哈希更改事件的更好方法是使用像jQuery Address 这样的插件。有了这个,您可以更多地利用您的 hashchange 事件。这是一个示例用法:

    // Get the height of the header
    var headerHeight = $("div#header").height();
    
    $.address.change(function(evt){
        var target = "#" + evt["pathNames"][0]; //Get the target from the event data
    
        // If there's been some content requested go to it…else go to the top
        if(evt["pathNames"][0]){
            var scrollToPosition = $(target).offset().top - headerHeight;
            $('html').animate({ 'scrollTop': scrollToPosition }, 600);
        }else{
            $('html').animate({ 'scrollTop': '0' }, 600);
        }
    
        return false;
    });
    
    // Attach the click event
    $('a').bind("click", function(e) {
        // Change the location
        $.address.value($(this).attr("href"));
    
        return false;
    });
    

    此处的示例:http://www.vdotgood.com/stack/user3444.html

    注意:您现在不需要将哈希添加到您的链接 href 属性。这是您可以使用 jQuery 选择器定位的链接:

    <!-- This is correct -->
    <a href="/target" class="myclass">Target</a>
    
    <!-- These are incorrect -->
    <a href="/#/target" class="myclass">Target</a>
    
    <a href="#/target" class="myclass">Target</a>
    

    要定位此链接,您可以使用如下选择器:

    $("a.myclass").click(function(){
        $.address.value($(this).attr("href"));
        return false;
    });
    

    jQuery Address 实际上会寻找具有以下属性的链接:

    <a href="/target" rel="address:/target">Target</a>
    

    这里的rel 属性包含address:,后面是您在本例中定义的相对URL /target。如果你使用这个,jQuery Address 会自动检测到链接并触发 hash change 事件。

    【讨论】:

    • 非常感谢史蒂夫。我发誓我会学到足够的知识来理解我在复制和粘贴的内容,希望今年,但这只是让我头疼不已。干杯-m
    • 快速提问:代码运行良好,但添加到 url 的哈希值显示为“#undefined” - 有什么想法吗?
    • 别担心,伙计。只要坚持下去,定期获得一些好的在线教程,你就会吸收你所追求的知识! Defo 查看 tutsplus 网站 (Webdesigntuts, Nettuts) 和 Team Treehouse Carsonified 的网页设计/开发学习,所有这些都是很棒的免费资源。
    • 嗯——似乎不起作用。但是后来,我只是在 chrome 中尝试了它(而不是 ff),并没有发生任何事情——看起来要炸的鱼要大得多。
    • 要让它在 Chrome / Safari 和其他 webkit 浏览器中运行,您需要将 $('html').animate 都更改为 $('html,body').animate
    【解决方案2】:

    我知道这是一个老问题(有点),但我在网站上使用固定的下拉导航遇到了类似的问题。请注意,这是一个平滑的滚动代码 sn-p,尽管您可以通过更改动画速度轻松使其自动运行。

    jQuery:

    $('body').on('click','a[href^="#"]',function(event){
        event.preventDefault();
        var target_offset = $(this.hash).offset() ? $(this.hash).offset().top : 0;
        //change this number to create the additional off set        
        var customoffset = 75
        $('html, body').animate({scrollTop:target_offset - customoffset}, 500);
    });
    

    我已经使用这段代码很长时间了,没有任何问题。我唯一不喜欢它的是它会抓住任何#标签。所以在像 Flexslider 插件这样的插件中,导航使用 #'s 我手动从插件中剥离它们。

    【讨论】:

      【解决方案3】:

      我已经从http://www.paulund.co.uk/smooth-scroll-to-internal-links-with-jquery 调整了原始脚本。它的效果很棒,但您不能按原样设置延迟。

      var headerHeight = $("header").height();
      
      
              $(document).ready(function(){
          $('a[href^="#"]').on('click',function (e) {
              e.preventDefault();
      
              var target = this.hash,
              $target = $(target);
      
              $('html, body').stop().animate({
                  'scrollTop': $target.offset().top - headerHeight
              }, 1200, 'swing', function () {
                  window.location.hash = target ;
              });
          });
      });
      

      是的,我有点晚了,但这个问题刚刚发生在我身上...... 干杯!

      【讨论】:

        【解决方案4】:

        我们的一个子导航也有类似的问题。 我写了这段代码,它似乎为我做了。

        $(document).ready(function() {
        var hashId = window.location.hash;
        var sectionid = $(hashId);
        if(sectionid.length != 0 {
        {
        $('html,body').animate({scrollTop: $(hashId).offset().top - 180}, 500);
        }
        }});
        

        您可以将 180 更改为您想要的偏移量,并将 500 更改为执行动画所需的时间。

        【讨论】:

          【解决方案5】:

          万一有人看到这个问题,在提出问题 8 年后和上次发表评论 6 年后,我会问一个后续问题...

          我正在使用一个 Bootstrap 模板,该模板使用此 javascript 滚动到锚点,然后折叠(以前展开的)移动菜单:

              $pageScrollLink.on('click', function(e){
                  var anchor = $(this),
                      target = anchor.attr('href');
                  pageScroll(target);
                  e.preventDefault();
              });
          
              function pageScroll(target){
                  var ww = Math.max($window.width(), window.innerWidth),
                          offset = ww > 992 ? navHeightShrink : navHeight;
          
                  $htmlBody.stop().animate({
                      scrollTop: $(target).offset().top - (offset - 1)
                  }, 1000, 'easeInOutExpo');
          
                  // Automatically retract the navigation after clicking on one of the menu items.
                  $navbarCollapse.collapse('hide');
              };
          

          只要 'href' 是一个普通的旧“#anchor”,事情就可以正常工作。但是,如果我尝试在不同的文件中使用锚链接,比如“otherfile.php#myanchor”,甚至是完全限定的 URL,比如“https://somesite.com/index.php#section3”,它失败,抛出一个错误,抱怨“顶部”未定义或其他东西。

          有谁知道为什么它只在href是#anchor而不是其他格式时才有效?

          谢谢。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-02-23
            • 2015-07-13
            • 1970-01-01
            • 2016-10-06
            • 1970-01-01
            相关资源
            最近更新 更多