スクロールをしたときに、DOM操作をしたいときのtipsです。
例えば、スクロールに応じて色を変えたり、高さを変えたり・・。
スクロールすると消えるタイトルを例にVue.jsでのDOM操作を理解します
スクロールすると消えるタイトル
index.vue
<template>
<div class="sample">
<!-- スクロールすると消えるタイトル -->
<h2 :style="hiddenStyle" class="sample__title--hidden">タイトル</h2>
</div>
</template>
テンプレートにはこんなかんじで :style
を定義してます。
hiddenStyle
は好きな変数を書いてあげればOK。
index.vue
<script>
export default {
data() {
return {
// タイトルの座標を保持
targetRect: 0,
hiddenStyle: {}
};
},
mounted() {
window.addEventListener('scroll', this.handleScroll);
},
destroyed() {
window.removeEventListener('scroll', this.handleScroll);
},
methods: {
handleScroll() {
// タイトルを取得
const title = document.querySelector(`.sample__title--hidden`);
// タイトルの座標を取得
const rect = title.getBoundingClientRect().top;
// data()のtargetRectを更新
this.targetRect = rect;
// タイトルの座標がTOPから15px以上になったら隠す
if (this.targetRect > 15) {
this.$set(this.hiddenStyle, 'visibility', 'hidden');
} else {
this.$set(this.hiddenStyle, 'visibility', 'visible');
}
}
}
};
</script>
コードには下記のことが書いてあります。
- dataにスクロールの座標を登録
- dataにhiddenStyleを定義
- mountedで、インスタンスがマウントされた後に実行する処理を書く
(スクロールされたときhandleScrollメソッドが呼ばれるイベント) - destroyedで、インスタンスが破棄された後に実行する処理を書く
(イベントリスナを削除) - methodsにスクロールされたときの処理を書く
ちなみに、element.scrollTop
は相対座標、element.getBoundingClientRect
は絶対座標を取得できます。
注意
今回のようにタイトルを消す際に v-show
を使うことはできません。
なぜなら、 v-show
は display: none
だからです。
スクロールして条件がtrueになった場合、一度 display: none
が適用されると、要素自体が消えて取得できなくなり、スクロールイベントが発火しません。
要素を消すのではなく、visibility: hidden
で隠してください。
(わたしは最初v-showを使って困りました笑)
参考
ライフサイクルのダイアグラム | Vue.js
element.getBoundingClientRect | JavaScript