iPhone clickイベント

li要素をタップしたら、ほげほげ(アラート出す、ハイライトする、etc)させたかったのでonclickを使ってたんだが、どうも動きがもっさり。ググってみるとこんな記事が。

Remove onClick delay on webkit for iPhone

Developing on the webkit for iPhone I encountered a curious delay on onClick events. It seems that the click is triggered with about 300 milliseconds delay. While this is unnoticeable on a standard web page, it can be annoying on a web application. Fortunately the click event can be overridden thus eliminating the delay.


Appleのdeveloperサイト(http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html#//apple_ref/doc/uid/TP40006511-SW1)でイベントモデルを調べてみた結果、Double Tapを判定するためにdelayが発生してしまうのでは、という考えに至る。

解決策: ontouchendを使う

ただし、スクロール時にもtouchendイベントは発生するので、以下のように回避する必要あり。

var isMove = 0;
element.ontouchmove = function(event) { isMove = 1; };
element.ontouchend  = function (event) {
	if (!isMove) { do_something(); }
	isMove = 0;
};

ベンチマーク

せっかくなのでclick/touchendでどれくらい差がでるかやってみた。

<div id="test" style="background-color:#666">
    This is test.<br/>
    This is test.<br/>
    This is test.<br/>
</div>
<script type="text/javascript">
    var div = document.getElementById('test');
    var start;

    div.addEventListener('touchstart', function() {
        start   = parseInt(new Date() * 1);
    });
    div.addEventListener('click', function() {
        var delay = (parseInt(new Date() * 1) - start) / 1000;
        alert(delay);
        start = 0;
    });
    //div.addEventListener('touchend', function() {
    //  var delay = (parseInt(new Date() * 1) - start) / 1000;
    //  alert(delay);
    //  start = 0;
    //});
</script>

手元のiPhone4でclickがだいたい0.4sec、touchendが0.1secくらい。

まとめ

iPhoneではonclickさけて、ontouchend(with ontouchmove)つかうべし。