電子書籍の厳選無料作品が豊富!

表題の処理を、JavaScriptで実装したいと考えています
タッチ操作可能のノートPCでの実装を想定しています(スマホなどは想定していません)
ブラウザはIE11のみ

当初、pointerdownの座標とpointerupの座標を比較することを想定していましたが以下2点で躓いております
①フリック操作を行うと、pointerdownの後にpointerleave,pointercancel となりpointerupが発生しませんでした

②上記の3つのイベントの際のプロパティ内の座標がすべて同じ値のため、移動方向が判定できません


①、②の理由
別の方法があれば、ご教授いただきたく思います

・HTML
<div id="outer">
<div class="inner"></div>
<div class="inner"></div>
<div class="inner"></div>
<div class="inner"></div>
</div>

・JS
$("#outer").on("pointerdown",function(e){
console.log(e.pageX)
console.log(e.pageY)
});
$("#outer").on("pointerleave",function(e){
console.log(e.pageX)
console.log(e.pageY)
});
$("#outer").on("pointercancel",function(e){
console.log(e.pageX)
console.log(e.pageY)
});

A 回答 (1件)

こんにちは



回答が無いようですので・・・
IEはよくわかりませんが、手元にあったIE11でテスト的に実験しただけの内容です。
(正しい方法かどうかは不明です)

概ね以下の経緯を辿りました。
(アロー関数が使えないのに気が付くだけで、大分かかってしまった…汗)
1)質問者様同様のテストをしてみたところ、確かに、pointermoveやpointerupのイベントが発生しないことを確認。

2)デフォルトではタッチイベントはマウスイベントとしても発火しているはずなので、mousedown、mousemove、mouseupに切り替えてテストしてみる。
各イベントは発生するが、どうやらmousemove、mouseupがmousedownと同時に発生してしまっている模様。
(mousemoveが、必ず1度しか発生しない)
また、ポインター位置が、全て同じ値となってしまう。

3)ブラウザ側のタッチに対する反応を停止すべく、CSSで touch-action:none; を設定。
これによって、各イベントが順次発生し、ポインター位置も取得できるようになることを確認。

・・・ということで、以下のサンプルはかなり適当ですが、上記を確認した時のものです。
「フリック」を抽出とのご質問でしたので、「タッチの継続最大時間」と「移動の最小距離」を設定しておいて、最大時間を超えたらドラッグ等と考え、最小移動距離を越えなければタッチのみと見做してフリックとは扱わないようにしています。
(時間:tLimit:400 と、距離:dLimit:20 の値はとりあえずの適当です)

以下は、テスト用に作成したものなので、一行目に「フリックの判定と移動方向」が表示されるだけのものです。
(テスト用なので、継ぎはぎの修正ものですが、ご参考にでもなれば。)


<!DOCTYPE HTML>
<html lang="ja">
<head><title>Sample</title>

<style type="text/css">
body { touch-action:none; }
#outer{ height:90vh; background-color:#EFF; }
</style>

<script type="text/javascript">
let flickObj = {
flag:false, start:false, sTime:0,
dLimit:25, tLimit:400,
coordS:[], coordE:[]
}

flickObj.funcs = {
mousedown:function(e){
let f = flickObj;
f.start = true;
f.flag = false;
f.sTime = new Date();
f.coordS = [e.pageX, e.pageY];
f.coordE = [e.pageX, e.pageY];
},

mousemove:function(e){
let f = flickObj;
if(!f.start) return;
f.coordE = [e.pageX, e.pageY];
if( Math.abs(f.coordE[0] - f.coordS[0]) > f.dLimit) f.flag = true;
if( Math.abs(f.coordE[1] - f.coordS[1]) > f.dLimit) f.flag = true;
},

mouseup:function(e){
flickObj.funcs.mousemove(e);
let f = flickObj;
f.start = false;
if((new Date() - f.sTime)>f.tLimit) f.flag = false;

/*** 判定結果と方向表示 ***/
let info = f.flag?"Flicked! ":"Not Flick ";
if(f.flag){
info +=", dx=" + (f.coordE[0]-f.coordS[0]).toFixed(2)
+ "px, dy=" + (f.coordE[1]-f.coordS[1]).toFixed(2) + "px";
}
document.getElementById("info").innerHTML = info;
}
}

/* イベント設定 */
for(let e in flickObj.funcs){
document.addEventListener(e, flickObj.funcs[e] )
};
</script>

</head>
<body>

<div id="info">info</div>
<div id="outer"></div>

</body>
</html>
    • good
    • 0
この回答へのお礼

丁寧な回答及び、ソースコードの提示までいただきありがとうございます
>CSSで touch-action:none;
が盲点でした

上記設定後、pointerdown,pointerupともに発火し、座標取得できました
ありがとうございました

お礼日時:2020/08/01 21:09

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!