2011-02-16 60 views
3

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

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

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

这正确地滚动到由“选择”限定的元件,但回调被调用两次(因为$('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(); 
     } 
    }); 
} 
+0

我做了一个粗略的修复,检查函数是否已经运行。有没有另一种方法来解决这个问题呢? – 2011-02-16 17:48:31

回答

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

您是否尝试过使用

$(document.body).animate(...) 
+0

这与$('body')。animate`在Firefox中不起作用相同。 – 2011-02-16 17:47:41

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

因为延期对象只能一次解决,你不能有一个以上的调用回调函数。

+0

在jQuery中的新推迟的东西看起来整洁,但我不知道使用它。此外,将升级到jQuery 1.5打破任何东西(我正在使用jQuery 1.4.2)? – 2011-02-16 18:10:17

+0

@火箭不应该是一个问题,除非有任何插件做不寻常的事情。 – lonesomeday 2011-02-16 18:12:25

+0

延期在这里做布尔检查基本相同的事情,但在一个更迂回的方式。它不会解决任何潜在的问题。 – 2011-02-16 18:14:27

0

如何使用,绵延在整个文档主体,做动画上该分区,而不是一个DIV?您无法确定您可以找到多少浏览器问题(例如,多少浏览器不会为HTML或BODY生成动画)

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的早期版本)上效果会更好。

相关问题