👆
【Vue】規約を最下部までスクロールしないと押せないチェックボタン
2023/01/27追記
新しくscrollend
というイベントが追加されました。
本記事の方法を使わなくてもscrollend
イベントを使って、より簡単にスクロールの終わりを検知することができそうです!
与件
- 利用規約への同意画面がモーダルで表示される
- 規約文章を最下部までスクロールしないと同意のチェックボタンが押せない
コード
template
<div class="modal-panel">
<div ref="reference" class="scroll-area">
<!-- 利用規約文章 -->
</div>
<div class="agreement">
<checkbox
v-model="isChecked"
:disabled="!isScrollDown"
/>
<span>利用規約に同意する</span>
</div>
</div>
script
import { defineComponent, ref, onMounted } from '@nuxtjs/composition-api'
export default defineComponent({
setup () {
const isScrollDown = ref(false)
const reference = ref(null)
onMounted(() => {
reference.value.onscroll = function () {
const clientHeight = reference.value.clientHeight
const scrollHeight = reference.value.scrollHeight
if (scrollHeight - (clientHeight + reference.value.scrollTop) < 1) {
isScrollDown.value = true
}
}
})
return {
isScrollDown,
reference
}
}
})
解説
Vue.jsのライフサイクルフックであるonMountedを使用しています。onMountedは、コンポーネントがマウントされた後に実行されるフックです。
そこで、onMountedのコールバック関数内で、.onscroll
関数を定義しています。これは、スクロールイベントを監視するための関数です。referenceの参照にはref属性を使用しています。
.clientHeight
は、要素の高さを取得します。
同様に.scrollHeight
は、要素全体のスクロールアウトされた(隠れた)部分も含めた高さを取得します。
引用:https://ja.javascript.info/size-and-scroll#ref-3788
そして、.scrollTop
は、要素の隠された部分の高さを取得します。(つまり、scrollTop
は“どのくらいスクロールされているか”)
引用:https://ja.javascript.info/size-and-scroll#ref-3789
これらを使用して、ユーザーがスクロール要素の末尾に到達したかどうかを検出します。
// 隠された部分も含めた高さ - (表示されている規約文章の高さ + スクロールされた高さ) < 1 の場合
if (scrollHeight - (clientHeight + reference.value.scrollTop) < 1) {
isScrollDown.value = true
}
もしページの末尾に到達した場合、isScrollDown
をtrueに設定します。
チェックボタンには:disabled="!isScrollDown"
が設定されているのでisScrollDown
がtrueになるとdisabledが解除されるといった仕組みです。
Discussion