2011-05-23 47 views
14

我與backbone.js一起玩耍,我想知道是否有更簡潔的解決方案來創建模型/集合的「無限滾動」情況,而不是模塊I一直在看(有幾個jQuery,可能更適合其他庫)。我想我會在嘗試構建我自己的骨幹解決方案,如果它應該在骨幹集合之外構建的東西,或者如果有人嘗試過類似的東西之前,會問一些搜索。backbone.js的無盡/無限滾動類型解決方案

回答

10

blog post最近登陸我的twitter流。看起來像一個非常好的解決方案,並在main page上運行良好。在博客中,該解決方案的好處是:

  1. 保留後退按鈕。
  2. 不管使用hashbang,不管twitter工程師有多開心。
  3. 如果(1)不可能,就可以無限滾動。
  4. 漸進式增強:當(3)發生時,用戶會遵循良好的超鏈接獲取更多內容。
+0

這很有趣,我會考慮它。 – blueblank 2011-05-23 23:48:05

+3

我剛寫了一個無限的滾動教程也http://backbonetutorials.com/infinite-scrolling/ – 2012-04-28 04:18:18

+0

這篇文章給出了很好的觀點。不過,我個人認爲,不要爲非js回退而感到不適。http://developer.yahoo.com/blogs/ydn/many-users-javascript-disabled-14121.html – albertpeiro 2013-04-28 10:15:22

-1

另一個重複的答案:這是我Backbone.Collection的延伸:

_.extend Backbone.Collection.prototype, 
    options: 
    infinitescroll: 
     success: $.noop 
     error: $.noop 
     bufferPx: 40 
     scrollPx: 150 
     page: 
     current: 0 
     per: null 
     state: 
      isDuringAjax: false 
      isDone: false 
      isInvalid: false 
     loading: 
     wrapper: 'backbone-infinitescroll-wrapper' 
     loadingId: 'backbone-infinitescroll-loading' 
     loadingImg: 'loading.gif' 
     loadingMsg: '<em>Loading ...</em>' 
     finishedMsg: '<em>No more</em>' 
     msg: null 
     speed: 'fast' 

    infinitescroll: (options={})-> 
    # NOTE: coffeescript cannot deal with nested scope! 
    that = @ 

    _.extend(@options.infinitescroll, options.infinitescroll) if options.infinitescroll 

    infinitescroll_options = @options.infinitescroll 

    # where we want to place the load message in? 
    infinitescroll_options.loading.wrapper = $(infinitescroll_options.loading.wrapper) 
    if !infinitescroll_options.loading.msg and infinitescroll_options.loading.wrapper.size() > 0 
     infinitescroll_options.loading.msg = $('<div/>', { 
     id: infinitescroll_options.loading.loadingId 
     }).html('<img alt="'+$(infinitescroll_options.loading.loadingMsg).text()+'" src="' + infinitescroll_options.loading.loadingImg + '" /><div>' + infinitescroll_options.loading.loadingMsg + '</div>') 
     infinitescroll_options.loading.msg.appendTo(infinitescroll_options.loading.wrapper).hide() 
    else 
     infinitescroll_options.loading.msg = null 

    fetch_options = _.omit(options, 'infinitescroll') 
    infinitescroll_fetch =()=> 
     # mark the XHR request 
     infinitescroll_options.state.isDuringAjax = true 

     # increase page count 
     infinitescroll_options.page.current++ 

     payload = { 
     page: infinitescroll_options.page.current 
     } 
     payload['limit'] = infinitescroll_options.page.per if infinitescroll_options.page.per isnt null 

     _.extend(fetch_options, { 
     remove: false 
     data: payload 
     }) 

     if infinitescroll_options.loading.msg 
     # preload loading.loadingImg 
     (new Image()).src = infinitescroll_options.loading.loadingImg if infinitescroll_options.loading.loadingImg 

     infinitescroll_options.loading.msg.fadeIn infinitescroll_options.loading.speed,()-> 
      that.fetch(fetch_options) 
      .success (data, state, jqXHR)=> 
      infinitescroll_options.state.isDuringAjax = false 
      infinitescroll_options.state.isDone = true if _.size(data) is 0 

      infinitescroll_options.loading.msg.fadeOut infinitescroll_options.loading.speed,()-> 
       infinitescroll_options.success.call(data, state, jqXHR) if _.isFunction(infinitescroll_options.success) 
       return 
      return 
      .error (data, state, jqXHR)=> 
      infinitescroll_options.state.isDuringAjax = false 
      infinitescroll_options.state.isInvalid = true 

      infinitescroll_options.loading.msg.fadeOut infinitescroll_options.loading.speed,()-> 
       infinitescroll_options.error.call(data, state, jqXHR) if _.isFunction(infinitescroll_options.error) 
       return 
      return 
      return 

     else 
     that.fetch(fetch_options) 
     .success (data, state, jqXHR)=> 
      infinitescroll_options.state.isDuringAjax = false 
      infinitescroll_options.state.isDone = true if _.size(data) is 0 

      infinitescroll_options.success.call(data, state, jqXHR) if _.isFunction(infinitescroll_options.success) 
      return 

     .error (data, state, jqXHR)=> 
      infinitescroll_options.state.isDuringAjax = false 
      infinitescroll_options.state.isInvalid = true 

      infinitescroll_options.error.call(data, state, jqXHR) if _.isFunction(infinitescroll_options.error) 
      return 
     return 

    $(document).scroll()-> 
     $doc = $(document) 
     isNearBottom =()-> 
     bottomPx = 0 + $doc.height() - $doc.scrollTop() - $(window).height() 

     # if distance remaining in the scroll (including buffer) is less than expected? 
     (bottomPx - infinitescroll_options.bufferPx) < infinitescroll_options.scrollPx 

     return if infinitescroll_options.state.isDuringAjax || infinitescroll_options.state.isDone || infinitescroll_options.state.isInvalid || !isNearBottom() 

     infinitescroll_fetch() 
     return 


    infinitescroll_fetch() 
    return 

https://gist.github.com/mcspring/7655861

+0

您可以使用胖箭頭=>而不是細箭頭,並將外部背景帶到@或_this – 2014-05-19 23:45:06