æºåž¯é»è©±ãã¿ãã¬ãããã©ãããããããã¹ã¯ãããã®ã¿ããã¹ã¯ãªãŒã³ã¯ã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ã€ã®ç°ãªãã¿ãããªã¹ããå«ãŸããŠããŸãã
- 觊ããŸãã å®è¡äžã®æ©èœãå±ããŠããã¢ã€ãã ã«é¢ä¿ãªããç»é¢äžã§çŸåšã¢ã¯ãã£ããªãã¹ãŠã®å ±éã°ã©ãŠã³ããå«ãŸããŸãã
- TargetTouchesã ãŠãŒã¶ãŒãæãèŠçŽ ã®å€åŽã«ç§»åããŠããèŠçŽ å ã§éå§ããã¿ãããã€ã³ãã®ã¿ãå«ãŸããŸãã
- å€æŽãããã¿ããã æåŸã®ã¿ããã€ãã³ã以éã«å€æŽãããå ±éã®åºç€ãå«ãŸããŸãã
ãããã®åã·ãŒãã¯ãåã ã®æèŠãªããžã§ã¯ãã®ãããªãã¯ã¹ã§ãã ããã§ã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ã§ã¿ããã€ãã³ããæäœããåºæ¬ã«ã€ããŠèª¬æããŸããã ããã圹ã«ç«ã€ããšãé¡ã£ãŠããŸãã