というわけで、Microsoft Surface 用の Web アプリケーションを作成しているときに、興味深い問題に遭遇しました。
ユーザーが DOM 要素を操作するときのイベント リスナーを追加したいと考えています。今私はできる:
if ('ontouchstart' in document.documentElement) {
//Attach code for touch event listeners
document.addEventListener("touchstart" myFunc, false);
} else {
//Attach code for mouse event listeners
document.addEventListener("mousedown" myFunc, false);
}
デバイスにマウス入力がない場合、この問題は単純で、上記のコードは問題なく機能します。しかし、Surface (および多くの新しい Windows 8 コンピューター) には、タッチ入力とマウス入力の両方があります。したがって、上記のコードは、ユーザーがデバイスに触れたときにのみ機能します。マウス イベント リスナーがアタッチされることはありません。
それで、私はこれを行うことができると思いました:
if ('ontouchstart' in document.documentElement) {
//Attach code for touch event listeners
document.addEventListener("touchstart" myFunc, false);
}
//Always attach code for mouse event listeners
document.addEventListener("mousedown" myFunc, false);
タッチをサポートしていないデバイスにはイベントが関連付けられていませんが、タッチを使用するデバイスはそのハンドラーを登録します。ただし、これの問題はmyFunc()
、タッチ デバイスで 2 回呼び出されることです。
myFunc()
「touchstart」が発生すると起動します- タッチブラウザは通常、touchstart -> touchmove -> touchend -> mousedown -> mousemove -> mouseup -> clickのサイクルを経るため
myFunc()
、「mousedown」で再度呼び出されます
myFunc()
呼び出すようなコードを追加することを検討しましたが、これは touchendだけでなく、一部のブラウザーではmousedown / mousemove / mouseupe.preventDefault()
もブロックするようです( link )。
私は useragent sniffer を行うのは嫌いですが、タッチ ブラウザーにはタッチ イベントの実装方法にバリエーションがあるようです。
確かにこれらの JavaScript 実装は、マウスとタッチの両方をサポートするブラウザーの可能性を考慮して決定されたように思われるため、何かが欠けているに違いありません!