hookex
3/18/2019 - 2:42 AM

infinite-scroll

infinite-scroll

<div id="container" class="infinite-scroll">
  <div class="infinite-inner">
    <div class="card">1</div>
    <div class="card">2</div>
    <div class="card">3</div>
    <div class="card">4</div>
    <div class="card">5</div>
  </div>
  <div class="loading">加载中...</div>
</div>
const Default = {
  noMore: false, // TODO
  distance: 50,
  onLoadMore: (e) => {
    console.log('onLoadMore', e)
  }
}

class InfiniteScroll {
  public $wrapper = null;
  public $loading = null;
  public $inner = null;
  public options = {};
  public isLoading = false;

  constructor(element, options) {
    this.$wrapper = $(element);
    this.$loading = this.$wrapper.find('.loading');
    this.$inner =  this.$wrapper.find('.infinite-inner');
    this.options = {
      ...Default,
      ...options,
    }
    
    this._bindEvents();
    
    this._init();
  }
  
  private _init() {
    
  }
  
  private showLoading() {
    this.isLoading = true;
    this.$loading.show();
  }
  
  private hideLoading() {
    this.isLoading = false;
    this.$loading.hide();
  }
  
  private _bindEvents() {
    this.$inner.on('scroll', (e) => {
      console.log(111)
      if (this.isLoading) return;
      
      let {scrollTop, scrollHeight, clientHeight} = e.target;
      
      if (scrollHeight - clientHeight - scrollTop < this.options.distance) {
        this.showLoading();
        this.options.onLoadMore(e);
      }
    })
  }
}

function getItem(txt) {
  return `<div class="card">${txt}</div>`
}

let scroll = new InfiniteScroll('#container', {
  onLoadMore: (e) => {
    setTimeout(_ => {
      let count = scroll.$inner.find('.card').length;
      scroll.$inner.append(getItem(count + 1))
      scroll.hideLoading();
    }, 1000);
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

// common
.infinite-scroll {
  display: flex;
  // flex-wrap: wrap;
  flex-direction: column;
  
  .infinite-inner {
    display: flex;
    flex-direction: column;
    height: 100%;
    overflow: scroll;
  }
  
  .loading {
    display: none;
    align-self: flex-end;
  }
}

.card {
  width: 96%;
  border: 1px solid #888;
  margin: 6px;
  display: flex;
  flex: 0 0 100px;
  align-items: center;
  justify-content: center;
}

// custom 

#container {
  height: 300px;
  width: 300px;
  border: 1px solid red;
  padding: 1px;
}