initTouchEventにおけるAndroidとiOSの引数違い

こんにちは。毎日欠かさずAndroidと心で対話をおこなうHTMLファイ部の高橋です。入社4週目にしての初投稿です。 UIのタッチ操作が絡むJSのテストで、タッチイベントを生成する際のハマりどころをエントリします。

きっかけ

先日、JsTestDriverでタッチイベントの生成をした際、Androidだけイベントが生成されず何のエラーも出ないという事象が発生。

その答えは「selenium」の中にありました。

events.js#443 | selenium

// Android's initTouchEvent method is not compliant with the W3C spec.

// Android's initTouchEvent method is not compliant with the W3C spec.

// Android's initTouchEvent method is not compliant with the W3C spec. だと?(大事なことなので)

さらに selenium のコードを追ってみると

// Native touch api supported starting in version 4.0 (Ice Cream Sandwich).

の表記があり、selenium の中では、4.0(ICS)以下の場合 initMouseEvent でイベントの初期化を行い、そのイベントオブジェクトに対して touches, targetTouches などのプロパティを追加してイベントを生成しているようです。 (ツッコみどころがありすぎる)

今回は、試しに上記 events.js 443行以下のイベント生成方法で検証を行ったところ、Android2.1以上(1系は検証していません)ではイベントが生成されたので、その結果をまとめたいと思います。

initTouchEvent 仕様

Android, iOSにおけるinitTouchEventの仕様を書き出してみました。

// iOS initTouchEvent
// via. TouchEvent Class Reference | Safari Development Library
// https://developer.apple.com/library/safari/#documentation/UserExperience/Reference/TouchEventClassReference/TouchEvent/TouchEvent.html
    event.initTouchEvent(
            type,
            canBubble,
            cancelable,
            view,
            detail,
            screenX,
            screenY,
            clientX,
            clientY,
            ctrlKey,
            altKey,
            shiftKey,
            metaKey,
            touches,
            targetTouches,
            changedTouches,
            scale,
            rotation
    );


// Android initTouchEvent
// via. events.js | selenium
// http://code.google.com/p/selenium/source/browse/trunk/javascript/atoms/events.js#443
    event.initTouchEvent(
            touches,
            targetTouches,
            changedTouches,
            eventType,
            view,
            screenX,
            screenY,
            clientX,
            clientY,
            ctrlKey,
            altKey,
            shiftKey,
            metaKey
    );

すごく、引数多いです…。

見てのとおり、AndroidにはcanBubble, cancelable, detail, scale, rotationの5個が存在せず、順番も違うため、生成の際は切り分けてあげる必要があります。

サンプルコード

[TEST] createTouchEvent - jsdo.it - share JavaScript, HTML5 and CSS

(Android, iOSでアクセスすると動作確認ができます >> http://jsrun.it/keeeeei/p3Mf )

このように簡単なラッパーを作ってあげると、すごく便利にタッチイベントを生成することができますね!

KAYACでは、数多の引数を操り、心でTouchEventを生成する技術者を募集しています!