1

我有一个单页网站:

http://chiaroscuro.telegraphbranding.com/

每个部分都根据用户的窗口动态调整大小。我试图弄清楚当点击链接时如何让 jQuery 平滑滚动功能滚动到每个部分的顶部。它对于第一部分,资金领域非常有用,我只使用了一个简单的 offset().top,但其他部分不起作用,因为它们不知道滚动多远,因为窗口大小总是不同的。

我一直试图让 offset() 或 position() 工作,但没有骰子。我很感激任何建议。

这是我的 jQuery:

`

$(document).ready(function () {
    var slowScrollFunding = $('#funding-areas').offset().top;
    var slowScrollAbout = $('#about-us').offset().top;
    var slowScrollProjects = $('#our-projects').offset().top + 600;
    panelOpen = true;
    $('#anchor-funding-areas').click(function(event) {
        event.preventDefault();
        if(panelOpen == true) {
            $('#slide-panel-content').stop(true, true).animate({height: '0px'}, 600, function() {
                $('#panel-content-container').hide();
                $('.scrollableArea').css('z-index', '11');
                // Scroll down to 'slowScrollTop'
                $('html, body, #home-wrap').animate({scrollTop:slowScrollFunding}, 1000);
                panelOpen = false;
            });
        }else{
            $('html, body, #home-wrap').animate({scrollTop:slowScrollFunding}, 1000);
        };
    });
    $('#anchor-aboutus').click(function(event) {
        event.preventDefault();
        if(panelOpen == true) {
            $('#slide-panel-content').stop(true, true).animate({height: '0px'}, 600, function() {
                $('#panel-content-container').hide();
                $('.scrollableArea').css('z-index', '11');
                // Scroll down to 'slowScrollTop'
                $('html, body, #aboutus-wrap').animate({scrollTop:slowScrollAbout}, 1000);
                panelOpen = false;
            });
        }else{
            $('html, body, #home-wrap').animate({scrollTop:slowScrollAbout}, 1000);
        };
    });
    $('#anchor-ourprojects').click(function(event) {
        event.preventDefault();
        if(panelOpen == true) {
            $('#slide-panel-content').stop(true, true).animate({height: '0px'}, 600, function() {
                $('#panel-content-container').hide();
                $('.scrollableArea').css('z-index', '11');
                // Scroll down to 'slowScrollTop'
                $('html, body, #home-wrap').animate({scrollTop:slowScrollProjects}, 1000);
                panelOpen = false;
            });
        }else{
            $('html, body, #home-wrap').animate({scrollTop:slowScrollProjects}, 1000);
        };
    });
    $('#header-logo').add('.homelink').click(function() {
        if(panelOpen == false) {
            $('.scrollableArea').css('z-index', '0');
            $('#panel-content-container').show();
            $('#slide-panel-content').stop(true, true).animate({height: '389px'}, 600, function() {
                // Scroll down to 'slowScrollTop'
                panelOpen = true;
            });
        };
    });
});

`

4

1 回答 1

0

$.offset并且$.position可能有点不可靠,特别是如果您有很多复杂的布局正在进行 - 就像您的页面一样。我过去使用的是以下技巧:

var de = document.documentElement ? document.documentElement : document.body;
var elm = $('get_your_anchor_element').get(0);
var destScroll, curScroll = de.scrollTop;

/// check for the function scrollIntoView
if ( elm.scrollIntoView ) {
  /// get the browser to scrollIntoView (this wont show up yet)
  elm.scrollIntoView();
  /// however the new scrollTop is calculated
  destScroll = de.scrollTop;
  /// then set the scrollTop back to where we were
  de.scrollTop = curScroll;
  /// you now have your correct scrollTop value
  $(de).animate({scrollTop:destScroll});
}
else {
  /// most browsers support scrollIntoView so I didn't bother
  /// with a fallback, but you could just use window.location
  /// and jump to the anchor.
}

以上可以发生在点击事件上。唯一需要改进的是不同的浏览器在不同的基本元素(body 或 html)上滚动。当我使用它时,我有自己的可滚动元素,所以我不需要弄清楚代理正在使用哪个元素......当我得到第二个时,我会看看我是否能找到一个很好的代码来检测区别。

以上在我测试过的所有现代浏览器(Firefox、Safari、Chrome)中都有效,但是我不需要支持 Internet Explorer,所以我不确定。

更新:

我不太确定您的实施发生了什么 - 页面内容可能如此繁重以至于您实际上可以看到正在发生的.scrollIntoView()事情 - 这从来不是我的经验,但是我没有那么多事情要做在屏幕上。考虑到这一点,我已经实现了一个简单的系统,我建议您使用并构建您需要的每个额外部分:

http://pebbl.co.uk/stackoverflow/13035183.html

这样你就知道你有一个可以工作的系统,并且很容易发现是什么阻止了它的工作。关于 chiaro.js,您的实现似乎没问题 - 如果在文件的许多不同区域有点爆炸 - 但是这部分有点错误:

$('#anchor-aboutus').click(function() {
    event.preventDefault();
    if(panelOpen == true) {
        $('#slide-panel-content')
                      .stop(true, true)
                      .animate({height: '0px'}, 600, function() {
            $('#panel-content-container').hide();
            $('.scrollableArea').css('z-index', '11');
            elm.scrollIntoView(true)
                              .animate({scrollTop:destScroll}, 1000);
            panelOpen = false;
        });
    }else{
        elm.scrollIntoView(true).animate({scrollTop:destScroll});
    };
});

在上面的代码中,您只会得到destScrollif的正确值panelOpen === true。啊,实际上我还发现了另一个问题 - 这将解释为什么它不起作用:

elm.scrollIntoView(true)
  .animate({scrollTop:destScroll}, 1000);

上面的代码混合了纯 JavaScript 和 jQuery,elmvar 是一个普通的 DOM 元素(支持 scrollIntoView 方法)。但是您随后尝试将animatejQuery 的方法链接到混合中 - 您还应该在负责滚动条的元素上触发 animate 方法。你应该使用如下:

$('#anchor-aboutus').click(function(e) {
  var currentScroll, destScroll;
  e.preventDefault();
  if(panelOpen == true) {
    $('#slide-panel-content')
      .stop(true, true)
      .animate({height: '0px'}, 600, function() {
        $('#panel-content-container').hide();
        $('.scrollableArea').css('z-index', '11');
        currentScroll = de.scrollTop;
        elm.scrollIntoView(true);
        destScroll = de.scrollTop;
        de.scrollTop = currentScroll;
        $(de).animate({scrollTop:destScroll}, 1000);
        panelOpen = false;
      });
  }else{
    currentScroll = de.scrollTop;
    elm.scrollIntoView(true);
    destScroll = de.scrollTop;
    de.scrollTop = currentScroll;
    $(de).animate({scrollTop:destScroll}, 1000);
  };
});

但是,您还需要做的是确保您的de元素指向正确的元素 - html 或 body 取决于浏览器 - 为此您可以使用:

var de;

/// calculate which element is the scroller element
$('body, html').each(function(){
  if ( this.scrollHeight > this.offsetHeight ) {
    de = this;
    return false;
  }
});

alert( $(de).is('body') ) /// will be true for Chrome, false for Firefox.

您将需要使用此代码代替以下代码:

var de = document.documentElement ? document.documentElement : document.body;

更改您使用的代码的原因如下:

/// store the current scroll position from the de element
currentScroll = de.scrollTop;
/// get the browser to do the scrollTo calculation
elm.scrollIntoView(true);
/// store where the browser scrolled to behind the scenes
destScroll = de.scrollTop;
/// reset our scroll position to where we were before scrollIntoView()
/// if you don't reset then the animation will happen instantaneously
/// because that is what scrollIntoView does.
de.scrollTop = currentScroll;
/// wrap the normal dom element de with jquery and then animate
$(de).animate({scrollTop:destScroll}, 1000);
于 2012-10-23T17:31:06.223 回答