ビューポートズームiOS 10以降のサファリを無効にしますか?


164

私は私のiPhone 6を更新プラスiOSの10のベータ版にだけモバイルサファリでは、あなたがダブルタップで任意のウェブページをズームしたりピンチができることを発見したIGNOREuser-scalable=noメタタグ内のコードを。バグなのか機能なのかわかりません。機能と見なされる場合、ビューポートズームiOS 10サファリを無効にするにはどうすればよいですか?


iOS 11/12リリースで更新されましたが、iOS 11およびiOS 12のサファリはメタタグを尊重しませんuser-scalable=no

Safariのモバイルgithubサイト


2
アクセシビリティ機能:iOS 10のSafariで注目に
値する

87
いいえ、そうではありません。通常のWebコンテンツでは悪い習慣です。Webアプリの場合、デフォルトのズーム動作は使いやすさを完全に損なう可能性があります。たとえば、チャンネルアップボタンを2度タップしてズームインしたり、ジャンプボタンを2度タップしてビデオゲームの一部をズームインしたりすることはできません。この機能が最初に追加されたのには理由があり、少数の「Webデザイナー」が何をしているのかを知らないからといって、誰にとってもユーザビリティを損なうのは意味がありません。サイトの設計者に悲鳴を上げ、ブラウザの破壊をやめます。
dgatwood 2017年

36
それが「悪い習慣」だと言うのは意見であり、コミュニティがクロスプラットフォームを実装するためにコミュニティが数ヶ月/数年/数十年費やすウェブ標準の採用に固執し、それらに巨大ながらくたを取ることに固執しているという事実を変えるものではありません。なぜAppleは、Webデザイナーが自分のしていることを知らないように指示する必要があるのですか?ひどい議論。
samrap 2017

2
個人的には、これはオンラインのボイラープレートコードに由来すると思います。開発者は、コードの目的がわからないまま、盲目的にコピーアンドペーストします。
ウィリアム・イステッド2017年

7
答えは簡単です、Apple:メタタグを無効にすることをデフォルトのアクセシビリティ設定にします。それを必要とする人は、必要としない人を罰せずに、それを手に入れるでしょう。
ルーベンマルティネスジュニア

回答:


94

iOS 10のSafariでWebページのスケーリングを防止することは可能ですが、ユーザー側でさらに作業が必要になります。ある程度の困難は、カーゴカルトの開発者が「user-scalable = no」をすべてのビューポートタグにドロップして、視覚障害のあるユーザーにとって不必要に困難になることを阻止するべきだという議論だと思います。

それでも、Appleが実装を変更して、ダブルタップによるズームを無効にする簡単な(メタタグ)方法があるようにしてほしいと思います。困難のほとんどは、その相互作用に関連しています。

次のような方法でピンチズームを停止できます。

document.addEventListener('touchmove', function (event) {
  if (event.scale !== 1) { event.preventDefault(); }
}, false);

より深いターゲットがイベントでstopPropagationを呼び出す場合、イベントはドキュメントに到達せず、スケーリング動作はこのリスナーによって妨げられないことに注意してください。

ダブルタップしてズームを無効にする方法も同様です。前のタップから300ミリ秒以内に発生したドキュメントのタップを無効にします。

var lastTouchEnd = 0;
document.addEventListener('touchend', function (event) {
  var now = (new Date()).getTime();
  if (now - lastTouchEnd <= 300) {
    event.preventDefault();
  }
  lastTouchEnd = now;
}, false);

フォーム要素を正しく設定しないと、入力に焦点を合わせると自動ズームが行われ、手動ズームをほとんど無効にしているため、ズームを解除することはほとんど不可能になります。入力フォントサイズが16px以上であることを確認してください。

これをネイティブアプリのWKWebViewで解決しようとしている場合、上記の解決策は実行可能ですが、これはより良い解決策です:https : //stackoverflow.com/a/31943976/661418。また、他の回答で述べたように、iOS 10ベータ6では、Appleがメタタグを尊重するフラグを提供しています。

2017年5月更新:ピンチズームを無効にする古い「タッチスタートでタッチの長さをチェックする」メソッドを、よりシンプルな「タッチムーブでイベントをチェックする」チェックアプローチに置き換えました。誰にとってもより信頼できるはずです。


3
タッチスタートハックには一貫性がないことに注意してください。回避できた場合、非常に不快な状態に陥ります
Sam Saffron

5
例えば。全画面マッピングアプリでは、マッピングアプリケーション(Google Maps JS、Leafletなど)にハードコーディングされたズーム機能があります。Googleはメタタグを追加することをお勧めし<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />ます。ブラウザがメタタグを尊重しない場合、それは非常に悪いブラウザデザインです。非常に悪いデザインのようなもう1つのこれは、スライドによるバック/フォワードアクションであり、iOS 9/10では防止できません。これは、Webアプリケーション内での激しいドラッグ操作を中断します。
TimoKähkönen16年

4
ユーザーが1本の指でドラッグを開始した場合、2本目の指を画面上に置くとピンチズームできます。preventDefaultonを使用すると、ズームとスクロールの両方を無効にできtouchmoveます。スクロールを無効にせずにズームを(完全に)無効にすることはできません。
Paolo

10
うわー、この部分(ここに貼り付けます)はとても役に立ちました。私はこれがインターネット上のどこか他の人によって言及されたのを見たことがありません。この問題を修正するのに何時間もかかりました。私はこれについてAppleのUXデザインの選択に本当にがっかりしています。自動ズームインを形成しますが、ズームアウトしません。If you don't set up your form elements right, focusing on an input will auto-zoom, and since you have mostly disabled manual zoom, it will now be almost impossible to unzoom. Make sure the input font size is >= 16px.
Ryan

6
これはiOS 12ではもう機能していないようです。これをiOS 12で機能させる方法はありますか?
TJR 2019年

78

これはiOS 10の新機能です。

iOS 10ベータ1リリースノートから:

  • SafariのWebサイトでのアクセシビリティを向上させるために、ユーザーはWebサイトuser-scalable=noがビューポートに設定されている場合でもピンチしてズームできるようになりました。

これを何らかの方法で無効にするJSアドオンがまもなく表示されることを期待しています。


4
@Onza:悪くないと思います。いいと思います。ピンチ/ズーム(デフォルトのユーザー動作)を無効にすることは悪いことだと考えられており、多くのモバイルWebサイトがそれを行っています。許容できる唯一のユーザーケースは、アプリのように見えて感じる実際のWebアプリです。
2016

6
悪い。jsを使用してビューポートを変更し、Webサイトで一部の要素が選択されている場合にのみズームをブロックすると、この「決定」のために壊れます。誰かがそれをブロックすると決めた場合-理由があります。
ジェンヤ

9
@カールスそれはゲーム開発者にとって非常にベッドです
Sandeep

14
IOS 10.0.2を使用しています。user-scalable= noを使用すると、ズームが無効になりません...ズームに関する主な問題は、固定サイドメニューにあります。レイアウトを壊すだけです。これに関するアイデアや解決策はありますか?ズームはアクセシビリティに優れていることを理解しています。jsイベント(ハンマー)とcssを使用して、サイトの特定の部分でズームを使用できるようにしました。なぜPC警察が始まっているように、ルールを全員に適用する必要があるのか​​わかりません。私たちの開発世界も引き継ぐ?!
webkit 2016

49
「唯一の許容されるユーザーケースは、アプリのように見えて感じられる実際のWebアプリです。」-あなたは、ではない本当の、許容可能なユースケース、言ったように、これは、あること ...稀に
フローリー

21

touch-action個々の要素のcssプロパティを使用してこれを修正することができました。touch-action: manipulation;リンクやボタンなど、一般的にクリックされる要素を設定してみてください。


1
「操作」はピンチズームを防止せず、ダブルタップズームのみを防止します。
モース2017

4
これは受け入れられる答えになるはずです。を使用touch-action: none;して、すべてのジェスチャーを自分で制御できます。
ガイソファー2017

3
これは素晴らしいことです-ピンチズームを残したままダブルタップズームを無効にします。これはジェスチャと見なす必要があります-ダブルタップはすべきではありません。1匹は犬です。1匹+1匹はスペースシャトルはしません。それは2匹の犬を作ります、そして彼らはあなたが2匹の犬がすることを期待するであろうことをします。私は2匹の犬がスペースシャトルになるとは思っていませんでした。決して。
ラリー

5
@GuySopher iOSは提供しないtouch-action: noneだけmanipulatoinで、ピンチズームの問題がそのまま残ります。
humanityANDpeace

14

この動作はおそらく最新のベータ版で変更されているようです。執筆時点ではベータ版6です。

iOS 10 Beta 6のリリースノートから:

WKWebViewデフォルトuser-scalable=noはビューポートからの尊重になりました。のクライアントはWKWebViewWKWebViewConfiguration プロパティignoresViewportScaleLimitsをに設定することにより、アクセシビリティを向上させ、ユーザーがすべてのページをピンチズームできるようにすることができますYES

ただし、私の(非常に限られた)テストでは、これが事実であることをまだ確認できません。

編集:確認済み、user-scalable=noデフォルトではiOS 10 Beta 6が尊重されています。


11
10.0.1ここ。それを尊重しません。Appleが誰もが必要とする機能を取り除くこととは..
リフワニアン2016

1
これはSafariでWKWebView はないことを意味します。出典:マップアプリの1つが故障し、修正方法がわかりません
Fabio Poloni、2016

ああ!申し訳ありませんが、私は同じバグ/機能の解決策を探しているときにここに来ました。私の答えを書くときにWKWebView元の質問が尋ねたものだとWKWebView思っていました。したがって、最初のベータ版のいずれかで、AppleがWKWebViewモバイルSafariとモバイルSafari の両方の動作を変更したと思います。その後、ベータ6ではWKWebView、モバイルSafariの動作を元に戻しましたが、そのままにしました。
Cellane

1
10.0.2は尊重しませんuser-scalable=no。彼らがなぜこれを元に戻すのか、それを元に戻すのか、それをもう一度削除するのか、私にはわかりません。
エイダンハキミアン2016年

13

現時点でMobile Safariで機能する回避策は、3番目の引数をaddEventListenerbe { passive: false }にすることです。そのため、完全な回避策は次のようになります。

document.addEventListener('touchmove', function (event) {
  if (event.scale !== 1) { event.preventDefault(); }
}, { passive: false });

下位互換性を維持するためにオプションがサポートされているかどうか確認することをお勧めします


3
誰かがこれをiOS 12で試しましたか?上記のコードを追加しましたが、私のwebappでは何もしていません。まだこの愚かなサファリをズームインすることができます。私のメタビューポートタグは次のようになります<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
Patrick DaVader 2018年

1
@PatrickDaVaderうん、iOS 12 Safariの実用的なソリューションが見つかりません。絶え間ないズームから船酔い。
ジェイミーバーチ

1
このiOSの13私の内の1つの作品の<meta>タグは、次のとおり<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover, user-scalable=no, shrink-to-fit=no" /><meta name="HandheldFriendly" content="true">
スターリングボーン

1
@SterlingBourneセットアップをコピーしました。動作しますが、時間の90%だけが好きです。なぜいつもそうではないのかわからない。
Hillcow

1
@SterlingBourne応答は私のために働いた!ありがとう。コメントではなく回答として投稿する必要があるため、<meta name = "viewport" content = "width = device-width、initial-scale = 1、maximum-scale = 1、viewport-fit = cover、 user-scalable = no、shrink-to-fit = no "/>および<meta name =" HandheldFriendly "content =" true ">
Gene Black

8

より堅牢なJavaScriptオプションを探すのに約1時間費やしましたが、見つかりませんでした。たまたまここ数日でhammer.jsをいじっています(Hammer.jsはあらゆる種類のタッチイベントを簡単に操作できるライブラリです)を、ほとんどの場合私がやろうとしていたことで失敗しています。

この警告と、私がJavaScriptの専門家ではないことを理解していると、これは基本的にhammer.jsを利用してピンチズームとダブルタップイベントをキャプチャし、ログに記録して破棄するソリューションです。

ページにhammer.jsが含まれていることを確認してから、このjavascriptを頭のどこかに貼り付けてみてください。

< script type = "text/javascript" src="http://hammerjs.github.io/dist/hammer.min.js"> < /script >
< script type = "text/javascript" >

  // SPORK - block pinch-zoom to force use of tooltip zoom
  $(document).ready(function() {

    // the element you want to attach to, probably a wrapper for the page
    var myElement = document.getElementById('yourwrapperelement');
    // create a new hammer object, setting "touchAction" ensures the user can still scroll/pan
    var hammertime = new Hammer(myElement, {
      prevent_default: false,
      touchAction: "pan"
    });

    // pinch is not enabled by default in hammer
    hammertime.get('pinch').set({
      enable: true
    });

    // name the events you want to capture, then call some function if you want and most importantly, add the preventDefault to block the normal pinch action
    hammertime.on('pinch pinchend pinchstart doubletap', function(e) {
      console.log('captured event:', e.type);
      e.preventDefault();
    })
  });
</script>


私はまた、hammer.jsを操作するときにこの問題を解決しようと試みており.preventDefault、すべてのハンマージェスチャーハンドラーにを追加することで、ビューポートのズームを防止できることを確認できます。私は一緒にスワイプ/ピンチ/パン/タップを使用していますが、それをすべてのハンドラーに追加しました。ジョブを実行している特定のハンドラーがあるかどうかわかりません。
コナン

6

ピンチツーズームについての以前の答えを試しました

document.documentElement.addEventListener('touchstart', function (event) {
    if (event.touches.length > 1) {
        event.preventDefault();
    }
}, false);

ただし、event.touches.length> 1の場合でも画面がズームする ことがあります。画面上で指が動かないようにするために、touchmoveイベントを使用するのが最善の方法であることがわかりました。コードは次のようになります。

document.documentElement.addEventListener('touchmove', function (event) {
    event.preventDefault();      
}, false);

お役に立てば幸いです。


7
これが機能するのは、アプリが完全に適合する場合のみです。スクロール可能なコンテンツがある場合は機能しません。
eljamz

8
これにより、Webサイトでのスクロールも無効になります。悪い
ギャグ

@eljamz教えてくれてありがとう。そうです。私のアプリは画面にぴったりフィットします。
Chihying Wu 2016

@Gagsスクロール機能のテストはまだ行っていません。お知らせください。
Chihying Wu 2016

6

touchoveイベントでスケール係数を確認し、タッチイベントを防止します。

document.addEventListener('touchmove', function(event) {
    event = event.originalEvent || event;
    if(event.scale > 1) {
        event.preventDefault();
    }
}, false);

2
iOS 13はfalseを{passive:false}に変更
wayofthefuture

6

1つのスタイルルールを挿入し、ズームイベントをインターセプトすることで、必要なすべてを取得できます。

$(function () {
  if (!(/iPad|iPhone|iPod/.test(navigator.userAgent))) return
  $(document.head).append(
    '<style>*{cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0)}</style>'
  )
  $(window).on('gesturestart touchmove', function (evt) {
    if (evt.originalEvent.scale !== 1) {
      evt.originalEvent.preventDefault()
      document.body.style.transform = 'scale(1)'
    }
  })
})

pinピンチズームを無効にします。

doubleダブルタップズームを無効にします。

✔スクロールは影響を受けません。

tapタップによるハイライトを無効にします(iOSでは、スタイルルールによってトリガーされます)。

注意:iOS検出を好みに合わせて調整してください。詳細はこちら


lukejacksonPiotr Kowalskiに謝罪します。これらの回答は、上記のコードで変更された形式で表示されます。


これは、iOS 11.2を実行している私のiPadエミュレーターで動作します。iOS 11.3を実行している実際のiPadでは動作しません。console.logを追加して、イベントが発生し、コンソールに表示されることを確認しました。iOS 11.3と関係がありますか?または実際のデバイスで?
Mathieu R.

1
@MathieuR。iOS 11.3の問題です。addEventListenerベースの回答の1つを使用{ passive: false }し、のoptions代わりにパラメーターとして渡すことで修正できますfalse。ただし、下位互換性のためにfalsepassiveオプションフィールドがサポートされていない限り、渡す必要があります。developer.mozilla.org/en-US/docs/Web/API/EventTarget/…を
Josh Gallagher

@JoshGallagher実際の例を教えていただけますか?iOS11では、どの回答も機能しません。
ミック

'gesturestart'-> preventDefaultは、私がiOS 12、2を書いている時点で機能しています
Michael Camden

5

私はかなり素朴な解決策を思いつきましたが、それはうまくいくようです。私の目標は、偶発的なダブルタップがズームインとして解釈されるのを防ぎながら、ピンチ操作でズームしてアクセシビリティを維持することでした。

アイデアは、ダブルタップで最初touchstartと2番目の間の時間を測定し、遅延が小さすぎる場合はtouchend最後のtouchendクリックをクリックとして解釈することです。この方法は、偶発的なズームを防ぎながら、リストのスクロールに影響を与えないように見えるので便利です。私は何も見逃していないかどうかわからない。

let preLastTouchStartAt = 0;
let lastTouchStartAt = 0;
const delay = 500;

document.addEventListener('touchstart', () => {
  preLastTouchStartAt = lastTouchStartAt;
  lastTouchStartAt = +new Date();
});
document.addEventListener('touchend', (event) => {
  const touchEndAt = +new Date();
  if (touchEndAt - preLastTouchStartAt < delay) {
    event.preventDefault();
    event.target.click();
  }
});

mutewinterの要旨Josephの回答に触発されました。


5

私の特定のケースでは、Babylon.jsを使用して3Dシーンを作成しており、ページ全体が1つのフルスクリーンキャンバスで構成されています。3Dエンジンには独自のズーム機能がありますが、iOSではピンチツーズームがそれを妨害します。私の問題を克服するために@Josephの回答を更新しました。これを無効にするには、オプションとして{passive:false}をイベントリスナーに渡す必要があることがわかりました。次のコードは私のために働きます:

window.addEventListener(
    "touchmove",
    function(event) {
        if (event.scale !== 1) {
            event.preventDefault();
        }
    },
    { passive: false }
);

私の使用例は、カスタムのピンチコントロールを備えたフルページの3Dシーンでもあります。ユーザースケールを明示的に無視してAppleに回避策がなければ、私は沈んでいたでしょう。メタはありません。
Nick Bilyk 2018年

1

奇妙に聞こえるかもしれませんが、少なくともiOS 10.2のSafariでは、要素またはその祖先に次のいずれかが含まれている場合、ダブルタップによるズームは魔法のように無効になります。

  1. onClickリスナー-単純なnoopの場合もあります。
  2. cursor: pointerCSS のセット

つまむのはどう?
Sam Su

残念ながら、ピンチズームはこのソリューションの対象外です。:そのために、我々はに提案されたソリューションを使用stackoverflow.com/a/39594334/374196
mariomc

うまくいきません。このテストページを使用してiPod Touchで10.2.1 Beta 4を使用していて、灰色の四角形のズームのいずれかをダブルタップします。jsbin.com
kamuta

1
反応アプリのスパンでこれを使用していますが、機能しません。
FMD

1

次の場合、意図しないズームが発生する傾向があります。

  • ユーザーがインターフェースのコンポーネントをダブルタップする
  • ユーザーが2つ以上の数字(ピンチ)を使用してビューポートを操作する

ダブルタップ動作を防ぐために、2つの非常に簡単な回避策を見つけました。

<button onclick='event.preventDefault()'>Prevent Default</button>
<button style='touch-action: manipulation'>Touch Action Manipulation</button>

これらは両方とも、Safari(iOS 10.3.2)がボタンにズームインするのを防ぎます。ご覧のとおり、1つはJavaScriptのみで、もう1つはCSSのみです。適切に使用してください。

ここにデモがあります:https : //codepen.io/lukejacksonn/pen/QMELXQ

私はピンチ動作を(まだ)防止しようとしませんでした。これは、主にWebのマルチタッチインターフェイスを作成する傾向がないためです。次に、ネイティブアプリのUIを含むすべてのインターフェイスを「ピンチズーム」する必要があると考えました。 -場所でできます。ユーザー UIにアクセスできるようにするために、ユーザーがこれを実行しなくても済むように設計します。


1

ダブルクリックでズームできないように見える、この簡単な回避策が見つかりました:

    // Convert touchend events to click events to work around an IOS 10 feature which prevents
    // developers from using disabling double click touch zoom (which we don't want).
    document.addEventListener('touchend', function (event) {
        event.preventDefault();
        $(event.target).trigger('click');
    }, false);

1

リクエストに応じて、コメントを回答に転送しましたので、人々はそれを賛成できます:

これは、iOS 13の90%の時間で機能します。

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover, user-scalable=no, shrink-to-fit=no" />

そして

<meta name="HandheldFriendly" content="true">


0

上記のすべての回答をiOS(iPhone 6、iOS 10.0.2)の私のページで実際に確認しましたが、成功しませんでした。これは私の実用的な解決策です:

$(window).bind('gesturestart touchmove', function(event) {
    event = event.originalEvent || event;
    if (event.scale !== 1) {
         event.preventDefault();
         document.body.style.transform = 'scale(1)'
    }
});

残念ながら、これはページが完全にフィットする場合にのみ機能し、スクロール可能なコンテンツがある場合には機能しません
Shoe

うーん。私の経験では、これはスクロール可能なコンテンツで正常に機能します(iOS 10.3)。
jeff_mcmahan 2017

0

これは私のために働きました:

document.documentElement.addEventListener('touchmove', function (event) {
    event.preventDefault();
}, false);

私はこれを試しましたが、ピンチズームはできませんでしたが、ビューポートのタッチスクロールが無効になり、ページを上下にスクロールできなくなりました。
TGR
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.