Skip to content

Instantly share code, notes, and snippets.

@ykob
Last active May 18, 2020 11:52
Show Gist options
  • Save ykob/67dec659024ab4defbf6a6bfc44ab039 to your computer and use it in GitHub Desktop.
Save ykob/67dec659024ab4defbf6a6bfc44ab039 to your computer and use it in GitHub Desktop.
It is the rough asset of attaching the scroll effect with the Vue components.
<template>
<div></div>
</template>
<script>
export default {
created() {
window.addEventListener("resize", this.resize);
window.addEventListener("scroll", this.scroll);
this.resize();
},
methods: {
resize() {
this.$store.commit("resize", {
x: document.body.clientWidth,
y: window.innerHeight
});
},
scroll() {
this.$store.commit("scroll", window.pageYOffset);
}
}
};
</script>
<style></style>
<template>
<div>
<slot
:isIncludedScroll = "isIncludedScroll"
/>
</div>
</template>
<script>
export default {
data() {
return {
updateClientRectIterate: 0,
top: 0,
bottom: 0,
isIncludedScroll: false
};
},
watch: {
"$store.state.resolution"() {
this.updateClientRectIterate = 0;
this.updateClientRect();
},
"$store.state.scrollTop"() {
this.judgeBeIncludedScroll();
}
},
mounted() {
this.updateClientRect();
},
methods: {
updateClientRect() {
const rect = this.$el.getBoundingClientRect();
const top = this.$store.state.scrollTop + rect.top;
// ページロード直後はスクロールイベントが多発することがあるため、
// 正常に要素の位置を取得できない。
// なので数回位置情報取得の処理を実行して、
// 位置のズレがなくなったのを見越して要素の位置情報を確定とする。
if (this.updateClientRectIterate < 10) {
if (this.top === top) {
this.updateClientRectIterate++;
}
this.top = top;
requestAnimationFrame(this.updateClientRect);
} else {
this.bottom = top + rect.height;
this.judgeBeIncludedScroll();
}
},
judgeBeIncludedScroll() {
const { state } = this.$store;
if (
state.visibleAreaTop >= this.top &&
state.visibleAreaBottom <= this.bottom
) {
this.isIncludedScroll = true;
}
}
}
};
</script>
<style></style>
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
scrollTop: 0,
visibleAreaTop: 0,
visibleAreaBottom: 0,
resolution: {
x: 0,
y: 0
}
},
mutations: {
resize(state, { x, y }) {
state.resolution.x = x;
state.resolution.y = y;
},
scroll(state, scrollTop) {
state.scrollTop = scrollTop;
state.visibleAreaTop = state.scrollTop + state.resolution.y * 0.9;
state.visibleAreaBottom = state.scrollTop + state.resolution.y * 0.1;
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment