2011-06-01 46 views
2

看看下面的代碼(另外,你需要jquery.js,jquery.viewport.jsjquery.scrollTo.js)。什麼可以使jQuery的解除綁定功能不能按預期工作?

我希望從這個腳本的行爲是每當我滾動頁面,紅色行(<tr>元素與alwaysVisible類)應該剛好插入該表的最頂部可見行(<tr>元)下方。然後,應該滾動頁面,以便這些紅色行中的第一行在視口頂部「正好」出現。實際上發生的是makeVisibleWhatMust();被重複調用,直到我到達頁面的末尾。我認爲$(window).unbind('scroll');會保持makeVisibleWhatMust();不再被調用,但顯然這是行不通的。

任何想法爲什麼?

這裏是JavaScript我寫道:

function makeVisibleWhatMust() 
{ 
    $('#testContainer').text($('#testContainer').text() + 'called\n'); 
    $('table.scrollTable').each 
    (
    function() 
    { 
     var table = this; 
     $($('tr.alwaysVisible', table).get().reverse()).each 
     (
    function() 
    { 
     $(this).insertAfter($('tr:in-viewport:not(.alwaysVisible)', table)[0]); 
    } 
    ); 
     $(window).unbind('scroll'); 
     $(window).scrollTo($('tr.alwaysVisible')[0]); 
     $(window).bind('scroll', makeVisibleWhatMust); 
    } 
); 
} 

$(document).ready 
(
    function() 
    { 
    $(window).bind('scroll', makeVisibleWhatMust); 
    } 
); 

這裏是一個HTML頁面來測試它:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
    <head> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
    <title>Scroll Tables Test Page</title> 

    <script type="text/javascript" src="jQuery.js"></script> 
    <script type="text/javascript" src="jquery.viewport.js"></script> 
    <script type="text/javascript" src="jquery.scrollTo.js"></script> 
    <script type="text/javascript" src="scrollTable.js"></script> 

    <style type="text/css"> 
     table th, table td 
     { 
    border: 1px solid #000; 
    padding: .3em; 
     } 
     .alwaysVisible 
     { 
    background: #F66; 
     } 
    </style> 
    </head> 
    <body> 
    <table class="scrollTable"> 
     <thead> 
    <tr class="alwaysVisible"> 
     <th>Row name</th> 
     <th>Content</th> 
    </tr> 
    <tr class="alwaysVisible"> 
     <th>Row 2</th> 
     <th>Row 2</th> 
    </tr> 
     </thead> 
     <tbody> 
    <script type="text/javascript"> 
     for(var i = 0; i < 50; ++i) 
     { 
     document.writeln("<tr><td>Row " + i + "</td><td>Content</td></tr>"); 
     } 
    </script> 
     </tbody> 
     <tfoot> 
    <tr> 
     <td>Footer</td> 
     <td>Footer 2</td> 
    </tr> 
     </tfoot> 
    </table> 
    <div id="testContainer">TEST CONTAINER</div> 
    </body> 
</html> 

回答

0

我覺得你的問題是,scrollTo使用animate

// From the plugin's source 
function animate(callback){ 
    $elem.animate(attr, duration, settings.easing, callback && function(){ 
     callback.call(this, target, settings); 
    }); 
}; 

and animate使用定時器執行 動畫。結果是.scrollTo將在滾動完成之前返回,並且您將重新綁定滾動處理程序,而scrollTo仍在滾動。因此,當你不期待他們的事件。

一個簡單的方法是使用一個標誌,告訴makeVisibleWhatMustscrollTo的滾動和使用scrollTo回調清除標誌,當它完成,像這樣:

function makeVisibleWhatMust() { 
    // Ignore the event if we're doing the scrolling. 
    if(makeVisibleWhatMust.isScrolling) 
    return; 
    $('#testContainer').text($('#testContainer').text() + 'called\n'); 
    $('table.scrollTable').each(function() { 
     var table = this; 
     $($('tr.alwaysVisible', table).get().reverse()).each(function() { 
     $(this).insertAfter($('tr:in-viewport:not(.alwaysVisible)', table)[0]); 
     }); 
     makeVisibleWhatMust.isScrolling = true; 
     $(window).scrollTo($('tr.alwaysVisible')[0], { 
     onAfter: function() { makeVisibleWhatMust.isScrolling = false; } 
     }); 
    } 
); 
} 
makeVisibleWhatMust.isScrolling = false; 

而且這裏有一個現場版這似乎工作:http://jsfiddle.net/ambiguous/ZEx6M/1/

+0

@mu太短:我認爲你是對的問題,但你的解決方案不起作用。我得到和以前完全一樣的結果。現在我真的不明白。 – Shawn 2011-06-01 20:40:46

+0

@Shawn:我在JavaScript中輸入了一個錯字(太多的右括號)。我修正了這個問題並添加了一個jsfiddle鏈接。 – 2011-06-01 20:55:28

+0

@mu太短:所以它工作!這非常令人好奇,因爲當我在「本地」測試時,完全相同的代碼不起作用,但在JSFiddle中起作用。我想知道我的「本地設置」(在文本文件中保存代碼並在Firefox中打開html文件)和JSFiddle(也在Firefox中運行)之間的這種行爲差異可以解釋爲什麼。我想這個問題值得自己去考慮。無論如何,感謝(工作)解決方案! – Shawn 2011-06-01 21:06:32

相關問題