vue.jsでInfinite Scrollを実装する
ページを下端までスクロールしたら次のページが読み込まれるInfinite Scroll(無限スクロール)をvue.jsで実装する方法を調べてみました.
一般的なInfinite Scrollの実装方法
スクロール可能な要素の scroll
イベントを捕捉して,表示領域の位置を計算します.もし,要素の高さに達している場合は,下端までスクロールされたことになります.
<div class="items"></div>
.items { position: fixed; top: 0; bottom: 0; overflow-y: auto; }
$('.items').on('scroll', function (e) { // jQueryを使う場合 var target = $(e.target); if ((target.scrollTop() + target.outerHeight()) >= e.target.scrollHeight) { console.info('下端までスクロールされたよ'); } // 標準APIのみを使う場合(IEは動かないかも) if ((e.target.scrollTop + e.target.offsetHeight) >= e.target.scrollHeight) { console.info('下端までスクロールされたよ'); } });
vue.jsの実装方法
基本的なアイディアは上記と同じです.
<div class="items" v-on="scroll: scroll"></div>
new Vue({ el: 'body', methods: { scroll: function (e) { if ((e.target.scrollTop + e.target.offsetHeight) >= e.target.scrollHeight) { console.info('下端までスクロールされたよ'); } } } });
なお,スクロール可能な要素と操作したいコンポーネントが入れ子になっている場合はイベントを使うときれいに書けます.下記のように,親コンポーネントで $broadcast
を叩いてイベントをブロードキャストして,子コンポーネントの $on
で受け取ります.
<div class="items" v-on="scroll: scroll"> <div v-component="child"></div> </div>
new Vue({ el: 'body', methods: { scroll: function (e) { if ((e.target.scrollTop + e.target.offsetHeight) >= e.target.scrollHeight) { this.$broadcast('scroll-items-bottom'); } } }, components: { child: { template: 'child-template', created: function () { this.$on('scroll-items-bottom', function() { console.info('下端までスクロールされたよ'); }); } } } });
まとめ
vue.jsでInfinite Scrollを実装する方法を説明しました.
ここで説明した方法は Evernote風のGistクライアント でも採用しています.
ところで,無限スクロールという名称ですが,最後のページにたどり着いたらスクロールが止まるので実は有限スクロールなのでは.まあFacebookやTwitterなら本当に無限になりそうですね.