web-dev-qa-db-ja.com

Javascriptでタッチパッドとマウスを検出する

クライアントがタッチパッドを使用しているか、Javascriptでマウスを使用しているかを検出する方法はありますか?

または、少なくとも、マウスではなくタッチパッドを使用するユーザー数の合理的な見積もりを取得するには?

20
Fragsworth

一般的なケースでは、あなたが望むことをする方法はありません。 ActiveX might USBデバイスを表示および検査できますが、最良の場合、それが何らかの方法で可能であっても、IEユーザー。それを超えると、知る方法はありません。

タッチパッドユーザーがカーソルを移動する方法(または頻度)と、マウスユーザーがカーソルを移動する方法のパターンを識別できる場合があります。このように物理入力デバイスを区別することは、非常に困難な見通しであり、完全に不可能な場合があるため、ここでは完全を期すためにのみ含めます。

4
apsillers

このトピックはすでに解決されている可能性がありますが、答えはそれを検出する方法がないということでした。さて、私は解決策を得る必要がありました、それは非常に重要でした。だから私はこの問題の許容できる解決策を見つけました:

var scrolling = false;
var oldTime = 0;
var newTime = 0;
var isTouchPad;
var eventCount = 0;
var eventCountStart;

var mouseHandle = function (evt) {
    var isTouchPadDefined = isTouchPad || typeof isTouchPad !== "undefined";
    console.log(isTouchPadDefined);
    if (!isTouchPadDefined) {
        if (eventCount === 0) {
            eventCountStart = new Date().getTime();
        }

        eventCount++;

        if (new Date().getTime() - eventCountStart > 100) {
                if (eventCount > 10) {
                    isTouchPad = true;
                } else {
                    isTouchPad = false;
                }
            isTouchPadDefined = true;
        }
    }

    if (isTouchPadDefined) {
        // here you can do what you want
        // i just wanted the direction, for swiping, so i have to prevent
        // the multiple event calls to trigger multiple unwanted actions (trackpad)
        if (!evt) evt = event;
        var direction = (evt.detail<0 || evt.wheelDelta>0) ? 1 : -1;

        if (isTouchPad) {
            newTime = new Date().getTime();

            if (!scrolling && newTime-oldTime > 550 ) {
                scrolling = true;
                if (direction < 0) {
                    // swipe down
                } else {
                    // swipe up
                }
                setTimeout(function() {oldTime = new Date().getTime();scrolling = false}, 500);
            }
        } else {
            if (direction < 0) {
                // swipe down
            } else {
                // swipe up
            }
        }
    }
}

そして、イベントの登録:

document.addEventListener("mousewheel", mouseHandle, false);
document.addEventListener("DOMMouseScroll", mouseHandle, false);

最適化が必要な場合があり、完全ではない場合もありますが、機能します。少なくとも、MacBookのトラックパッドを検出できます。しかし、デザインのおかげで、パッドが多くのイベント呼び出しを導入する場所ならどこでも機能するはずです。

仕組みは次のとおりです。

ユーザーが最初にスクロールすると、50ミリ秒以内に5つ以下のイベントがトリガーされたことを検出して確認します。これは、通常のマウスでは非常に珍しいことですが、トラックパッドでは発生しません。

次に、elseの部分があります。これは、検出にとって重要ではなく、ユーザーがスワイプしたときのように関数を1回呼び出すためのトリックです。十分に明確でない場合は、私に来てください。これを機能させるのは非常に難しいことであり、もちろん理想的な回避策ではありません。

編集:コードを可能な限り最適化しました。 2回目にマウスロールを検出し、トラックパッドを即座にスワイプします。繰り返して不要なコードもたくさん削除しました。

編集2タイムチェックの数と呼び出されるイベントの数をそれぞれ50から100と5から10に変更しました。これにより、より正確な検出が可能になります。

15
David Fariña

JSイベントを検出できます。

タッチデバイスは、マウスイベントに加えて、touchstartなどのタッチイベントを発生させます。

非タッチデバイスは、マウスイベントのみを発生させます。

7
DA.

別のオプションは、Firefoxでe.wheelDeltaYとe.deltaYまたはe.deltaModeを比較することです。

function handler(e) {
    var isTouchPad = e.wheelDeltaY ? e.wheelDeltaY === -3 * e.deltaY : e.deltaMode === 0
    // your code
    document.body.textContent = isTouchPad ? "isTouchPad" : "isMouse"
}
document.addEventListener("mousewheel", handler, false);
document.addEventListener("DOMMouseScroll", handler, false);
2
Lauri

タッチパッドによってトリガーされたホイールイベントは、はるかに小さいevent.deltaY、1または2を生成しますが、マウスホイールによってトリガーされた場合は100,200のようになります。

2
Fei Sun

ローカルパッケージにインストールされているデバイスドライバソフトウェアが機能していることを確認するだけです。 Windowsシナプティクス、elanハードウェアと同様に、UNIX(Linux)の場合は、基本インストール中にインストールされたパッケージを確認するだけで済みます。多くのパッケージは、LinuxおよびLinuxのようなシステム(完全にLinuxではありません)の異なるバージョンで異なる形式で提供されますが、すべてに同じパッケージ名を使用します。それを引っ張るためのコードを知ったばかりです。まだ取り組んでいます。

0
CloakedSec

マウスを接続して、タッチパッドとタッチパッドを備えたWindowsマシンを備えたMacに接続するテストから、これがどのように機能したかを要約できます。

  1. ナビゲーターのユーザーエージェントに「モバイル」または「MacOS」が含まれているかどうかを検出します。これらのいずれかが当てはまる場合は、タッチベースのシステムである可能性がありますが、それを排除するように努めます。ブール値のhasTouchPadをtrueに設定します

  2. 上記が当てはまる場合は、「マウス」イベントを検出し、高い数値、非整数の頻度、またはカルマンフィルター処理などのテストを実行します。

  3. これらをキューに保持し、そのキューの合計がしきい値を超えた場合は、hasTouchpad変数を無効にして、イベントを切断します。

let isMouseCounts: Array<number> = []

if (Client.hasTouchpad) {
    document.addEventListener('wheel', detectMouseType);
}

function detectMouseType(e:WheelEvent) {
    if (!Client.hasTouchpad) return

    let isMouse = e.deltaX === 0 && !Number.isInteger(e.deltaY)

    isMouseCounts.Push(isMouse ? 1 : 0)
    if (isMouseCounts.length > 5) isMouseCounts.shift()

    let sum = isMouseCounts.reduce(function(a, b) { return a + b; });

    if (sum > 3 && e.type === "wheel") {
        console.log("Touchpad disabled")
        document.removeEventListener('wheel', detectMouseType);
        Client.hasTouchpad = false;
    }
}
0
Joel Teply