質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

0回答

770閲覧

Javascriptのタッチイベントについて

Butter

総合スコア0

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2023/02/24 12:40

編集2023/03/11 12:41

実現したいこと

JavaScriptでゲームを作ろうとしたのですが、タッチイベントが特定の場面で反応しない現象に悩まされています

発生している問題・エラーメッセージ

自分で色々試した結果、「どこかをタッチし、離すと同時に別のところをタッチ」したときに、後に行ったタッチが認識されていないと分かりました。
(後に行ったタッチはtouchstartもmoveもendも発火せず、event.touches.lengthにもカウントされていませんでした)

試したこと

タッチイベントのtargetを変更したり、eventが発火しているタイミングを調べたりしましたが、やはり特定の場面で発火していませんでした。

環境はiOSで、ChromeとSafari、Firefoxでこの問題が発生しました。
自分で調べた限りではそういった仕様は見つけられませんでした。
仕様や解決策をご存知でしたら回答よろしくお願いします

ソースコード

HTML

1 2<!DOCTYPE html> 3<html> 4 <head> 5 <meta charset="utf-8" /> 6 <meta name="description" content=""> 7 <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no"> 8 <script type="text/javascript" src="script.js"></script> 9 <title>Game</title> 10 <style> 11 * { 12 padding: 0; 13 margin: 0 auto; 14 } 15 16 canvas { 17 background: #000000; 18 display: block; 19 margin: 0; 20 } 21 22 body { 23 background: #555555; 24 } 25 26 #Canvas { 27 transform-origin: top left; 28 transform: scale(1.0); 29 } 30 31 #wrapper { 32 width: 900px; 33 height: 600px; 34 margin: auto; 35 onSelectStart: "return false;"; 36 user-select: none; 37 -moz-user-select: none; 38 -webkit-user-select: none; 39 -ms-user-select: none; 40 unselectable: "on"; 41 } 42 43 body { 44 overflow: hidden; 45 } 46 </style> 47 </head> 48 <body ontouchstart=""> 49 <div id="wrapper"> 50 <canvas id="Canvas" width="900px" height="600px"></canvas> 51 </div> 52 </body> 53</html>

javascript

1window.addEventListener("DOMContentLoaded", () => { 2 const canvasEle = 3 document.getElementById("Canvas"); 4 var ctx; 5 var ext = 1; 6 7 var touches = []; 8 9 var Cwidth = 900, 10 Cheight = 600; 11 12 function game() { 13 ctx.clearRect(0, 0, Cwidth, Cheight); 14 ctx.fillStyle = "#fff"; 15 for (t of touches) { 16 const x = getTouchesXY(t)[0]; 17 ctx.fillRect(x - 5, 0, 10, 600); 18 } 19 window.requestAnimationFrame(game); 20 } 21 22 function init() { 23 ctx = canvasEle.getContext("2d"); 24 setSize(); 25 window.requestAnimationFrame(game); 26 } 27 28 canvasEle.addEventListener("touchstart", () => { 29 event.preventDefault(); 30 touches = event.touches; 31 }, { 32 passive: false 33 }); 34 35 canvasEle.addEventListener("touchmove", () => { 36 event.preventDefault(); 37 touches = event.touches; 38 }, { 39 passive: false 40 }); 41 42 canvasEle.addEventListener("touchend", () => { 43 event.preventDefault(); 44 touches = event.touches; 45 }, { 46 passive: false 47 }); 48 49 canvasEle.addEventListener("touchcancel", () => { 50 event.preventDefault(); 51 touches = event.touches; 52 }, { 53 passive: false 54 }); 55 56 function setSize() { 57 var height = window.innerHeight; 58 var width = window.innerWidth; 59 60 Cheight = 600; 61 Cwidth = Math.floor(600 * width / height); 62 canvasEle.width = Cwidth; 63 canvasEle.height = Cheight; 64 65 ext = height / 600; 66 67 canvasEle.style.width = (Cwidth * ext) + "px"; 68 canvasEle.style.height = (Cheight * ext) + "px"; 69 70 var wrap = document.getElementById('wrapper'); 71 wrap.style.width = canvasEle.style.width; 72 wrap.style.height = canvasEle.style.height; 73 } 74 75 function getTouchesXY(touch) { 76 var rect = canvasEle.getBoundingClientRect(); 77 let x = (touch.clientX - (rect.left + window.pageXOffset)) / ext; 78 let y = (touch.clientY - (rect.top + window.pageYOffset)) / ext; 79 return [x, y]; 80 } 81 82 window.addEventListener("resize", setSize); 83 window.addEventListener("orientationchange", setSize); 84 init(); 85}); 86

追記

どこか別の場所をタッチし続けておけばこのバグは発生しないことが分かりました。
恐らく他のイベントに吸われてしまっているのかと思いますが、何が原因かまでは分かりませんでした⋯

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2023/02/25 02:20

まずは問題の発生するコードをご提示ください。
Butter

2023/02/25 06:08

すいません ソースコードです。 両方とも汚くて申し訳ありません⋯ jsの方はバグに関係無いところをカットしました どうやら画面縦向きだとこのバグは起きないようです (横向き前提で作っていたので気づきませんでした⋯) よろしくお願いします HTML---------- <!DOCTYPE html><html><head> <meta charset="utf-8"/> <meta name="description" content=""> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no"> <script type="text/javascript" src="script.js"></script> <title>Game</title> <style>*{padding: 0; margin: 0 auto;}canvas{background: #000000; display: block; margin: 0;}body{background: #555555;}#Canvas{transform-origin: top left; transform: scale(1.0);}#wrapper{width: 900px; height: 600px; margin: auto;onSelectStart:"return false;";user-select:none; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none;unselectable:"on";}body{overflow: hidden;}</style></head><body ontouchstart=""><div id="wrapper"><canvas id="Canvas" width="900px" height="600px"></canvas></div></body></html> js----------- window.addEventListener("DOMContentLoaded",()=>{ const canvasEle= document.getElementById("Canvas"); var ctx; var ext=1; var touches=[]; var Cwidth=900,Cheight=600; function game(){ ctx.clearRect(0,0,Cwidth,Cheight); ctx.fillStyle="#fff"; for(t of touches){ const x=getTouchesXY(t)[0]; ctx.fillRect(x-5,0,10,600); } window.requestAnimationFrame(game); } function init(){ ctx = canvasEle.getContext("2d"); setSize(); window.requestAnimationFrame(game); } canvasEle.addEventListener("touchstart",()=>{ event.preventDefault(); touches=event.touches; },{passive:false}); canvasEle.addEventListener("touchmove",()=>{ event.preventDefault(); touches=event.touches; },{passive:false}); canvasEle.addEventListener("touchend",()=>{ event.preventDefault(); touches=event.touches; },{passive:false}); canvasEle.addEventListener("touchcancel",()=>{ event.preventDefault(); touches=event.touches; },{passive:false}); function setSize(){ var height=window.innerHeight; var width=window.innerWidth; Cheight=600;Cwidth=Math.floor(600*width/height); canvasEle.width=Cwidth; canvasEle.height=Cheight; ext=height/600; canvasEle.style.width=(Cwidth*ext)+"px"; canvasEle.style.height=(Cheight*ext)+"px"; var wrap=document.getElementById('wrapper'); wrap.style.width=canvasEle.style.width; wrap.style.height=canvasEle.style.height; } function getTouchesXY(touch){ var rect = canvasEle.getBoundingClientRect(); let x=(touch.clientX-(rect.left + window.pageXOffset))/ext; let y=(touch.clientY-(rect.top + window.pageYOffset))/ext;return [x,y]; } window.addEventListener("resize", setSize); window.addEventListener("orientationchange",setSize); init(); });
m.ts10806

2023/02/25 06:11

質問は編集できますので本文に追記を。 また、コードはマークダウンでご提示を。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問