25
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【iOS対応】Vue.jsで背景固定のモーダルを作る

Last updated at Posted at 2019-07-14

モーダルを作る際に面倒なのが、スクロールしたときの背景の固定。
別に背景が動いても直接問題が起きることはないのですが、やっぱり気にはなります。ユーザーにもこのサービス大丈夫かな...と余計な不安感を与えることにもなりますし。

ただ、この背景固定、一筋縄ではいかないのが面倒なところ。とくにiOSは他のデバイスと異なる挙動を示し、AndroidやWebではちゃんと固定されるのにiOSだけ上手くいかない...と悩んでいる人も多いと思います。

何か解決方法はないかと探していたところ、非常に便利なライブラリを見つけたので、それで対応することにしました。

Body Scroll Lockを使う

名前の通り、機能を有効にすることで背景のスクロールを無効にできるライブラリです。便利なのは、ページ全てをスクロール無効にするのではなく、指定したDOM内部だけはスクロールできるように設定できること。
モーダル内部はスクロールさせたい!なんてケースにも対応可能ということです。

githubでのスターも1400個以上ついていますし、ある程度安心して導入できるのもメリットですね。公式サイトはこちら↓

Body Scroll Lock

Body Scroll Lockの使い方

何はともあれ、まずはnpm/yarnでinstallしましょう。

npm install body-scroll-lock

次に、背景固定を行いたいページ(コンポーネント)でimportします。

import { disableBodyScroll, enableBodyScroll, clearAllBodyScrollLocks } from 'body-scroll-lock';

名前からしてそのままですが、背景を固定したい場合はdisableBodyScrollを、解除したい場合はenableBodyScrollを使えばOKです。

たとえば、モーダルコンポーネントに使うならこんな感じ。

ModalLayout.vue
<template>
  <div class="modal-layer">
    <div class="modal">
      <slot />
    </div>
  </div>
</template>

<script>
import {
  disableBodyScroll,
  enableBodyScroll,
  clearAllBodyScrollLocks
} from 'body-scroll-lock';

export default {
  mounted() {
    const modal = document.querySelector('.modal')
    disableBodyScroll(modal)
  },

  beforeDestory() {
    clearAllBodyScrollLocks()
  }
}
</script>

ModalLayoutは親コンポーネントからv-ifで呼ばれる想定のコンポーネントです。
v-ifがtrueになったときにmounted()が走ることと、falseになるとbeforeDestoryが走ることを利用して、モーダルが表示されている場合にのみ背景が固定されるようにしています。

まとめ

非常にシンプルで使いやすいので、背景固定に困っているケースで便利です。モーダル系ライブラリとも簡単に組み合わせられそうなのも良さそうですね。

25
20
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?