Ext JS 5 に追加された機能で最も待ち望まれた機能は、タッチスクリーン式ノートパソコンやタブレットなどの、タッチスクリーン入力デバイスのサポートです。この機能の主な目的は、Ext JS アプリケーションを、ほとんど変更せずタッチスクリーンデバイスで実行させることです。これは、開発者が互換性の問題について検討する時間を減らし、その時間をアプリケーションの実装に回すことができることを意味します。
タッチスクリーンサポートの実装方法
タッチスクリーンデバイスのサポートは、3つの分野に分類できます。
イベント正規化
イベント正規化によって、Ext JS 5 のアプリケーションはタッチスクリーンデバイス上で動作できます。この正規化は、バックグランドで動作し、標準のマウスイベントを対応するタッチイベントとポインタイベントに単純に変換します。
ポインタイベントは、w3c 標準で、入力デバイス(マウス、タッチ、スタイラスなど)に関わらず、画面の特定の座標をターゲットするイベントを扱います。
コードがマウスイベントのリスナをリクエストすると、フレームワークが必要に応じてよく似たタッチやポインタイベントをアタッチします。例えば、アプリケーションが mousedown リスナをアタッチするには、次を行います。
myElement.on('mousedown', someFunction);
タッチイベントをサポートするデバイスの場合には、イベントシステムがこれを touchstart に変換します。
myElement.on('touchstart', someFunction);
または、ポインタイベントをサポートするデバイスの場合には、これを pointerdown に変換します。
myElement.on('pointerdown', someFunction);
この変換は既に準備されているので、コードを追加しなくても、タブレットやタッチスクリーンのサポートを実現できます。
ほとんどの場合、フレームワークがマウス、タッチ、ポインタの入力をシームレスに切り替えることができます。しかし、いくつかのマウス操作(例えば、mouseover)は簡単にタッチ操作に変換できません。このようなイベントは個別に扱う必要がありますが、次のセクションで説明します。
ジェスチャーシステム
標準 DOM イベントに加え、要素は合成された "gesture” イベントも発火します。Sencha Touch のイベントシステムは、Ext JS 5 の新しいイベントシステムの基盤となっているので、Sencha Touch のユーザーは、既にこの概念に馴染みがあるでしょう。
ブラウザから見ると、ポインタ、タッチ、マウスの各イベントには、主に3つのタイプ(Start、Move、End)があります。
イベント | タッチ | ポインタ | マウス |
---|---|---|---|
Start | touchstart | pointerdown | mousedown |
Move | touchmove | pointermove | mousemove |
Stop | touchend | pointerup |
これらのイベントのシーケンスとタイミングを解釈した後、drag
、swipe
、longpress
、pinch
、rotate
、tap
などの複雑なイベントを合成します。次の例のように、Ext JS アプリケーションは他のイベントと同じようにジェスチャーイベントをリッスンできます。
Ext.get('myElement').on('longpress', handlerFunction);
オリジナルの Sencha Touch ジェスチャーシステムは、主にタッチイベントを念頭に設計されました。ジェスチャーシステムにポインタとマウスイベントのサポートを追加することによって、Ext JS 5 ではどのような入力に対してもジェスチャーが反応できます。これは、すべてのジェスチャーがタッチ入力でトリガーできだけではなく、すべてのシングルポイントのジェスチャー(タップ、スワイプなど)もマウスを使用してトリガーできることを意味します。その結果、入力方法に関わらず、複数デバイスでシームレスに動作するジェスチャーシステムができました。
タッチスクローラー
コンテンツがオーバーフローする要素のネイティブなスクロールは、一部のモバイル用 Webkit ブラウザで多くの点で不十分です。モーメンタムスクロールとスクロール位置のインジケーターがないため、スクロールの操作が単調で、直感的ではありません。Sencha Touch から借用した ‘touch scroller’ では、JavaScript を使用してスクロールインジケーター付きのモーメンタムスクロールを導入し、この問題を解決しました。アプリケーション開発者は、通常タッチスクローラーをオンにするために何かをする必要はありません。ネイティブスクロールが最適ではないブラウザではデフォルトで有効になります。
アプリケーションに対するタッチスクリーンのサポートの影響
正規化されたイベントとジェスチャーの認識は、Ext JS 5 アプリケーションではデフォルトで有効になっています。これは、ほとんどの場合にタブレットとタッチスクリーンのサポートを有効にするための特別な操作は必要ないことを意味します。ただし、特に注意が必要な領域が2つあります。
まず、タッチ世界では対応するものがないマウスイベントへの対応です。現時点では、Ext JS 5 では、次のマウスイベントに対しては正規化を行いません。
- mouseover
- mouseout
- mousenter
- mouseleave
デスクトップのデバイスで上記のイベントに反応するアプリケーションの機能は、タッチデバイスに個別に再実装する必要があります。開発者はアプリケーションを設計する際にこのことを念頭に入れる必要があります。タッチスクリーンでも重要なアプリケーションの機能にアクセスできるように、これらの操作に対して別の実装を提供する必要もあります。これは、マウスイベントを適切なタッチジェスチャーに置き換えることを意味します。Ext JS は内部的に数ヶ所でこのアプローチを取ります。
その例の1つがグリッドコンポーネントです。デスクトップデバイスでは、グリッドのカラムヘッダーのメニューは、ヘッダーのトリガー要素のクリックに反応して表示されます。しかし、カラムヘッダーの mouseover に反応した時だけに表示されます。タッチスクリーンでは ‘mouseover’ に相当するジェスチャーは存在しないため、トリガーは表示されず、タッチできない状態になります。カラムヘッダーのメニューに確実にアクセスできるように、タッチスクリーンデバイスでグリッドが使われていることを検出すると、Ext JS は「longpress(長押し)」に反応してメニューを表示します。
注意:_アプリケーションやカスタムコンポーネントの開発者は、必要に応じてこのような調整を行う必要があります。_
注意すべき2つ目の領域は、フレームワークの内部的な変更に関するものです。タッチジェスチャーをサポートするために、Ext JS 5 ではデリゲートイベントモデルに切り替えました。リスナを直接 DOM 要素にアタッチする代わりに、DOM の最上位(window または document オブジェクト)にイベントタイプごとに1つのリスナがアタッチされます。 その後、Ext JS イベントシステムは、windows オブジェクトまでバブルアップしたイベントのターゲット要素をベースとして、イベントハンドラをディスパッチします。 イベントをリッスンするために、Ext JS API だけを使っているアプリケーション開発者は、この新しいアプローチによる問題を経験することはありません。
しかし、DOM API を使ってリスナ(addEventListener や attachEvent)を直接アタッチしている場合や 、サードパーティーの JavaScript ライブラリを使っている場合は、直接アタッチされているイベントハンドラとデリゲートされた対応部分にタイミングの問題が発生する可能性があります。
注意:_タブレットやタッチスクリーンのサポートは、現在 Safari、Chrome、IE10以降のみとなっています。Android ブラウザは現時点ではサポートされていません。_