滚动到页面上的元素,然后运行回调

时间:2011-02-16 17:36:58

标签: javascript jquery

我正在尝试使用jQuery的.animate滚动到页面上的元素,然后执行回调。

搜索后,我发现了这个功能:

function scrollToElement(selector, callback){
    var animation = {scrollTop: $(selector).offset().top};
    $('html,body').animate(animation, 'slow', 'swing', callback);
}

这正确地滚动到'selector'定义的元素,但回调被调用两次(因为$('html,body')包含2个元素)。

我尝试过更改

$('html,body').animate

为:

$(document).animate

$(window).animate

但是,这些都没有做任何事情。

我也尝试将功能更改为:

$('html').animate(animation, 'slow', 'swing', function(){
    $('body').animate(animation, 'slow', 'swing', callback);
});

但是,这使浏览器运行第一个动画然后运行第二个动画,所以我等待两个都运行回调之前运行(我不想这样)。

我发现$('body').scrollTop()仅适用于Chrome,$('html').scrollTop()仅适用于Firefox。

那么,有没有办法(无需下载jQuery插件)让我滚动到Chrome和Firefox中的特定元素(我不关心IE),并执行回调(一次)?

修改

我做了一个粗略的修复,通过制作一个布尔值来检查回调是否已经运行,如果是,则不要再次运行它。

function scrollToElement(selector, callback){
    var animation = {scrollTop: $(selector).offset().top};
    var callback_running = false;
    $('html,body').animate(animation, 'slow', 'swing', function(){
        if(typeof callback == 'function' && !callback_running){
            callback_running = true;
            callback();
        }
    });
}

5 个答案:

答案 0 :(得分:3)

我认为这也应该有用

function scrollToElement(selector, callback){
    var animation = {scrollTop: $(selector).offset().top};
    $('html,body').animate(animation, 'slow', 'swing', function() {
        if (typeof callback == 'function') {
            callback();
        }
        callback = null;
    });
}

答案 1 :(得分:1)

如果您使用的是jQuery 1.5(或可以升级到它),则可以使用新的$.Deferred语法。

$.fn.scrollToElement = function(selector, callback) {
    var def = new $.Deferred(),
        el = this;

    $('html, body').animate({scrollTop: $(selector).offset().top}, 'slow', 'swing', def.resolve);

    if (callback) {
        def.promise().done(function(){
            callback.call(el);
        });
    }
};

$('html, body').scrollToElement('#foo', function() {
    alert('done scrolling');
});

因为延迟对象只能解析一次,所以不能有多次调用回调。

答案 2 :(得分:0)

您是否尝试过使用

$(document.body).animate( ... )

答案 3 :(得分:0)

如何使用延伸到整个文档正文的DIV并在该DIV上执行动画呢?您无法确定您可以找到多少浏览器问题(例如,有多少浏览器不会为HTML或BODY设置动画)

答案 4 :(得分:0)

您应该避免为html和body元素设置动画。您的页面动画将在每个现代或旧浏览器上正常工作,并且回调将在您的函数中添加一个简单条件运行一次(应该如此)。

function scrollToElement(selector, callback){
    var scrollElem='html';
    //animate body for webkit browsers that don't support html animation
    if($.browser.webkit){ 
        scrollElem='body';
    }
    var animation = {scrollTop: $(selector).offset().top};
    $(scrollElem).animate(animation, 'slow', 'swing', callback);
}

只有webkit不支持“html”动画,因此您相应地更改“scrollElem”变量。此外,滚动单个元素(html或body)在旧版浏览器(例如Opera的早期版本)上运行得更好。