Nuxt.js(Vue.js)でScroll Indicatorを作る
コンポーネント
ScrollIndicator.vue
を作る。
<template>
<div
class="v-scroll--indicator-wrapper"
:style="{ height: height, background: background }"
>
<div
class="v-scroll--indicator"
:style="{ background: color, width: width }"
/>
</div>
</template>
<script>
export default {
name: "ScrollIndicator",
props: {
height: {
type: String,
default: "5px",
required: false,
},
color: {
type: String,
default: "linear-gradient(to right, #FEE645, #FEE645)",
required: false,
},
background: {
type: String,
default: "#F9FAFB",
required: false,
},
},
data() {
return {
scrolled: "",
docHeight: "",
width: "",
}
},
mounted() {
window.addEventListener("load", this.scrollHandler)
window.addEventListener("scroll", this.scrollHandler)
},
destroyed() {
window.removeEventListener("load", this.scrollHandler)
window.removeEventListener("scroll", this.scrollHandler)
},
methods: {
scrollHandler() {
let article = document.getElementById("article")
if (article) {
let articleHeight = article.scrollHeight
this.scrolled =
document.body.scrollTop || document.documentElement.scrollTop
this.docHeight = articleHeight - document.documentElement.clientHeight
this.width = (this.scrolled / this.docHeight) * 100 + "%"
}
},
},
}
</script>
<style scoped>
.v-scroll--indicator-wrapper {
/* position: fixed; */
top: 0;
right: 0;
left: 0;
z-index: 9999;
width: 100%;
margin-top: 0.5rem;
}
.v-scroll--indicator {
width: 0;
height: 100%;
}
</style>
使い方
記事のページのid="article"
を見て判断する。
<div id="article">
...記事
</div>
Headerの下に入れる。
<ScrollIndicator />
モバイルでは表示しない && 記事ページ以外では表示しない場合、
<ScrollIndicator v-show="$route.name === 'slug' && $device.isDesktop" />
SSRだと、v-if
でも行けるみたい。
ポイント
mounted
を使用する。created
では、window
プロパティが読み込めない。articleHeight
は、記事の長さdocument.documentElement.scrollTop
は、スクロールした長さdocument.documentElement.scrollHeight
は、スクロールできる長さdocument.documentElement.clientHeight
は、heightとpaddingの合計から、スクロールバーの幅を引いた高さ(borderは含まない)window.addEventListener
でイベント登録window.removeEventListener
でイベント削除