iOS 10 から <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">
が機能しなくなりました。
具体的には initial-scale=1
, minimum-scale=1
, maximum-scale=1
, user-scalable=no
の解釈が変更になり、特に user-scalable=no
は iOS Safari において完全に無視されるようになりました。 (WKWebKitでは抑止可能です、後述しています)
ブラウザゲームなどでは、ユーザが意図せずボタンや画面を連打するケースが多く user-scalable=no
が 意図しないダブルタップにおける画面のズームを抑止する 目的において素晴しい働きを見せていましたが、 iOS 10 からは代替手段を模索する必要がありそうです。
解法その1
ページズームそのものを抑止することはできないが、ボタンの連打におけるズームは防げる
ページズームをそのものを抑止することはどうやら不可能なようです。
個人的にページはズームできたほうが良いとも考えており、 問題のポイントはユーザが意図しないタイミングにおけるズームにあると考えました。
DEMO
こちらのシンプルな デモ(Source) では、ボタンを連打しても画面はズームしません。
- ズームを抑止したい要素に対して
class="prevent-zoom"
を付与する - 読み込み完了のタイミング(デモでは_attchEvent関数)で
prevent-zoom
を持つ要素を検索し、ズームを抑止するためのイベントハンドラを設定する - イベントハンドラの中では
event.preventDefault()
とevent.stopPropagation()
を行いイベントのバブリングを抑止する
といった事を行っています。
SPA ではどうするか
SPAなど、画面の構成要素が動的に頻繁に入れ替わる場合はこのようなシンプルな方法では抑止できません。
バブルアップしてくるイベントを捉えるか、キャプチャーフェーズでイベントを補足し、prevent-zoom
を持っている要素に対して event.preventDefault(); event.stopPropagation()
を行う必要があります。
ただ、既に長い運用の歴史があり、魔窟と化しているコードにおいては、最新の注意を払って実施しないと思わぬ副作用 があるでしょう。
解法その2
模索中… 分かったら追記します。
Safari 改変の歴史
Safari はこれまでにも、色々とボディブローのような改変が行われています。
-
コンテンツ領域を広く見せようとして、アドレスバーを隠すスクリプトを沢山の人達が導入していたところ、iOS 7 で突然無効化されてしまった
// ページロード直後にスクロールバーを隠す window.addEventListener("load", function() { setTimeout(scrollBy, 100, 0, 1); // 100ms後に scrollBy(0, 1) を行う }, false);
-
iOS 7 で横持ちしている時にフルスクリーン表示ができなくなってしまった(アドレスバーが表示されてしまう)
-
iOS 7.1 で
minimal-ui
を一瞬導入するも、すぐに無かった事にされてしまう<meta name="viewport" content="width=device-width,minimal-ui">
-
iOS 8 でブラウザのスタイルが刷新され、アドレスバーが小さくなったが、アドレスバーが出ているかどうかを判別不能になってしまった
-
iPhone 6s iOS 9 から 3D touch が導入されたが、機能を抑止する方法がセットになっていないため、ユーザがエキサイトすると長押しで誤爆してしまう という問題がある
などなど、一部の開発者にとっては嬉しくない改変が続いています。
禊(みそぎ)のようなものと捉え、これからも頑張って追従していけたら良いですね ><
WKWebView における対応方法
iOS 10 の WKWebView では設定が追加され、WebView におけるポリシーの設定が可能になりました。
WKWebView now defaults to respecting user-scalable=no from a viewport. Clients of WKWebView can improve accessibility and allow users to pinch-to-zoom on all pages by setting the WKWebViewConfiguration property ignoresViewportScaleLimits to YES.
via https://developer.apple.com/library/prerelease/content/releasenotes/General/RN-iOSSDK-10.0/
-
var ignoresViewportScaleLimits: Bool { get set }
-
@property(nonatomic) BOOL ignoresViewportScaleLimits;
参考になさってください。