タッチデバむスでサむトを機胜させる





携垯電話、タブレット、ラップトップ、デスクトップのタッチスクリヌンは、Web開発者にずっおたったく新しい䞀連のやり取りを可胜にしたした。 翻蚳されたガむドでは、Patrick LokiがJavaScriptでタッチむベントを操䜜する基本に぀いお説明しおいたす。 以䞋で説明する䟋はすべおアヌカむブにありたす 。





タッチを心配する必芁がありたすか



タッチデバむスの出珟により、開発者からの䞻な質問は、「サむトたたはアプリケヌションがそれらで動䜜するこずを確認するために䜕をする必芁がありたすか」です。驚くほど、答えは䜕もありたせん。 デフォルトでは、モバむルブラりザは、タッチデバむス甚に蚭蚈されおいないほずんどのサむトに察応しおいたす。 アプリケヌションは、静的ペヌゞで正垞に動䜜するだけでなく、JavaScriptでむンタラクティブサむトを凊理したす。JavaScriptでは、ホバヌなどのむベントにスクリプトが関連付けられたす。



これを行うために、ブラりザはデバむスのタッチスクリヌンでマりスむベントをシミュレヌトたたはシミュレヌトしたす。 単玔なペヌゞテスト添付ファむルのexample1.htmlは、タッチデバむス䞊でも、ボタンを抌すず次の䞀連のむベントがトリガヌされるこずを瀺しおいたす mouseover> mousemove> mousedown> mouseup> click 。



これらのむベントは、実質的に遅延するこずなく、連続しおトリガヌされたす。 mousemoveむベントに泚意しおください。これは、マりスの動䜜によっおトリガヌされるすべおのスクリプトの少なくずも1回の実行を提䟛したす。



サむトがマりス操䜜に応答する堎合、ほずんどの堎合、その機胜は远加の倉曎を必芁ずせずにタッチデバむスで匕き続き機胜したす。



マりスむベントシミュレヌションの問題



クリック遅延



タッチスクリヌンを䜿甚する堎合、ブラりザヌは、タッチアクションボタンたたはリンクのクリックなどず実際のクリックのアクティブ化の間で玄300ミリ秒の人為的な遅延を意図的に䜿甚したす。 この遅延により、ナヌザヌは誀っお他のペヌゞ芁玠をアクティブにするこずなく、ダブルタップを実行できたすたずえば、画像を拡倧および瞮小するため。



ネむティブアプリケヌションずしおナヌザヌアクションに応答するサむトを䜜成する堎合は、問題が発生する可胜性がありたす。 これは、䞀般ナヌザヌがほずんどのむンタヌネットリ゜ヌスに期埅するものではありたせん。



指远跡



既にお気付きのように、ブラりザヌによっお送出される合成むベントにはmousemoveむベントが含たれおいたす-垞に1぀だけです。 ナヌザヌが画面を過床にスワむプするず、合成むベントはたったく生成されたせん。ブラりザは、そのような動きをスクロヌルのようなゞェスチャヌずしお解釈したす。



これは、サむトがマりスの動き描画アプリケヌションなどによっお制埡されおいる堎合に問題になりたす。



簡単なキャンバスアプリケヌション example3.htmlを䜜成したしょう。 特定の実装の代わりに、スクリプトがマりスの動きにどのように応答するかを芋おみたしょう。



var posX, posY; ... function positionHandler(e) { posX = e.clientX; posY = e.clientY; } ... canvas.addEventListener('mousemove', positionHandler, false );
      
      





マりスを䜿甚しお䟋をテストするず、カヌ゜ルの移動に合わせおポむンタヌの䜍眮が継続的に監芖されおいるこずがわかりたす。 タッチデバむスでは、アプリケヌションは指の動きに応答せず、合成モヌションむベントをトリガヌするクリックにのみ応答したす。



「もっず深く」



これらの問題を解決するには、抜象化する必芁がありたす。 iOS 2.0のSafariにはタッチむベントが登堎し、ほずんどすべおのブラりザヌに実装された埌、 W3C Touch Events仕様で暙準化されたした。 暙準に蚘録される新しいむベントは、タッチスタヌト、タッチムヌブ、タッチ゚ンド、タッチキャンセルです。 最初の3぀の仕様は、暙準のmousedown、mousemove、およびmouseupず同等です。



Touchcancelは、タッチ操䜜が䞭断されるず呌び出されたす。たずえば、ナヌザヌが珟圚のドキュメントを超えお指を䌞ばした堎合などです。 クリックのために感芚むベントず合成むベントがトリガヌされる順序を芳察するず、次のようになりたすexample4.html



touchstart> [touchmove] +> touchend> mouseover>単䞀mousemove> mousedown> mouseup>をクリックしたす 。



すべおのタッチむベントが関係したすtouchstart、1぀以䞊のtouchmoveナヌザヌが画面䞊で指を動かさずにボタンをどれだけ慎重に抌すかによっお異なりたす、およびtouchend。 その埌、合成むベントがトリガヌされ、最埌のクリックが発生したす。







感芚むベント怜出



単玔なスクリプトを䜿甚しお、ブラりザヌがタッチむベントをサポヌトしおいるかどうかを刀断したす。



 if ('ontouchstart' in window) { /* browser with Touch Events support */ }
      
      





このスニペットは、最新のブラりザヌでうたく機胜したす。 叀いものには、皮膚から登った堎合にのみ芋぀けるこずができる癖ず矛盟がありたす。 アプリケヌションが叀いブラりザヌに焊点を合わせおいる堎合は、 Modernizrプラグむンずそのテストメカニズムを詊しおください。 ほずんどの矛盟を特定するのに圹立ちたす。



感芚むベントのサポヌトを決定する際、テスト察象を明確に理解する必芁がありたす。



遞択されたフラグメントは、タッチを認識するブラりザの機胜のみをチェックしたすが、タッチスクリヌンでアプリケヌションが開いおいるずは蚀いたせん。



遅延䜜業をクリックしたす



タッチデバむスでブラりザヌに送信され、同期情報example5.htmlを含む䞀連のむベントをテストするず、touchendむベントの埌に300ミリ秒の遅延が衚瀺されるこずがわかりたす。



touchstart> [touchmove] +> touchend> [300ms delay]> mouseover>単䞀mousemove> mousedown> mouseup>をクリックしたす 。



したがっお、スクリプトがクリックに応答する堎合、touchendたたはtouchstartに察する反応を蚘述するこずにより、デフォルトのブラりザヌ遅延を取り陀くこずができたす。 これらのむベントのいずれかに応答するこずでこれを行いたす。 タッチスタヌトは、画面に觊れるずすぐに起動するむンタヌフェむス芁玠に䜿甚されたす-たずえば、htmlゲヌムのコントロヌルボタン。







繰り返したすが、タッチむベントのサポヌトに぀いお、たたアプリケヌションがタッチデバむス䞊で特に開かれおいるずいう誀った仮定をしおはなりたせん。 モバむルの最適化に関する蚘事でよく蚀及される䞀般的なトリックの1぀を次に瀺したす。



 /* if touch supported, listen to 'touchend', otherwise 'click' */ var clickEvent =('ontouchstart'in window ?'touchend': blah.addEventListener(clickEvent,function(){ ... });
      
      





このシナリオは意図的なものですが、盞互に排他的な原則に基づいおいたす。 ブラりザのサポヌトに応じお、クリックたたはタッチのいずれかに察する反応は、ハむブリッドデバむスで問題を匕き起こしたす。マりス、トラックパッド、たたはタッチずのやり取りはすぐに䞭断されたす。



より堅牢なアプロヌチでは、䞡方のタむプのむベントを考慮したす。



 blah.addEventListener('click', someFunction,false); blah.addEventListener('touchend', someFunction,false);
      
      





問題は、関数が2回実行されるこずです。1回目はtouchendで、2回目は合成むベントずクリックが発生したす。 preventDefaultを䜿甚しおマりスむベントぞの暙準応答を抑制するこずにより、これを回避できたす。 たた、タッチ゚ンドハンドラヌに目的のクリックむベントをトリガヌさせるだけで、コヌドの繰り返しを防ぐこずもできたす。



 blah.addEventListener('touchend',function(e){ e.preventDefault(); e.target.click(); },false); blah.addEventListener('click', someFunction,false);
      
      





preventDefaultには問題がありたす。ブラりザで䜿甚するず、他のデフォルトの動䜜は抑制されたす。 最初のタッチむベントに盎接適甚するず、スクロヌル、マりスの長い移動、スケヌリングなど、他のアクティビティがブロックされたす。 これは適切な堎合もありたすが、このメ゜ッドは泚意しお䜿甚する必芁がありたす。



䞊蚘のコヌド䟋は最適化されおいたせん。 信頌できる実装に぀いおは、 FTLabsのFastClickで確認しおください。







touchmoveによるモヌショントラッキング



感芚むベントの知識を身に付けお、远跡の䟋example3.htmlに戻り、タッチスクリヌン䞊の指の動きを远跡するためにどのように倉曎できるかを芋おみたしょう。



このスクリプトの特定の倉曎を芋る前に、たずタッチむベントずマりスむベントの違いを理解する必芁がありたす。



感芚むベントの解剖孊



ドキュメントオブゞェクトモデルDOMレベル2によるず、マりスむベントに応答する関数は、マりスむベントオブゞェクトをパラメヌタヌずしお受け取りたす。 このオブゞェクトには、スクリプトが珟圚のマりス䜍眮を決定するために䜿甚するプロパティ-clientXおよびclientY座暙が含たれたす。



䟋



 interface MouseEvent : UIEvent { readonly attribute long screenX; readonly attribute long screenY; readonly attribute long clientX; readonly attribute long clientY; readonly attribute boolean ctrlKey; readonly attribute boolean shiftKey; readonly attribute boolean altKey; readonly attribute boolean metaKey; readonly attribute unsigned short button; readonly attribute EventTarget relatedTarget; void initMouseEvent(...); };
      
      





ご芧のずおり、toucheventには3぀の異なるタッチリストが含たれおいたす。







これらの各シヌトは、個々の感芚オブゞェクトのマトリックスです。 ここで、clientXずclientYに䌌た座暙のペアを芋぀けたす。



 interface Touch { readonly attribute long identifier; readonly attribute EventTarget target; readonly attribute long screenX;; readonly attribute long screenY; readonly attribute long clientX; readonly attribute long clientY; readonly attribute long pageX; readonly attribute long pageY; };
      
      





タッチむベントを䜿甚しお指を远跡する



キャンバスベヌスの䟋に戻りたす。 感芚むベントずマりスアクションの䞡方に応答するように、関数を倉曎する必芁がありたす。 単䞀のタッチポむントの動きを远跡する必芁がありたす。 targetTouches配列の最初の芁玠からclientXおよびclientY座暙を取埗するだけです。



 var posX, posY; function positionHandler(e) { if ((e.clientX)&&(e.clientY)) { posX = e.clientX; posY = e.clientY; } else if (e.targetTouches) { posX = e.targetTouches[0].clientX; posY = e.targetTouches[0].clientY; e.preventDefault(); } } canvas.addEventListener('mousemove', positionHandler, false ); canvas.addEventListener('touchstart', positionHandler, false); canvas.addEventListener('touchmove', positionHandler, false);
      
      





タッチデバむスexample6.htmlで倉曎されたスクリプトをテストするず、1本の指の動きの远跡が確実に機胜するこずがわかりたす。



マルチタッチが機胜するように䟋を拡匵する堎合は、最初のアプロヌチを少し倉曎する必芁がありたす。 単䞀の座暙ペアの代わりに、呚期的に凊理されるシリヌズ党䜓を考慮したす。 これにより、シングルマりスクリックずマルチタッチexample7.htmlの䞡方を远跡できたす。



 var points = []; function positionHandler(e) { if ((e.clientX)&&(e.clientY)) { points[0] = e; } else if (e.targetTouches) { points = e.targetTouches; e.preventDefault(); } } function loop() { ... for (var i = 0; i<points.length; i++) { /* Draw circle on points[0].clientX / points[0].clientY */ ... } }
      
      





このようなもの







パフォヌマンスの問題



mousemoveむベントのように、touchmoveは指を動かしながら高速で動䜜できたす。 耇雑なコヌド耇雑な蚈算たたは各移動の描画むベント党䜓を避けるこずをお勧めしたす。 これは、最新のタッチデバむスよりも叀い匷力なタッチデバむスにずっお重芁です。



この䟋では、絶察最小倀を実行したす。最埌のマりス配列たたはタッチポむントの座暙を保存したす。 アプリケヌションコヌドは、setIntervalを䜿甚しお個別のルヌプで独立しお実行されたす。



スクリプトによっお凊理されるむベントの数が倚すぎる堎合は、 limit.jsなどの特別な゜リュヌションの䜜業に倀したす。



既定では、タッチデバむスのブラりザヌは特定のマりススクリプトを凊理したすが、タッチ操䜜甚にコヌドを最適化する必芁がある堎合がありたす。 このチュヌトリアルでは、JavaScriptでタッチむベントを操䜜する基本に぀いお説明したした。 これが圹に立぀こずを願っおいたす。



All Articles