<!DOCTYPE html>
<title></title>
<meta name="viewport" content="width=640">
<style>
h1 {
font-size: large;
}
h3 {
margin-bottom : 0;
}
h3 + p {
font-size: small;
color: gray;
margin : 0 2em;
}
em {
color: green;
font-size:x-large;
}
li.focus {
border-bottom : 2px red dotted;
}
</style>
<body>
<h1>
<em>iPod</em> &
<em>iPad</em> &
<em>iPhone</em> で、クリックイベントを有効にする
</h1>
<h3>クリックイベントが発生する状態</h3>
<ul>
<li>document をクリック(タップ)した時
<li>フォームの input要素(button)など
<li>要素のインラインに書いたイベント
</ul>
<h3>クリックイベントの代わりに、touchstart, touchmove, touchend を利用する</h3>
<p>(3つのイベントを組み合わせて、クリックイベントを実現する)
<ul>
<li>touchstart イベントが発生したら、スタート位置を記憶する
<li>touchmove を監視し、現在位置との差が範囲外なら、止める
<li>touchend イベントオブジェクトからは、位置が拾えないので、スタート位置を基準とし、
クリックイベントを発生させる
</ul>
<h3>使い方</h3>
<ul>
<li>
<p>面倒なので略。
</ul>
<script>
document.addEventListener ('click', function (e) {
var n = e.target;
n.className = n.className ? '': 'focus';
}, false);
(function () {
function Emulator () {
this.range = 10;
this.startPoint = { 'x' : 0, 'y' : 0 };
this.action = true;
this.state = false;
}
function fire (event) {
var e = event.target;
var doc = e.ownerDocument;
var evt = doc.createEvent ('MouseEvents');
if (3 === e.nodeType)
e = e.parentNode;
evt.initMouseEvent(
'click',
true,
true,
doc.defaultView,
1,
this.startPoint.x,
this.startPoint.y,
this.startPoint.x,
this.startPoint.y,
false,
false,
false,
false,
0,
doc.body
);
e.dispatchEvent(evt);
}
function handler (event) {
if (! this.action)
return;
var touch = event.touches;
var eType = event.type;
var range = this.range;
var point = this.startPoint;
if (this.state) {
if (('touchmove' === eType) && (touch = touch[0])) {
if ((Math.abs (touch.pageX - point.x) < range) ||
(Math.abs (touch.pageY - point.y) < range)) {
this.state = false;
}
}
else if ('touchend' === eType) {
fire.call (this, event);
}
}
else if (('touchstart' === eType) && (1 === touch.length) && (touch = touch[0])) {
this.startPoint.x = touch.pageX;
this.startPoint.y = touch.pageY;
this.state = true;
}
}
function emulator_init (view) {
var doc = view ? view.document: document;
var emu = null;
if (/iPhone|iPad|iPod/.test (navigator.userAgent)) {
emu = new Emulator;
doc.addEventListener ('touchstart', emu, false);
doc.addEventListener ('touchmove', emu, false);
doc.addEventListener ('touchend', emu, false);
}
return emu;
}
Emulator.prototype.handleEvent = handler;
Emulator.init = emulator_init;
this.ClickEmulator = Emulator;
})();
ClickEmulator.init ();
</script>