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

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

搜索后,我发现了这个function:

 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 

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

我也尝试将function更改为:

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

我认为这也应该有效

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

如果您使用的是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'); }); 

由于延迟对象只能解析一次,因此您不能对回调进行多次调用。

你尝试过使用过吗?

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

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

你应该避免动画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的早期版本)上工作得更好。