动态div和scrollTop

时间:2012-10-23 16:33:34

标签: javascript jquery offset smooth-scrolling singlepage

我有一个单页网站:

http://chiaroscuro.telegraphbranding.com/

每个部分都根据用户的窗口动态调整大小。我正在试图找出如何在单击链接时将jQuery平滑滚动功能滚动到每个部分的顶部。它适用于第一部分,资助区域,我刚刚使用了一个简单的偏移量()。顶部,但其他部分不起作用,因为他们不知道滚动多远,因为窗口大小总是不同。

我一直试图让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;
            });
        };
    });
});

`

1 个答案:

答案 0 :(得分: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});
    };
});

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

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

上面的代码混合了纯JavaScript和jQuery,elm var是一个普通的DOM元素(这支持scrollIntoView方法)。但是,您正在尝试将jQuery的animate方法链接到混合中 - 您还应该在负责滚动条的元素上触发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或正文,具体取决于浏览器 - 为此您可以使用此:

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);