web-dev-qa-db-ja.com

ブラウザにマウスがなく、タッチのみであることを検出する

私は、タッチ(クリックすると画面が非表示になる)とマウス(ホバープレビューに大きく依存)のインターフェイスが非常に異なるwebapp(興味深いテキストのページを含むWebサイトではない)を開発しています。ユーザーに適切なインターフェイスを表示するマウスがないことを検出するにはどうすればよいですか?マウスとタッチ(一部のノートブックなど)の両方を使用するユーザーにはスイッチを残す予定です。

ブラウザーのタッチイベント機能は、実際にはユーザーがタッチデバイスを使用していることを意味しません(たとえば、Modernizrはそれをカットしません)。質問に正しく答えるコードは、デバイスにマウスがある場合はfalseを返し、そうでない場合はtrueを返します。マウスとタッチを備えたデバイスの場合、falseを返す必要があります(タッチのみではありません)

補足として、私のタッチインターフェイスはキーボードのみのデバイスにも適している可能性があるため、検出しようとしているマウスが不足しています。

必要性をより明確にするために、私が実装しようとしているAPIは次のとおりです。

// Level 1


// The current answers provide a way to do that.
hasTouch();

// Returns true if a mouse is expected.
// Note: as explained by the OP, this is not !hasTouch()
// I don't think we have this in the answers already, that why I offer a bounty
hasMouse();

// Level 2 (I don't think it's possible, but maybe I'm wrong, so why not asking)

// callback is called when the result of "hasTouch()" changes.
listenHasTouchChanges(callback);

// callback is called when the result of "hasMouse()" changes.
listenHasMouseChanges(callback);
138
nraynaud

主な問題は、次の異なるクラスのデバイス/ユースケースがあることです。

  1. マウスとキーボード(デスクトップ)
  2. タッチのみ(電話/タブレット)
  3. マウス、キーボード、およびタッチ(ラップトップにタッチ)
  4. タッチとキーボード(タブレットのBluetoothキーボード)
  5. マウスのみ(無効なユーザー/閲覧設定)
  6. キーボードのみ(無効なユーザー/閲覧設定)
  7. タッチアンドマウス(つまり、Galaxy Note 2ペンからのホバーイベント)

さらに悪いことに、これらのクラスのいくつかから他のクラスに移行できる(マウスを接続し、キーボードに接続する)か、ユーザーが手を伸ばして画面に触れるまで通常のラップトップにいるように見える場合があります。

ブラウザーにイベントコンストラクターが存在することは、前進するのに適した方法ではない(そして多少一貫性がない)と仮定するのは正しいことです。さらに、非常に特定のイベントを追跡している場合、または上記のいくつかのクラスのみを除外しようとしている場合を除き、イベント自体の使用は完全な証拠ではありません。

たとえば、ユーザーが実際のマウスムーブを発したことを発見したとしましょう(タッチイベントからの偽のマウスムーブではありません。 http://www.html5rocks.com/en/mobile/touchandmouse/ を参照) 。

じゃあ何?

ホバースタイルを有効にしますか?さらにボタンを追加しますか?

いずれにせよ、イベントが発生するのを待つ必要があるため、グラスまでの時間が増えています。

しかし、高貴なユーザーがマウスを抜いてフルタッチにしたいと決めた場合、どうなりますか。彼が今ぎゅうぎゅう詰めのインターフェイスに触れるのを待って、混雑したUIを正確に特定しようとした直後に変更しますか?

箇条書きの形式で https://github.com/Modernizr/Modernizr/issues/869#issuecomment-15264101 でstucoxを引用

  • マウスの存在を検出したい
  • Aeはおそらくイベントが発生する前に検出できません
  • そのため、私たちが検出しているのは、このセッションでマウスが使用されているかどうかです。マウスはページの読み込みからすぐにではありません
  • おそらく、マウスがないことも検出できません。trueになるまで未定義になります(証明されるまでfalseに設定するよりも理にかなっていると思います)
  • また、セッション中にマウスが切断されたかどうかはおそらく検出できません。これは、マウスをあきらめただけのユーザーと区別できません。

余談:ブラウザは、ユーザーがマウスを接続したりキーボードに接続したりすることを認識しますが、JavaScriptに公開しません。

これにより、次のようになります。

特定のユーザーの現在の能力を追跡することは、複雑で信頼性が低く、疑わしいメリットがあります

ただし、ここではプログレッシブエンハンスメントのアイデアが非常によく当てはまります。ユーザーのコンテキストに関係なくスムーズに機能するエクスペリエンスを構築します。次に、ブラウザの機能/メディアクエリに基づいて想定を行い、想定されるコンテキストに関連する機能を追加します。マウスの存在は、さまざまなデバイスのさまざまなユーザーがWebサイトを体験する方法の1つにすぎません。カーネルにメリットのあるものを作成し、ボタンをクリックする方法についてあまり心配しないでください。

59
Wyatt

文書のmousemoveイベントをリッスンしてください。その後、そのイベントを聞くまで、デバイスはタッチまたはキーボードのみであると想定します。

var mouseDetected = false;
function onMouseMove(e) {
  unlisten('mousemove', onMouseMove, false);
  mouseDetected = true;
  // initializeMouseBehavior();
}
listen('mousemove', onMouseMove, false);

(必要に応じて、listenおよびunlistenaddEventListenerまたはattachEventに委任する場所。)

うまくいけば、これが視覚的な余計なものにならないようにし、モードに基づいて大規模な再レイアウトが必要な場合はそれが悪いでしょう...

55
Dan

@Wyattの答えは素晴らしく、考えることがたくさんあります。

私の場合、最初のインタラクションをリッスンし、その後にのみ動作を設定することにしました。そのため、ユーザーがマウスを使用していても、最初の操作がタッチだった場合はタッチデバイスとして扱います。

イベントが処理される所定の順序

  1. タッチスタート
  2. タッチムーブ
  3. タッチエンド
  4. マウスオーバー
  5. マウスムーブ
  6. マウスダウン
  7. マウスアップ
  8. クリック

タッチの前にマウスイベントがトリガーされた場合、それはエミュレートされたイベントではなく、実際のマウスイベントであると想定できます。例(jQueryを使用):

$(document).ready(function() {
    var $body = $('body');
    var detectMouse = function(e){
        if (e.type === 'mousedown') {
            alert('Mouse interaction!');
        }
        else if (e.type === 'touchstart') {
            alert('Touch interaction!');
        }
        // remove event bindings, so it only runs once
        $body.off('mousedown touchstart', detectMouse);
    }
    // attach both events to body
    $body.on('mousedown touchstart', detectMouse);
});

それは私のために働いた

23
Hugo Silva

2018年の時点で、ブラウザにマウス(または同様の入力デバイス)があるかどうかを検出するための優れた信頼できる方法があります:CSS4メディアインタラクション機能ほとんどの最新ブラウザでサポートされています(IE 11および特別なモバイルブラウザを除く)。

W3C:

ポインターメディア機能は、マウスなどのポインティングデバイスの存在と精度を照会するために使用されます。

次のオプションを参照してください。

    /* The primary input mechanism of the device includes a 
pointing device of limited accuracy. */
    @media (pointer: coarse) { ... }

    /* The primary input mechanism of the device 
includes an accurate pointing device. */
    @media (pointer: fine) { ... }

    /* The primary input mechanism of the 
device does not include a pointing device. */
    @media (pointer: none) { ... }

    /* Primary input mechanism system can 
       hover over elements with ease */
    @media (hover: hover) { ... }

    /* Primary input mechanism cannot hover 
       at all or cannot conveniently hover 
       (e.g., many mobile devices emulate hovering
       when the user performs an inconvenient long tap), 
       or there is no primary pointing input mechanism */
    @media (hover: none) { ... }

    /* One or more available input mechanism(s) 
       can hover over elements with ease */
    @media (any-hover: hover) { ... }


    /* One or more available input mechanism(s) cannot 
       hover (or there are no pointing input mechanisms) */
    @media (any-hover: none) { ... }

メディアクエリはJSでも使用できます。

if(window.matchMedia("(any-hover: none)").matches) {
    // do sth
}

関連する:

公式のワーキングドラフト: https://drafts.c​​sswg.org/mediaqueries/#mf-interaction

ブラウザのサポート: https://caniuse.com/#search=media%20features

同様の問題: クライアントデバイスが:hoverおよび:focus状態をサポートしているかどうかを検出

18
Blackbam

ブラウザがタッチされているかどうかのみを検出できますcapable。実際にタッチスクリーンまたはマウスが接続されているかどうかを知る方法はありません。

ただし、タッチ機能が検出された場合、マウスイベントの代わりにタッチイベントをリッスンすることで、使用を優先できます。

タッチ機能のクロスブラウザーを検出するには:

function hasTouch() {
    return (('ontouchstart' in window) ||       // html5 browsers
            (navigator.maxTouchPoints > 0) ||   // future IE
            (navigator.msMaxTouchPoints > 0));  // current IE10
}

次に、これを使用して以下を確認できます。

if (!hasTouch()) alert('Sorry, need touch!);

または、リッスンするイベントを選択するには、次のいずれかを実行します。

var eventName = hasTouch() ? 'touchend' : 'click';
someElement.addEventListener(eventName , handlerFunction, false);

または、タッチと非タッチに別々のアプローチを使用します。

if (hasTouch() === true) {
    someElement.addEventListener('touchend' , touchHandler, false);

} else {
    someElement.addEventListener('click' , mouseHandler, false);

}
function touchHandler(e) {
    /// stop event somehow
    e.stopPropagation();
    e.preventDefault();
    window.event.cancelBubble = true;
    // ...
    return false; // :-)
}
function mouseHandler(e) {
    // sorry, touch only - or - do something useful and non-restrictive for user
}

マウスについては、マウスが存在するかどうかではなく、マウスが使用されているかどうかのみを検出できます。グローバルフラグを設定して、マウスが使用法によって検出されたことを示すことができます(既存の回答に似ていますが、少し簡略化されています)。

var hasMouse = false;

window.onmousemove = function() {
    hasMouse = true;
}

mouseupまたはmousedownを含めることはできません。これらのイベントはタッチでもトリガーできるためです)

ブラウザは、使用されているシステムのハードウェア機能などの機能を検出するために必要な低レベルのシステムAPIへのアクセスを制限します。

これらにアクセスするためのプラグイン/拡張機能を作成する可能性がありますが、JavaScriptおよびDOMを介してこのような検出はこの目的に制限され、さまざまなOSプラットフォームに固有のプラグインを作成する必要があります。

結論として、このような検出は「良い推測」によってのみ推定できます。

9
user1693593

ブラウザで Media Queries Level 4 が使用可能な場合、「ポインター」および「ホバー」クエリを使用して、マウスでデバイスを検出できます。

本当にその情報をJavascriptに伝えたい場合は、CSSクエリを使用してデバイスタイプに応じて特定のスタイルを設定し、JavascriptでgetComputedStyleを使用してそのスタイルを読み取り、元のデバイスタイプをそれ。

しかし、マウスはいつでもconnectedまたはunpluggedであり、ユーザーがタッチとマウスを切り替えたい場合があります。そのため、この変更をdetectし、インターフェースの変更を提案するか、自動的に行う必要があるかもしれません。

8
joeytwiddle

とにかくインターフェースを切り替える方法を提供することを計画しているので、アプリケーションの正しいバージョンを「入力」するためにリンクまたはボタンをクリックするようにユーザーに単純に求めることは実行可能でしょうか?そうすれば、将来の訪問に対する彼らの好みを思い出すことができます。ハイテクではありませんが、100%信頼できます:-)

6
Brandan

@SamuelRossille残念ながら、マウスの存在(またはその欠如)を公開していることを知っているブラウザはありません。

それで、それが言われているので、既存のオプション...イベントでできる限りのことをしようとするだけです。私はそれがあなたが探しているものそのものではないことを知っています...それは現在理想から程遠いことに同意しました。

ユーザーがいつでもマウスまたはタッチを使用しているかどうかを把握するために最善を尽くすことができます。 jQueryとKnockoutを使用した簡単で汚い例を次に示します。

//namespace
window.ns = {};

// for starters, we'll briefly assume if touch exists, they are using it - default behavior
ns.usingTouch = ko.observable(Modernizr.touch); //using Modernizr here for brevity.  Substitute any touch detection method you desire

// now, let's sort out the mouse
ns.usingMouse = ko.computed(function () {
    //touch
    if (ns.usingTouch()) {
        //first, kill the base mousemove event
        //I really wish browsers would stop trying to handle this within touch events in the first place
        window.document.body.addEventListener('mousemove', function (e) {
            e.preventDefault();
            e.stopImmediatePropagation();
        }, true);

        //remove mouse class from body
        $('body').removeClass("mouse");

        //switch off touch listener
        $(document).off(".ns-touch");

        // switch on a mouse listener
        $(document).on('mousemove.ns-mouse', function (e) {
            if (Math.abs(window.lastX - e.clientX) > 0 || window.lastY !== e.clientY) {
                ns.usingTouch(false);  //this will trigger re-evaluation of ns.usingMouse() and result in ns.usingMouse() === true
            }
        });

        return false;
    }
    //mouse
    else {
        //add mouse class to body for styling
        $('body').addClass("mouse");

        //switch off mouse listener
        $(document).off(".ns-mouse");

        //switch on a touch listener
        $(document).on('touchstart.ns-touch', function () { ns.usingTouch(true) });

        return true;
    }
});

//tests:
//ns.usingMouse()
//$('body').hasClass('mouse');

Usingbind/subscribe usingMouse()usingTouch()および/またはbody.mouseクラス。インターフェースは、マウスカーソルが検出されるとすぐにタッチスタートで切り替わります。

ブラウザベンダーからより良いオプションがまもなく提供されることを願っています。

4
daredev

タッチを検知したり、マウスの動きに反応したりする能力があるかどうかを検出してみませんか?

// This will also return false on
// touch-enabled browsers like Chrome
function has_touch() {
  return !!('ontouchstart' in window);
}

function has_mouse() {
  return !!('onmousemove' in window);
}
2
iblue

これは私にとって同様の状況で機能しました。基本的に、ユーザーがマウスダウンやマウスアップに介入することなく、連続した短い一連のマウスの動きを見るまでマウスを持っていないと仮定します。あまりエレガントではありませんが、機能します。

var mousedown = false;
var mousemovecount = 0;
function onMouseDown(e){
    mousemovecount = 0;
    mousedown = true;
}
function onMouseUp(e){
    mousedown = false;
    mousemovecount = 0;
}
function onMouseMove(e) {
    if(!mousedown) {
        mousemovecount++;
        if(mousemovecount > 5){
            window.removeEventListener('mousemove', onMouseMove, false);
            console.log("mouse moved");
            $('body').addClass('has-mouse');
        }
    } else {
        mousemovecount = 0;
    }
}
window.addEventListener('mousemove', onMouseMove, false);
window.addEventListener('mousedown', onMouseDown, false);
window.addEventListener('mouseup', onMouseUp, false);
2

Tera-WURFL は、サイトにアクセスしているデバイスの機能を示しますブラウザの署名を比較することによりデータベースと比較します。無料でご覧ください。

2
Gigi

ここで見た主な問題は、ほとんどのタッチデバイスが対応するタッチイベント(touchstart-> mousedown、touchmove-> mousemoveなど)とともにマウスイベントを発生させることです。キーボードのみのもの、最後に現代のもの、それらは汎用ブラウザを持っているので、MouseEventクラスの存在を検出することさえできません。

ここでの苦痛の少ない解決策は、私の意見では、起動時にメニューを表示し(キーボードのみのユーザーに対して「alt」管理を使用)、おそらくlocalStorage/cookies/serversideで選択を保存するか、次の選択肢を維持することです訪問者が来る時間。

0
Ernoriel

私の意見では、mousemoveリスナー(現在、一番の答え)が最良のアイデアです。この方法は少し調整する必要があると思います。 このiOSの議論 でわかるように、タッチベースのブラウザーはmousemoveイベントでさえエミュレートするのは事実です。したがって、少し注意が必要です。

タッチベースのブラウザは、ユーザーが画面をタップしたとき(ユーザーの指が下になったとき)にのみこのイベントをエミュレートすることは理にかなっています。これは、イベント中にどのマウスボタンが押されているか(ある場合)を確認するために、mousemoveハンドラーでテストを追加する必要があることを意味します。マウスボタンが押されていない場合は、実際のマウスが存在していると想定できます。マウスボタンが押されている場合、テストは決定的ではありません。

それで、これはどのように実装されますか?この question は、mousemove中にどのマウスボタンが押されているかを調べる最も信頼できる方法が、実際にドキュメントレベルで3つのイベント(mousemove、mousedown、mouseup)をリッスンすることであることを示しています上下はグローバルブールフラグのみを設定します。移動によりテストが実行されます。動きがあり、ブール値がfalseの場合、マウスが存在すると想定できます。正確なコード例については質問をご覧ください。

最後のコメント..このテストは、ロード時に実行できないため理想的ではありません。したがって、以前に提案されたプログレッシブエンハンスメント方法を使用します。デフォルトでは、マウス固有のホバーインターフェイスをサポートしないバージョンを表示します。マウスが検出された場合、JSを使用してランタイムでこのモードを有効にします。これは、ユーザーにとってできるだけシームレスに表示されるはずです。

ユーザーの構成の変更(つまり、マウスが切断された)をサポートするために、定期的に再テストできます。この場合、2つのモードについてユーザーに通知し、ユーザーが手動で切り替えられるようにする方がよいと考えています(モバイル/デスクトップの選択は常に元に戻すことができます)。

0
talkol

マウスの使用を検出するjQueryのシンプルなソリューション。モバイルデバイスも「mousemove」イベントをトリガーする問題を解決します。タッチスタートリスナーを追加してmousemoveリスナーを削除するだけで、タッチ時にトリガーされないようにできます。

$('body').one('touchstart.test', function(e) {
  // Remove the mousemove listener for touch devices
  $('body').off('mousemove.test');
}).one('mousemove.test', function(e) {
  // MOUSE!
});

もちろん、デバイスはまだタッチANDマウスでもかまいませんが、上記は実際のマウスが使用されたことを保証します。

0
suncat100

Phonegapアプリでこの問題を解明するのに何時間も費やし、このハックを思いつきました。トリガーされたイベントが「パッシブ」イベントである場合、コンソールの警告を生成します。つまり、変更は行われませんが、機能します。改善するためのアイデアや、より良い方法に興味があります。しかしこれにより、実質的に$ .touch()を普遍的に使用できます。

$(document).ready(function(){
  $("#aButton").touch(function(origElement, origEvent){
    console.log('Original target ID: ' + $(origEvent.target).attr('id'));
  });
});

$.fn.touch = function (callback) {
    var touch = false;
    $(this).on("click", function(e){
        if (!touch)
        {
            console.log("I click!");
            let callbackReal = callback.bind(this);
            callbackReal(this, e);
        }else{
            touch = true;
        }
        touch = false;
    });
    $(this).on("touchstart", function(e){
        if (typeof e.touches != typeof undefined)
        {
            e.preventDefault();
            touch = true;
            console.log("I touch!");
            let callbackReal = callback.bind(this);
            callbackReal(this, e);
        }
    });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button id="aButton">A Button</button>
0
Jay

(もちろん私の知る限りでは)タッチのみのデバイスを識別することは不可能だと思います。主な問題は、すべてのマウスおよびキーボードイベントがタッチデバイスでも発生することです。次の例を参照してください。タッチデバイスの場合、両方のアラートがtrueを返します。

function is_touch_present() {
  return ('ontouchstart' in window) || ('onmsgesturechange' in window);
}

function is_mouse_present() {
  return (('onmousedown' in window) && ('onmouseup' in window) && ('onmousemove' in window) && ('onclick' in window) && ('ondblclick' in window) && ('onmousemove' in window) && ('onmouseover' in window) && ('onmouseout' in window) && ('oncontextmenu' in window));
}

alert("Touch Present: " + is_touch_present());
alert("Mouse Present: " + is_mouse_present());
0
Bikas

私は同じ問題に遭遇しました。そこでは、ワンタッチもクリックとして登録されました。上位投票の回答のコメントを読んだ後、私は自分の解決策を思いつきました:

var body = document.getElementsByTagName('body')[0];
var mouseCount = 0;

// start in an undefined state 
// (i use this to blend in elements once we decide what input is used)
var interactionMode = 'undefined';


var registerMouse = function() {
  // count up mouseCount every time, the mousemove event is triggered
  mouseCount++;

  // but dont set it instantly. 
  // instead wait 20 miliseconds (seems to be a good value for multiple move actions), 
  // if another mousemove event accoures switch to mouse as interaction 
  setTimeout(function() {
    // a touch event triggers also exactly 1 mouse move event.
    // So only if mouseCount is higher than 1 we are really moving the cursor by mouse.
    if (mouseCount > 1) {
      body.removeEventListener('mousemove', registerMouse);
      body.removeEventListener('touchend', registerTouch);

      interactionMode = 'mouse';
      console.log('now mousing');
      listenTouch();
    }

    // set the counter to zero again
    mouseCount = 0;
  }, 20);
};

var registerTouch = function() {
  body.removeEventListener('mousemove', registerMouse);
  body.removeEventListener('touchend', registerTouch);

  interactionMode = 'touch';
  console.log('now touching');
  mouseCount = 0;

  listenMouse();
};

var listenMouse = function() {
  body.addEventListener("mousemove", registerMouse);
};
var listenTouch = function() {
  body.addEventListener("touchend", registerTouch);
};

listenMouse();
listenTouch();

// after one second without input, assume, that we are touching
// could be adjusted to several seconds or deleted
// without this, the interactionMode would stay 'undefined' until first mouse or touch event
setTimeout(function() {
  if (!body.classList.contains('mousing') || body.classList.contains('touching')) {
    registerTouch();
  }
}, 1000);
/* fix, so that scrolling is possible */

html,
body {
  height: 110%;
}
Mouse or touch me

私が見つけた唯一の問題は、タッチイベントを適切に検出するために、スクロールできる必要があるということです。単一のタブ(タッチ)で問題が発生する場合があります。

さまざまなPC、Linux、iPhoneでいくつかのテストを実行しました。Android電話とタブ。簡単な防弾ソリューションがないことは奇妙です。アプリケーションへのマウスイベント:マウスのみとタッチのみのインスタンスをサポートしたいので、両方を処理したいが、これにより、ユーザーインタラクションが2回発生します。デバイスにマウスが存在しないことがわかっている場合、fake /マウスイベントを挿入しました。MouseMoveに遭遇した場合にフラグを設定しようとしましたが、一部のブラウザは偽のMouseMoveとMouseUpおよびMouseDownをスローしました。挿入されたMouseDownの直前の単一のMouseMove。私のケースの99.99%で、実際のマウスを持つシステムで実行している場合、複数の連続したMouseMoveイベント(少なくとも2つ)があります。この条件が満たされない場合、イベントを移動し、マウスが存在しないことを宣言します。これはおそらく簡単すぎるかもしれませんが、すべてのテスト設定で機能します。より良い解決策を見つけるまで、私はそれを固執すると思います。 -ジムW

0
jwasch

他の人が指摘したように、マウスを持っているかどうかを明確に検出することは信頼できません。これは、デバイスに応じて簡単に変更できます。少なくともドキュメントスケールでは、ブール値のtrueまたはfalseで確実に行うことはできません。

タッチイベントとマウスイベントは排他的です。そのため、これはさまざまなアクションを実行するのにいくらか役立ちます。問題は、タッチイベントがマウスアップ/ダウン/移動イベントに近く、クリックイベントをトリガーすることです。

あなたの質問から、ホバーしてプレビューしたいと言います。それ以外は、インターフェイスに関する他の詳細は知りません。私は仮定マウスがないので、タップしてプレビューしたいのですが、クリックするとホバープレビューのために異なるアクションを実行します。

その場合は、検出に怠laなアプローチを使用できます。

Onclickイベントの前には、常にマウスによるonmouseoverイベントが発生します。マウスがクリックされた要素の上にあることに注意してください。

これは、ドキュメント全体のonmousemoveイベントで実行できます。 event.targetを使用して、マウスが置かれている要素を記録できます。次に、onclickイベント内で、クリックされている要素(または要素の子)上にマウスが実際にあるかどうかを確認できます。

そこから、両方のクリックイベントに依存するか、結果に応じてAまたはBアクションを実行するかを選択できます。一部のタッチデバイスがクリックイベントを発行しない場合、Bアクションは何もできません(代わりに、ontouch *イベントに依存する必要があります)。

0
Luke

Modenizrの機能の1つはタッチです

http://modernizr.com/docs/#features-misc

完全にはテストしていませんが、非常にうまく機能しているようです

また、これはmodernizrページからリンクされています http://www.html5rocks.com/en/mobile/touchandmouse/

0
exussum

私は非常にエレガントだと思う解決策を見つけました。

// flag as mouse interaction by default
var isMouse = true;

// detect a touch event start and flag it
$(window).on('touchstart', function () {
  // if triggers touchstart, toggle flag
  // since touch events come before mouse event / click
  // callback of mouse event will get in callback
  // `isMouse === false`
  isMouse = false;
});

// now the code that you want to write
// should also work with `mouse*` events
$('a.someClass').on('click', function () {
  if (isMouse) {
    // interaction with mouse event
    // ...
  } else {
    // reset for the next event detection
    // this is crucial for devices that have both
    // touch screen and mouse
    isMouse = true;

    // interaction with touch event
    // ...
  }
});
0
Koala Yeung