2011-04-01 55 views
3

我想在滾動結束後立即調用一個函數。我曾嘗試不同的東西,沒有一個是有相當工作了負載,然後我在SO臨到這個解決方案:如何在滾動結束後調用函數?

How do I know when I've stopped scrolling Javascript

我參加了一個很好看的第二個答案,試了一下 - 有用。然後,我試圖稍微改變它爲我的目的。所以現在整個shebang看起來像這樣:

<!DOCTYPE html> 
<html> 

<head> 
<meta content="text/html; charset=utf-8" http-equiv="Content-Type"> 
<title>Do something after scroll ends</title> 

<style type="text/css"> 
    #scrollableDiv{ 
     width:500px; 
     height:100px; 
     overflow:scroll; 
    } 

    #someContent{ 
     width:600px; 
     height:200px; 
    } 
</style> 

<script type="text/javascript" src="scripts/jquery-1.5.1-min.js"></script> 

<script type="text/javascript"> 
    $(document).ready(function() { 

     $('#scrollableDiv').bind('scroll', bodyScroll); 

     var scrollTimer = -1; 

     function bodyScroll() { 
      console.log('scrolling.'); 

      if (scrollTimer != -1) 
       clearTimeout(scrollTimer); 

      scrollTimer = window.setTimeout('scrollEnded()', 500); 

     }; 

     function scrollEnded(){ 
      console.log('scrollEnded. Now do something astounding.'); 
     }; 

    }); 
</script> 

</head> 

<body> 

<div id="scrollableDiv"> 
    <div id="someContent"> 
     Scroll me. 
    </div> 
</div> 

</body> 
</html> 

當我運行這個,滾動事件觸發器(很棒!)。

然後,不是調用我的「scrollEnded()」函數,而是產生一個錯誤:「scrollEnded未定義」。我試圖通過進入調試模式並逐步完成腳本來弄清楚這是從哪裏來的,但後來我發現了一個「匿名函數」 - 這是我對目前對這個問題的理解的極限。我試着將scrollEnded()函數移到頂端。我試過各種各樣的東西...

我該怎麼做才能做到這一點? (可以這個東西有用嗎?)

+2

請勿將字符串傳遞給'setTimeout'和'setInterval'。這是變相的「評估」,每次你評估的時候,忍者都會殺死一隻可愛的小動物。 – 2011-04-01 15:38:14

回答

1

該jQuery throttle/debounce plugin是完美的。使用at_begin = false在最後執行回調。

var scrollEnded = $.debounce(500, false, function() 
{ 
    console.log('scroll ended'); 
}); 

$('#scrollableDiv').scroll(scrollEnded); 

Demo

+0

@ Matt。這完全按照我想要的方式工作。完善。謝謝。 – cfouche 2011-04-03 07:29:16

0

對不起,我完全忽略了這個函數在閉包中的事實,因此在我以前的回覆中沒有提供給頁面。你可以把它通過類似工作:

window.scrollEnded = function() { console.log('scrollEnded. No do something astounding'); } 

接着是

window.setTimeout(window.scrollEnded, 500); 

這應該刪除的字符串的eval,以及把它在全球範圍內的地方可用。在命名空間污染方面還有其他一些古怪的東西,但是暫時我試圖讓它變得簡單一些,並幫助你實現它。

+1

避免在setTimeout中使用字符串,這使用eval被認爲是不好的做法。而是使用一個匿名函數,例如:scrollTimer = setTimeout(function(){scrollEnded();},500); – JaredMcAteer 2011-04-01 15:38:57

+0

我試過這個,它工作...爲什麼「-1」?是編輯之前的解決方案? – cfouche 2011-04-03 06:18:45

+0

初始設置使用引號進行滾動,這會強制您通常希望遠離的eval調用。真的只是一個嘗試快速回答的人造物品。 – whoughton 2011-04-03 18:29:04

0

你有沒有試過把scrollEnded()放在bodyScroll()之上?

function scrollEnded(){ 
    console.log('scrollEnded. Now do something astounding.'); 
}; 
function bodyScroll() { 
    console.log('scrolling.'); 

    if (scrollTimer != -1) 
     clearTimeout(scrollTimer); 

    scrollTimer = window.setTimeout('scrollEnded()', 500); 

}; 
+1

這使零差異。 – Raynos 2011-04-01 15:40:34

+0

是的 - 試圖沒有成功,如問題中所述。 – cfouche 2011-04-03 06:20:51

1

作爲除了這一切的答案,我只會建議設置而不是500 200ms的200ms的超時是手指移動,眼睛期待看到效果之間的平均人眼的反應。 200ms的超時時間應該足夠短,以便而不是被用戶注意,並且足夠長的時間讓javascript觸發並完成事件。 我試過200ms之前,它似乎工作得很好,即使在較慢的PC上。

相關問題