「スマホのときだけクリック(タップ)で何かしたい」という要望はよくあります。ただし最初に知っておきたいのは、click イベントはPCでもスマホでも動くということです。
「スマホ専用」にしたいなら、もろいUA(ユーザーエージェント)判定ではなく、能力判定(matchMedia)で出し分けるのが現代的で確実です。この記事ではその正しいやり方を解説します。
click はPC・スマホ両方で発火します。タッチ端末かどうかはmatchMedia("(pointer: coarse)")、画面サイズは matchMedia("(max-width: 768px)") で判定します。UA判定は非推奨(iPadがデスクトップUAを返すなど誤判定する)です。まず:clickはPCでもスマホでも動く
click イベントは、マウスのクリックでも指のタップでも発火します。つまり普通に click を設定すれば、スマホでもタップで動きます。「スマホ専用」にしたい場面は実は限られていて、多くは端末の能力に応じて挙動を変えたいだけのはずです。
const button = document.getElementById("myButton");
button.addEventListener("click", () => {
console.log("クリックでもタップでも発火します");
});
タッチ端末かどうかを判定する(matchMedia)
「タッチで操作する端末か」を判定するには、CSSメディア特性を読む matchMedia を使います。(pointer: coarse)(主ポインタが粗い=指タッチ)や(hover: none)(ホバーできない)で判定できます。
// 主ポインタが粗い(指タッチ)か
const isTouch = window.matchMedia("(pointer: coarse)").matches;
if (isTouch) {
button.addEventListener("click", () => {
console.log("タッチ端末でのみ実行");
});
}
UA文字列に依存しないため、機種が変わっても壊れにくいのが利点です。matchMedia で画面サイズを扱う例は画面サイズをリアルタイムで取得する方法でも解説しています。
画面サイズで判定する(max-width)
「スマホ=小さい画面」とみなして画面幅で出し分ける方法もあります。CSSのブレークポイントと同じ条件で書け、画面幅が変わっても追従できます。
const mq = window.matchMedia("(max-width: 768px)");
function setup(e) {
if (e.matches) {
console.log("スマホ想定(小さい画面)の処理");
} else {
console.log("PC想定の処理");
}
}
setup(mq); // 初期判定
mq.addEventListener("change", setup); // 幅が変わったら追従
ウィンドウ幅の条件で処理を分ける実装はウィンドウサイズの条件でページをリロードする方法も参考になります。
UA判定がなぜ非推奨なのか
古い記事では navigator.userAgent に「Mobi」「Android」が含まれるかで判定しますが、おすすめしません。次のように当てになりません。
// NG: もろいUA判定
function isMobile() {
return /Mobi|Android/i.test(navigator.userAgent);
}
matchMedia の能力判定を使うのが安全です。マウスもタッチも統一して扱う:Pointer Events
そもそも「端末を判定して分岐」しなくても、マウス・タッチ・ペンを統一して扱える Pointer Eventsがあります。イベントごとに pointerType で入力種別を見分けられます。
button.addEventListener("pointerdown", (event) => {
// "mouse" / "touch" / "pen" のいずれか
console.log(event.pointerType);
if (event.pointerType === "touch") {
console.log("指で操作された");
}
});
グローバルに「スマホかどうか」を判定するより、操作ごとに入力種別を見るほうが正確な場合が多いです。キーボードなど他の入力の扱いはキーボード入力を取得する方法も参考になります。
よくある質問(FAQ)
window.matchMedia("(pointer: coarse)").matches(タッチ端末か)で分岐してイベントを設定します。click 自体はPCでもスマホでも発火するため、能力判定で出し分けるのが確実です。matchMedia の能力判定(pointer / hover)を使ってください。pointerdown(または touchstart)で座標を記録し、pointerup での差分が小さければタップ、大きければスワイプと判定します。方向は deltaX・deltaY の比較で分かります。pointerdown・pointermove・pointerup)がマウス・タッチ・ペンを統一したAPIです。モダンブラウザで使えるため、新規実装に推奨されます。まとめ
click はPC・スマホ両方で動くので、まず「本当に分岐が必要か」を考えましょう。必要な場合も、もろいUA判定ではなく matchMedia の能力判定((pointer: coarse) / (hover: none))や画面サイズ(max-width)で出し分けるのが確実です。
UA判定はiPadをデスクトップと誤認するなど当てにならず、非推奨です。マウスもタッチも扱いたいなら、Pointer Events でpointerType を見るのが、もっとも正確で将来も安心な方法です。
