コンテキスト
Libraryビルドを思い出すと、スクロールローディングの必要性は誰にでもあると思います。UIコンポーネントを使う?自分でスクロールイベントを聞く?落とし穴に備えて他の人のUIコンポーネントを使う?従来のスクロールイベントをリッスンする方法は、イベント負荷が高く、パフォーマンス上の問題が発生しやすいものでした。だから、2020年の今日、異なる〜_〜に来ることは可能ではありません。
要素が表示されているかどうかを自動的に「監視」する新しい あり、Chrome 51ではすでにサポートされています。可視性の本質は、対象要素がビューポートと交差することなので、このAPIは「交差点オブザーバー」と呼ばれます。
IntersectionObserverについて
//IntersectionObserver自体がコンストラクタである
//着信コールバック関数は、コールバック関数の着信パラメータは、リスニングされているオブジェクトに関する情報を含む配列である
new IntersectionObserver((change) => {
//do something...
//changeは配列で、それぞれが IntersectionObserverEntry オブジェクトである。
})
1. IntersectionObserver.disconnect()
仕事を聞くのをやめる
2. IntersectionObserver.observe()
対象要素のリスニングを開始する
3. IntersectionObserver.takeRecords()
観測されたすべてのオブジェクトの配列を返す (IntersectionObserverEntry)
4. IntersectionObserver.unobserve()
特定のターゲット要素のリスニングを停止する
//IntersectionObserverEntryオブジェクト内部のプロパティ
1. boundingClientRect ターゲット要素の境界に関する情報を含む DOMRectReadOnly を返す。 Element.getBoundingClientRect()
2. intersectionRatiointersectionRectとboundingClientRectの比率値を返す
3. intersectionRectルート要素とターゲット要素の交差領域を記述した DOMRectReadOnly を返す。
4. isVisibleビューポートに表示されているかどうかをブール値で返す
5. isIntersectingターゲット要素が交差オブザーバオブジェクトのルートと交差している場合、ブール値を返す。 true.真を返した場合、IntersectionObserverEntry は、交差点への変換時の状態を記述する; false を返した場合は、交差状態から非交差状態への変換と判断できる。
6. rootBounds交差領域オブザーバでルートを記述するために使用されるDOMRectReadOnlyを返す
7. targetルートとリージョンの要素が交差して見える。 (Element)
8. timeIntersectionObserverの時間原点から交差点がトリガーされた時間までを記録したタイムスタンプを返す(DOMHighResTimeStamp)
実用的なVUEスクロール無限ローディングコンポーネント
<template>
<div class="scroll-tool" ref="scroll-tool">
<slot></slot>
<div class="loadStatus">
<span v-show="this.noMore">データがない~~~。</span>
<div v-show="!this.noMore&&loading">
<Icon type="ios-loading" class="loadingAnimate"/>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'scroll-tool',
props:{
data: {type: Array,default: () => {}},
// データがすべて読み込まれた
noMore: {type: Boolean,default: false},
loading: {type: Boolean,default: false}
},
data () {
return {
nowOberver: ''
}
},
watch: {
data (value, oldVal) {
this.$nextTick(() => {
// 時間で空にする
this.nowOberver && this.nowOberver.disconnect()
this.nowOberver = new IntersectionObserver((change) => {
// 対象要素がIntersectionObserverオブジェクトと交差するとき、読み込まれるデータがないときは、まだ読み込まれるデータがある
if (change[0].isIntersecting && !this.noMore && !this.loading) {
//changeは IntersectionObserverEntry オブジェクトを含む配列である。
// ローディングを続ける
this.$emit('loadMore')
}
})
const list = this.$refs['scroll-tool'].children[0].children
this.nowOberver.observe(list[list.length - 1])
})
}
},
}
</script>
<style scoped lang="less">
.scroll-tool{
.loadStatus{
font-size: 14px;
display: flex;
justify-content: center;
align-content: center;
padding: 10px 0;
}
.loadingAnimate{
animation: animal 1s infinite linear ;
-webkit-animation: animal 1s infinite linear ;
-webkit-transform-origin: center center;
-ms-transform-origin: center center;
transform-origin: center center;
}
}
//loading Iconの無限回転アニメーションを作成することもできる。
@keyframes animal
{
0%{
transform: rotate(0deg);
-ms-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
}
100%{
transform: rotate(360deg);
-ms-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
}
}
</style>
その他の用途
テイクアウトを注文すると、名店庵のこのページで施術の様子を見ることができます。こんな使い方もできますよ~~~。





