表示

v-b-visibleは、要素がビューポートに表示された時、およびビューポートから外れた時(または表示されなくなった時)に反応できる軽量なディレクティブです。

BootstrapVue v2.1.0以降で使用可能です。

概要

  • v-b-visibleは、要素が表示されているか(ビューポートと交差しているか)どうかを示すブール値を指定して、コールバックメソッドを呼び出します。
  • このディレクティブは、ほとんどの要素やコンポーネントに配置できます。
  • 要素がビューポート内(またはビューポートの一部内)、あるいはオプションのオフセット内にある限り、表示状態の変化(display: noneなど)も検出できます。注:v-if="false"による非表示状態への遷移は検出できません
  • 内部的に、BootstrapVueは<b-img-lazy>などのいくつかのコンポーネントでこのディレクティブを使用しています。
  • v-b-visibleディレクティブは、IntersectionObserverのブラウザサポートが必要です。IntersectionObserverをサポートしていない古いブラウザでは、ポリフィルを使用する必要があります。
  • IntersectionObserverのサポートが検出されない場合、v-b-visibleは要素が常に表示されていると見なし、引数をtrueに設定してコールバックを1回呼び出します。

ディレクティブの構文と使用方法

<div v-b-visible.[mod1].[mod2]="callback">content</div>

callbackが必要な場合

  • 表示状態が変わるたびに呼び出される関数参照。コールバックには、単一のブール値の引数が渡されます。trueは、要素がビューポート内で交差している(部分的または完全に表示されている)ことを示し、falseは要素がビューポートと交差していない/表示されていないことを示します。 once修飾子が使用されている場合を除き、要素の表示状態が変わるたびにコールバックが呼び出されます。(詳細は下記参照)

[mod1]または[mod2]は(すべてオプション)

  • ピクセル単位で表される正の整数。ビューポートの端から離れたオフセット(マージン)を表し、要素がビューポート内にある(またはビューポートに入る直前である)とみなされるかどうかを決定します。この値はビューポートの周囲にマージンを追加します。デフォルト値は0です。
  • キーワードonce。この修飾子が存在する場合、コールバックは要素が初めて表示された時(引数trueは要素が交差/表示されていることを示す)にのみ呼び出されます。 コールバックは、それ以前にfalse(要素が交差/表示されていないことを示す)の引数で呼び出される可能性があります

修飾子の順序は重要ではありません。

使用例

すべてのケースで、コールバック関数は必須です。

基本(修飾子なし)

<template>
  <div v-b-visible="visibleHandler"> ... </div>
</template>
<script>
export default {
  methods: {
    visibleHandler(isVisible) {
      if (isVisible) {
        // Do something
      } else {
        // Do something else
      }
    }
  }
}
</script>

ビューポートオフセット修飾子付き

この例では、修飾子の値は350pxを表します(要素が物理的なビューポートの外側に少なくとも350pxある場合、「表示されている」と見なされます)

<template>
  <div v-b-visible.350="visibleHandler"> ... </div>
</template>
<script>
export default {
  methods: {
    visibleHandler(isVisible) {
      if (isVisible) {
        // Do something
      } else {
        // Do something else
      }
    }
  }
}
</script>

once修飾子付き

<template>
  <div v-b-visible.once="visibleHandler"> ... </div>
</template>
<script>
export default {
  methods: {
    visibleHandler(isVisible) {
      if (isVisible) {
        // This will only ever happen once, when the
        // element has become visible for the first time
      } else {
        // This may happen zero or more times before
        // the element becomes visible, but will never
        // happen after the element has become visible
      }
    }
  }
}
</script>

onceとオフセット修飾子の両方付き

<template>
  <div v-b-visible.once.350="visibleHandler"> ... </div>
</template>
<script>
export default {
  methods: {
    visibleHandler(isVisible) {
      if (isVisible) {
        // This will only ever happen once, when the
        // element is outside of the physical viewport
        // by at least 350px for the first time
      } else {
        // This may happen zero or more times before
        // the element becomes visible, but will never
        // happen after the element has become visible
      }
    }
  }
}
</script>

ライブ例

2つの一般的なユースケースを示すライブ例を2つ紹介します。

スクロールされたコンテンツの表示

コンテナをスクロールして、<b-badge>がビューにスクロールインしたときの反応を確認します。要素がビューポートからスクロールアウトした場合も、表示状態が変わります。

<template>
  <div>
    <div
      :class="[isVisible ? 'bg-info' : 'bg-light', 'border', 'p-2', 'text-center']"
      style="height: 85px; overflow-y: scroll;"
    >
      <p>{{ text }}</p>
      <b-badge v-b-visible="handleVisibility">Element with v-b-visible directive</b-badge>
      <p>{{ text }}</p>
    </div>
    <p class="mt-2">
      Visible: {{ isVisible }}
    </p>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        isVisible: false,
        text: `
          Quis magna Lorem anim amet ipsum do mollit sit cillum voluptate ex nulla
          tempor. Laborum consequat non elit enim exercitation cillum aliqua
          consequat id aliqua. Esse ex consectetur mollit voluptate est in duis
          laboris ad sit ipsum anim Lorem. Incididunt veniam velit elit elit veniam
          Lorem aliqua quis ullamco deserunt sit enim elit aliqua esse irure. Laborum
          nisi sit est tempor laborum mollit labore officia laborum excepteur commodo
          non commodo dolor excepteur commodo. Ipsum fugiat ex est consectetur ipsum
          commodo tempor sunt in proident. Non elixir food exorcism nacho tequila tasty.
        `
      }
    },
    methods: {
      handleVisibility(isVisible) {
        this.isVisible = isVisible
      }
    }
  }
</script>

<!-- v-b-visible-scroll.vue -->

once修飾子と組み合わせることで、ユーザーがページまたはスクロール可能なdivの一番下までスクロールしたかどうか(つまり、「利用規約全体を読んだ」かどうか)を確認するといったユースケースがあります。

CSS displayによる表示状態の検出

ボタンをクリックして<div>の表示状態を変更します。要素がビューポートからスクロールアウトした場合も、表示状態が変わります。

<template>
  <div>
    <b-button @click="show = !show" class="mb-2">Toggle display</b-button>
    <p>Visible: {{ isVisible }}</p>
    <div class="border p-3" style="height: 6em;">
      <!-- We use Vue's `v-show` directive to control the CSS `display` of the div -->
      <div v-show="show" class="bg-info p-3">
        <b-badge v-b-visible="handleVisibility">Element with v-b-visible directive</b-badge>
      </div>
    </div>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        show: true,
        isVisible: false
      }
    },
    methods: {
      handleVisibility(isVisible) {
        this.isVisible = isVisible
      }
    }
  }
</script>

<!-- v-b-visible-display.vue -->

参照

IntersectionObserverの詳細については、MDNドキュメントを参照してください。

ディレクティブリファレンス

個々のディレクティブのインポート

次の名前付きエクスポートを使用して、個々のディレクティブをプロジェクトにインポートできます。

ディレクティブ
名前付きエクスポート
インポートパス
v-b-visibleVBVisiblebootstrap-vue

import { VBVisible } from 'bootstrap-vue'
// Note: Vue automatically prefixes the directive name with 'v-'
Vue.directive('b-visible', VBVisible)

Vue.jsプラグインとしてインポート

このプラグインには、上記にリストされているすべての個々のディレクティブが含まれています。

名前付きエクスポート
インポートパス
VBVisiblePluginbootstrap-vue

import { VBVisiblePlugin } from 'bootstrap-vue'
Vue.use(VBVisiblePlugin)