JavascriptでPCならクリック、SPならタップに対してイベントハンドリングをする実装。
ポイントは下記。
-
element.onclick
は使わずにelement.addEventListener
かelement.attachEvent
を使う - スマホでclickイベントを使うとダブルタップ判定待ちのラグが発生するため、touchXXX系のイベントを使う
- スワイプやフリックは除外
touchstart
発生後にtouchmove
があればスワイプ/フリックとみなして除外、touchmove
がないままtouchend
が来たならタップとみなす。
というふうに実装しています
// ページのDOMツリー構築後に実行(要するにwindow.onload)
function ale(fn){
if (window.addEventListener) {
window.addEventListener('load', fn, false);
} else if(window.attachEvent) {
window.attachEvent('onload', fn);
} else {
window.onload = fn;
}
}
// 要素にクリックイベントリスナーを付加
function ace(el, fn){
if (el.addEventListener){
if(window.ontouchstart === undefined){
el.addEventListener('click', fn, false);
}else{
var fTapped = false;
el.addEventListener('touchstart', function(){fTapped = true}, false);
window.addEventListener('touchmove', function(){fTapped = false}, false);
window.addEventListener('touchend', function(){if(fTapped){fn()} fTapped = false}, false);
}
} else if(el.attachEvent){
el.attachEvent('onclick', fn);
}
}
// クリック/タップ時に実行する関数
function fn(){alert('clicked');}
// 1個の要素を指定して実行
ale(function(){ace(document.getElementById('room1'), fn)});
// 複数の要素をまとめて指定して実行
(function(){
var els = document.getElementsByClassName('menu');
ale(function(){
for (var i = 0; i < els.length; i++)
ace(els[i], fn);
}
});
})();