新人エンジニアのつぶやき

日々の学びをアウトプットするためのブログです

【フロントエンド】スマホでwebアプリを動かす場合、画面の拡大縮小を無効化する方法

この記事について

いいコードはいい心から

今回はスマホでwebアプリを動かす際の制御についてです。 人為的に画面が拡大縮小してしまう要因として主に2つ存在すると考えています。

  1. 2本指でピンチアウト、ピンチインで画面の拡大縮小する方法
  2. 1本指で画面をダブルタップする方法

上記の2つを無効化することができれば、画面が拡大縮小しないようにすることができるのではないかと考えていくつか試行錯誤しました。今回はその方法を紹介します。

2本指でピンチアウト、ピンチインで画面の拡大縮小する方法を無効化する方法

無効化する方法として2つ挙げられます。

  1. javascript側でDOMの要素にイベント発火時の処理を追加する
  2. cssで制御する

1. javascript側でDOMの要素にイベント発火時の処理を追加する場合

画面を2本指操作している場合にイベントを無効にすることで拡大縮小を無効化します

<script setup lang="ts">
import { ref, onMounted } from 'vue';

const wrapDiv = ref<HTMLElement>();

onMounted(() => {
  if (wrapDiv.value) {
    wrapDiv.addEventListener('touchmove', disableScreenScaling, false);
  }
});

/**
 * 2本指で操作する際に画面の拡大縮小を無効にする処理
 * @param event
 */
const disableScreenScaling = (event: TouchEvent) => {
  if (event.touches.length > 1) {
    event.preventDefault();
  }
};
</script>

<template>
  <div ref="wrapDiv" />
</template>

TouchEventをチェックします

面における現在のすべての接触点を表すすべての Touch オブジェクトが入ります。

とのことなので、こちらで2点以上タッチされている場合はデフォルトの動作をキャンセルすることができます。

2. cssで制御する場合

cssで制御する場合はtouch-actionを使用します 色々指定できるのですが、今回は3つ紹介します。

1: none: ブラウザーがすべてのパンやズームのジェスチャーを扱うことを無効にします。 これと使うと手っ取り早く画面の拡大縮小を無効化できますが、スクロール機能も無効化されてしまうので注意が必要です

2: pan-x: 指 1 本で水平にパンするジェスチャーを有効にします

3: pan-y: 指 1 本で垂直にパンするジェスチャーを有効にします

<template>
  <div class="wrapper-content" />
</template>

<style lang="scss" scoped>
.content-wrapper {
  touch-action: pan-y;
}
</style>

ちなみに私が対応した際はcssで一本指の場合の操作を制御しつつ、javascriptで2本指の操作を無効化するようにしました。部分的に効かないところがあったからです。

1本指で画面をダブルタップして画面の拡大縮小する方法を無効化する方法

無効化する方法として2つ挙げられます。

  1. javascript側でDOMの要素にイベント発火時の処理を追加する
  2. cssで制御する

1: javascript側でDOMの要素にイベント発火時の処理を追加する

1本指で画面をダブルタップした場合にイベントを無効にすることで拡大縮小を無効化します

<script setup lang="ts">
import { ref, onMounted } from 'vue';

const wrapDiv = ref<HTMLElement>();

onMounted(() => {
  if (wrapDiv.value) {
    wrapDiv.addEventListener('touchend', disableDoubleClick, false);
  }
});

/**
 * ダブルタップによる画面の拡大縮小を無効にする処理
 * @param event
 */
const disableDoubleClick = (event: Event) => {
  let isClicked = false;
  if (isClicked) {
    if (event.cancelable) {
      event.preventDefault();
    }
    isClicked = false;
  } else {
    isClicked = true;
    setTimeout(function () {
      isClicked = false;
    }, 500);
  }
};
</script>

<template>
  <div ref="wrapDiv" />
</template>

こちらは500ms以内に2回タップされた場合はダブルタップと認識し、デフォルトの動作をキャンセルすることができます。

2: cssで制御する方法

cssで制御する場合はtouch-actionmanipulationを使用する方法があります。

パンおよびズームのジェスチャーは有効にしますが、ダブルタップでのズームなど、標準外の追加的なジェスチャーを無効します。

と記載されています。

<template>
  <div class="wrapper-content" />
</template>

<style lang="scss" scoped>
.content-wrapper {
  touch-action: manipulation;
}
</style>

しかし、こちらを試したところ、良い効果は得られませんでした。 なので今回はjavascript側で制御する方法を採用しました。

最後に

画面を制御するだけでも色々な方法があることを知りましたし、コンポーネントによっても効いている効いていないがあるのでプログラミングというのは奥が深いなと感じました。