近年、ブラウザと端末の対応において特定のベンダープレフィックス(例:-webkit-)を気にする必要は随分減りました。
とはいえ、端末ごとの癖や違いには注意が必要で、コードに間違いがなくても異なる動作を見せることがあります。ここでは、iPhone向けに注意して実装するスタイルを挙げました。
iphoneかどうかの判定
function isIphone() {
return /iPhone/i.test(navigator.userAgent);
}
// iPhone でない場合のみ処理を実行
if (!isIphone()) {
// iPhone 以外で実行したい処理
const element = document.querySelector('.my-element');
const totalHeight = getElementHeightWithMargin(element);
console.log('マージンを含めた高さ:', totalHeight, 'px');
} else {
console.log('iPhone では処理を除外');
}
ブラウザ判定
//Safariの場合
function isSafari() {
const ua = navigator.userAgent;
return ua.includes('Safari') && !ua.includes('Chrome') && !ua.includes('CriOS');
}
//chromeの場合
function isChrome() {
const ua = navigator.userAgent;
return ua.includes('Chrome') || ua.includes('CriOS');
}
iphoneでover-flow:hiddenが効かないとき
html、body以外に、body直下のクラスにもoverflow:hiddenを付与することで固定できた。(iphone Safari以外は問題ない)
// リスナー関数を定義
function handleTouchMove(event) {
event.preventDefault();
}
// タッチイベントリスナーを追加
function enableTouchMove() {
document.addEventListener('touchmove', handleTouchMove, { passive: false });
}
// タッチイベントリスナーを削除
function disableTouchMove() {
document.removeEventListener('touchmove', handleTouchMove, { passive: false });
}
// ある条件でタッチイベントを無効化
function doSomething() {
disableTouchMove();
// ここに処理を書く
}
// 別の条件でタッチイベントを有効化
function doSomethingElse() {
enableTouchMove();
// ここに処理を書く
}
// 使用例
doSomething(); // タッチイベントを無効化する処理
// doSomethingElse(); // タッチイベントを有効化する処理
◼︎iphone用に気を付けるスタイル
①overflow-x
②height:100vh
③hoverイベント
①overflow-x
iPhoneでは画面左右にスワイプができる場合があります。このままではユーザビリティに影響するため、htmlにoverflow-xを設定します(原因は不明)。それでも効かない場合はwebkitを試しましょう。
◼︎図
・改善前:左右スワイプで左右の余白が見えてしまう
・改善後:左右スワイプで余白が見えなく
◼︎iphoneでsetTimeout(***,0)が効かない
setTimeoutのタイミングが0ミリ秒だと、スクロール処理が正しく反映されないことがあります。
少しタイミングを遅らせてみると改善することがあります。
※Chromeのみ発生し、safariだと問題ない場合もありました。
◼︎iphone用に気を付けるその他
videoの自動再生はiOSはブロックされる。そのため、videoタグにはplaysinline=””をつけ、autoplayは外す。また、自動再生はそのままではできないので、sceollイベントやtouchイベントなどで動画が動くようにする。動画の0コマ目の画像は自動的に表示されないため、以下のようにposter属性をつけることで表示される。ただし、poster要素はautoplayとの相性が悪いため、androidの場合はposterを取り除く必要がある。
なお、動画読み込みを検知するトリガー:canplaythroughはload()と合わせて使う必要がある(再現なし)
以下のように自動で1pxずらすことで、強制的に発火させる
<video controls poster="0frame.jpg">
<source src="video.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
■firefox用に気を付けるポイント
① 「 will-change: transform, opacity;」を実装するとかくつく。
→rotate(0.0001deg)にしても改善されなかった。実際、不要ならwill-changeは使用しないほうが良いかもしれません。
■参考ページ
①Firefoxでアニメーションがガクガクしたときの対応記録
https://qiita.com/heeroo_ymsw/items/ca2c992701c0a0092ab1