2011-02-16 98 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的早期版本)上效果會更好。

相關問題