JavaScriptを使用して「タッチスクリーン」デバイスを検出する最良の方法は何ですか?


416

デスクトップとモバイルの両方のデバイスで使用するためのjQueryプラグインを作成しました。デバイスにタッチスクリーン機能があるかどうかを検出する方法がJavaScriptにあるかどうか疑問に思いました。jquery-mobile.jsを使用してタッチスクリーンイベントを検出し、iOS、Androidなどで動作しますが、ユーザーのデバイスにタッチスクリーンがあるかどうかに基づいて条件ステートメントを記述したいと思います。

それは可能ですか?


これは、document.documentElementのvar x = 'touchstart'のより良い方法です。console.log(x)//サポートされている場合はtrueを返します//それ以外の場合はfalseを返します
Risa__B

新しいテクニックがまだ出現しているのに、なぜこのスレッドが保護されているのですか?
アンディホフマン

回答:


139

更新:機能検出ライブラリ全体をプロジェクトに取り込む前に、下記のblmstrの回答を読んでください。実際のタッチサポートの検出はより複雑であり、Modernizrは基本的な使用例のみをカバーしています。

Modernizrは、あらゆるサイトであらゆる種類の特徴検出を行うための優れた軽量な方法です。

各機能のhtml要素にクラスを追加するだけです。

その後、CSSおよびJSでこれらの機能を簡単にターゲットにできます。例えば:

html.touch div {
    width: 480px;
}

html.no-touch div {
    width: auto;
}

そしてJavaScript(jQueryの例):

$('html.touch #popup').hide();

88
Modernizrはタッチスクリーンをテストしません。これは、ブラウザー内のタッチイベントの存在をテストします。ドキュメントの「その他のテスト」セクションを参照してください:modernizr.com/docs/#features-misc
Harry Love

1
(Modernizr.touch){/ * do touch stuff /} else {/ fine、do n't * /}の場合、タッチイベントの存在についてJSテストを実行することもできます
Anatoly G

7
@harryloveの要点として、Windows 8がリリースされて以来、Modernizrは私のPCのすべてのブラウザーをタッチ互換として誤って返してきました。
アントン

3
更新:blmstrの答えはより良く、純粋なJavascriptソリューションです。
アランクリストファートーマス

1
Modernizr.touch予期せずが返された場合はundefined、タッチイベント検出をサポートしていない、カスタマイズされたModernizr(選択して選択する)が存在する可能性があります。
Henrik N

679

この機能を使ってみましたか?(これは、Modernizrが使用していたものと同じです。)

function is_touch_device() {  
  try {  
    document.createEvent("TouchEvent");  
    return true;  
  } catch (e) {  
    return false;  
  }  
}

console.log(is_touch_device());

アップデート1

document.createEvent("TouchEvent")true最新のクローム(v。17)で戻ってきました。Modernizrはこれを少し前に更新しました。ここでModernizrテストをチェックしてください

このように関数を更新して、機能させます。

function is_touch_device1() {
  return 'ontouchstart' in window;
}

console.log(is_touch_device1());

アップデート2

上記はIE10では機能していないことがわかりました(MS Surfaceではfalseを返します)。ここに修正があります:

function is_touch_device2() {
  return 'ontouchstart' in window        // works on most browsers 
  || 'onmsgesturechange' in window;  // works on IE10 with some false positives
};

console.log(is_touch_device2());

アップデート3

'onmsgesturechange' in window一部のIEデスクトップバージョンではtrueが返されるため、信頼性は高くありません。これは少し確実に機能します:

function is_touch_device3() {
  return !!('ontouchstart' in window        // works on most browsers 
  || navigator.maxTouchPoints);       // works on IE10/11 and Surface
};

console.log(is_touch_device3());

2018年の更新

時間が経つにつれ、これをテストする新しいより良い方法があります。基本的に、Modernizrによるチェック方法を抽出して簡略化しました。

function is_touch_device4() {
    
    var prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
    
    var mq = function (query) {
        return window.matchMedia(query).matches;
    }

    if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
        return true;
    }

    // include the 'heartz' as a way to have a non matching MQ to help terminate the join
    // https://git.io/vznFH
    var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
    return mq(query);
}

console.log(is_touch_device4());

ここで彼らは非標準のtouch-enabledメディアクエリ機能を使用していますが、これはちょっと奇妙で悪い習慣だと思います。しかし、ちょっと、現実の世界では、それはうまくいくと思います。(これらはすべてでサポートされています)将来的にはこれらのメディアクエリの機能はあなたに同じ結果を与えることができる:pointerhover

Modernizrがどのように実行しているかソースを確認してください。

タッチ検出の問題を説明する優れた記事については、「Stu Cox:You Ca n't Detect a Touchscreen」を参照してください 。


20
ダブルバングは値をブール値にキャストし、関数にtrueまたはを返すように強制しますfalse。詳細については、こちらをご覧ください:stackoverflow.com/questions/4686583/…–
Rob Flaherty

2
これはOpera Mobile 10またはInternet Explorer Mobile 6(Windows Mobile 6.5)では機能しません。
doubleJ 2012年

17
in演算子はすでにブール値に評価されるため、二重のNOT(!!)は不必要です。
Steve

11
'onmsgesturechange'非タッチデバイス(PC)でもtrueを評価しています。 window.navigator.msMaxTouchPointsより正確なようです。 ここで見つけた
Steve

6
画面にタッチセンサーがない場合でも、Windows 8のIE10ではtrueと評価されます。古いラップトップをWindows 7からWindows 8にアップグレードしました
Pwner

120

ModernizrはWindows Phone 8 / WinRTでIE10を検出しないため、シンプルなクロスブラウザーソリューションは次のとおりです。

var supportsTouch = 'ontouchstart' in window || navigator.msMaxTouchPoints;

デバイスが突然タッチをサポートしたりサポートしなくなったりすることはないため、一度チェックするだけでよいので、変数に格納するだけで複数回効率的に使用できます。


3
ウィンドウの「onmsgesturechange」は、非タッチデバイス上の「デスクトップ」IE10も検出するため、これはタッチを判別する信頼できる方法ではありません。
Matt Stow、

6
この回答は、最もシンプルで最新のものであるため、受け入れられるべきでした。関数では、これはより一貫していると思います:(return !!('ontouchstart' in window) || !!('msmaxtouchpoints' in window.navigator);両方の答えを組み合わせるため)IE10でも正常に動作します!
イエティ

これは受け入れられる答えになるはずです。'onmsgesturechange' in windowタッチが可能な場合でもIE10デスクトップでtrueを返す
Sam Thornton

6
必要なもの:function isTouchDevice() { return 'ontouchstart' in window || !!(navigator.msMaxTouchPoints);}
GFoley83 2013

1
GFoleysでさえ、ウィンドウ内の「ontouchstart」の提案|| !!(navigator.msMaxTouchPoints); 2014
トムアンデルセン

37

上記のすべてのコメントを使用して、自分のニーズに合った次のコードを組み立てました。

var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0));

私はこれをiPad、Android(ブラウザとChrome)、Blackberry Playbook、iPhone 4s、Windows Phone 8、IE 10、IE 8、IE 10(タッチスクリーン付きWindows 8)、Opera、Chrome、Firefoxでテストしました。

現在、Windows Phone 7では失敗し、そのブラウザーの解決策をまだ見つけることができません。

誰かがこれが便利だと思うことを願っています。


使用できない理由はありますか:function is_touch_device(){return !!( 'ontouchstart' in window)|| !!(ナビゲーターの 'msmaxtouchpoints'); };
sidonaldson 2013

関数を使用しても機能しますが、通常は上記の変数メソッドを使用するのが好きなので、テストは1回だけで、後でコードで確認するときに高速になります。また、タッチスクリーンのないWindows 8のIE 10がmsMaxTouchPointsとして0を返したため、msMaxTouchPointsが0より大きいかどうかをテストする必要があることもわかりました。
デビッド

trueWindows 7上の私のFirefox 32で戻ります:(
vsync

私のシステムでは、Windows 8上のFirefox 33と33.1はどちらも正しくfalseを表示します。Firefoxを最新バージョンにアップグレードしても、trueが返されますか?マシンにデバイスがインストールされていて、Firefoxがマシンに接触していると誤って認識してしまう可能性がありますか?
David 14年

>>>ウィンドウの「ontouchstart」>>> ubuntuでの真のFF 51.0.1
Ravi Gadhia

25

インタラクションメディア機能の導入により、次のことが簡単に行えます。

if(window.matchMedia("(pointer: coarse)").matches) {
    // touchscreen
}

https://www.w3.org/TR/mediaqueries-4/#descdef-media-any-pointer

更新(コメントによる):上記の解決策は、「粗いポインター」(通常はタッチスクリーン)が主要な入力デバイスであるかどうかを検出することです。マウスなどのデバイスにタッチスクリーンがあるかどうかを判断したい場合は、any-pointer: coarse代わりに。

詳細については、こちらをご覧ください:ブラウザーにマウスがなく、タッチのみであることの検出


3
これは断然最良の解決策です、ありがとうございます!(pointer: coarse)ほとんどの場合、主要な入力のみを対象とするため、使用をお勧めします。サポートされていないブラウザはデスクトップのみであるため、本番環境で使用できます。css-tricksにこれに関する素晴らしい記事があります。
Fabian von Ellerts

2
これは、あらゆる状況で機能する、私がテストした唯一のソリューションです。ありがとう!
カイザーキウイ

20

私はこれが好きです:

function isTouchDevice(){
    return typeof window.ontouchstart !== 'undefined';
}

alert(isTouchDevice());

12
ブール値を返すために三項式を使用する必要はありません。式を使用してブール値を返します。function isTouchDevice(){ return (window.ontouchstart !== undefined); }
Tim Vermaelen 2013年

1
次のように使用することもできます。var isTouch = 'ontouchstart' in window;ただし、これは最新のChrome(v31)では機能せず、var isTouch = 'createTouch' in window.document;まだ機能しています。
Olivier、

2
以前に受け入れられた質問のコメントですでに述べたように。「Modernizrはタッチスクリーンをテストしません。ブラウザでのタッチイベントの存在をテストします。」あなたの関数は技術的にはisTouchDevice()ではなくhasTouchEvents()です
hexalys

touchstartIEがpointer代わりにイベントを使用するため、同様のメソッドテストでは、Surfaceがタッチデバイスとして認識されないことに注意してください。
CookieMonster 2014年

1
@Nisは正しかったかもしれませんが、Firefox 39では正しくfalseを返します。
Dan Dascalescu、2015

17

Modernizrを使用すると、非常に簡単に使用できますModernizr.touch先に述べたように。

ただし、Modernizr.touch安全のために、とユーザーエージェントのテストを組み合わせて使用​​することを好みます。

var deviceAgent = navigator.userAgent.toLowerCase();

var isTouchDevice = Modernizr.touch || 
(deviceAgent.match(/(iphone|ipod|ipad)/) ||
deviceAgent.match(/(android)/)  || 
deviceAgent.match(/(iemobile)/) || 
deviceAgent.match(/iphone/i) || 
deviceAgent.match(/ipad/i) || 
deviceAgent.match(/ipod/i) || 
deviceAgent.match(/blackberry/i) || 
deviceAgent.match(/bada/i));

if (isTouchDevice) {
        //Do something touchy
    } else {
        //Can't touch this
    }

Modernizrを使用しない場合は、Modernizr.touch上記の関数を次のように置き換えるだけです。('ontouchstart' in document.documentElement)

また、ユーザーエージェントをテストするiemobileと、検出されたMicrosoftモバイルデバイスの範囲がより広くなることに注意してくださいWindows Phone

このSOの質問も見てください


8
「何かに触れる」と「これに触れられない」のボーナスポイントがたくさん
リーサクソン

同じデバイスについて複数回チェックし、1つしか使用できない場合は複数のRegexeを実行しています。さらに、大文字と小文字を区別しない正規表現を行っていますが、文字列はすでに小文字になっています。
caesarsol 2016年

1
これで十分です:/(iphone|ipod|ipad|android|iemobile|blackberry|bada)/.test(window.navigator.userAgent.toLowerCase())
caesarsol

小文字にするか、一致の大文字と小文字を区別しない理由はありますか?「iOS」、「Android」、「IEMobile」はいつ他のケースを使用しますか?
Henrik N

14

私たちはmodernizrの実装を試しましたが、タッチイベントの検出は一貫していません(IE 10にはWindowsデスクトップでタッチイベントがあり、IE 11はタッチイベントを削除してポインターAPIを追加したため機能します)。

そのため、ユーザーの入力タイプがわからない限り、タッチサイトとして最適化することにしました。これは、他のどのソリューションよりも信頼性が高くなります。

私たちの調査によると、ほとんどのデスクトップユーザーはクリックする前に画面上でマウスを動かしているため、ユーザーが何かをクリックしたりホバーしたりする前にそれらを検出して動作を変更できます。

これは、コードを簡略化したバージョンです。

var isTouch = true;
window.addEventListener('mousemove', function mouseMoveDetector() {
    isTouch = false;
    window.removeEventListener('mousemove', mouseMoveDetector);
});

今日のコンピューターはタッチとマウスの両方を備えています...区別する必要があります。タッチ、マウス、またはその両方のいずれであるかを知ることは絶対に必要です。3つの異なる状態。
vsync 2014年

1
はい、あなたは正しいですが、これは非常に難しいです。最良の場合、アプリケーションは任意の入力コントローラーで使用するように設計されており、ユーザーがタッチスクリーン、マウス、キーボード、またはすべてを一緒に持っているかどうかは問題になりません。
Martin Lantzsch 2014年

1
ユーザーの行動は、ユーザーがどのようなデバイスを持っているかという実際の情報よりも価値があります。ユーザーがマウス、タッチスクリーン、キーボードを持っていることがわかったら、それでどうでしょうか。動作を処理します(マウスムーブ、タッチムーブ、キーダウンなど)。ユーザーは「実行時」に入力タイプを変更できます。これは、リロードなしで8〜5で使用される実際のアプリケーションを開発しているときに、非常に厄介な問題です。
Martin Lantzsch 2014年

2
+1実用的には、これが私にとって最良の答えです。たとえば、データグリッドがあります。これらのデータグリッドには、編集のためにタッチする「編集アイコン」、またはその他のオプションのコンテキストメニューが表示されます。マウスの動きが検出された場合は、アイコンを削除して(グリッド上のスペースを節約)、ユーザーはダブルクリックまたは右クリックできます。
プログラハンマー2015

3
タッチデバイスのクロムが
マウスムーブを

9

フィドル

私はこのようにそれを達成しました。

function isTouchDevice(){
    return true == ("ontouchstart" in window || window.DocumentTouch && document instanceof DocumentTouch);
}

if(isTouchDevice()===true) {
    alert('Touch Device'); //your logic for touch device
}
else {
    alert('Not a Touch Device'); //your logic for non touch device
}

はWindowsの表面タブレットを検出しません
Dan Beaulieu

@DanBeaulieuは、デバイスに特定していただけますか?私はWindowsフォンが正常に機能しているため、アプリケーションでQA:EDを使用しました。もう一度チェックして、回答を更新します。ご不便をおかけして申し訳ありません
アーミルシャーザド

何年かはわかりませんが、同僚に所属しているのはWindows Surface Proです。modernizrを追加した後、私たちはそれを動作させました。
Dan Beaulieu、2015年

これは、Windows 7マシンで非タッチを正しく報告し、タッチスクリーン付きのWindows 8ラップトップとAndroid 4.4 MotoX電話でタッチしました。
クレイニコルズ

私のMacのChrome(46)で誤検知を発生させる
Patrick Fabrizius 2015年

9

彼らがタッチスクリーンを持っているかどうかを確認するよりも良いことは、彼らがそれを使用しているかどうかを確認することです。さらに、より簡単に確認できます。

if (window.addEventListener) {
    var once = false;
    window.addEventListener('touchstart', function(){
        if (!once) {
            once = true;
            // Do what you need for touch-screens only
        }
    });
}

6

これはWindows Surfaceタブレットでもうまく機能します!!!

function detectTouchSupport {
msGesture = window.navigator && window.navigator.msPointerEnabled && window.MSGesture,
touchSupport = (( "ontouchstart" in window ) || msGesture || window.DocumentTouch &&     document instanceof DocumentTouch);
if(touchSupport) {
    $("html").addClass("ci_touch");
}
else {
    $("html").addClass("ci_no_touch");
}
}

4

上記のコードを使用してタッチかどうかを検出したので、私のfancybox iframeはタッチではなくデスクトップコンピューターに表示されました。Opera Mini for Android 4.0は、blmstrのコードを単独で使用した場合でも非タッチデバイスとして登録されていることに気付きました。(誰かが理由を知っていますか?)

私は結局使用しました:

<script>
$(document).ready(function() {
    var ua = navigator.userAgent;
    function is_touch_device() { 
        try {  
            document.createEvent("TouchEvent");  
            return true;  
        } catch (e) {  
            return false;  
        }  
    }

    if ((is_touch_device()) || ua.match(/(iPhone|iPod|iPad)/) 
    || ua.match(/BlackBerry/) || ua.match(/Android/)) {
        // Touch browser
    } else {
        // Lightbox code
    }
});
</script>

単一の正規表現で単一の一致呼び出しを使用しない理由を説明してください/iPhone|iPod|iPad|Android|BlackBerry/
user907860 14

Opera Miniはデバイス自体ではなく、Operaのサーバー上でレンダリングを実行するので、それはちょっと奇妙です。
bluesmoon 2015

4

タッチを検出しようとする際の最大の問題は、タッチとトラックパッド/マウスの両方をサポートするハイブリッドデバイスです。ユーザーのデバイスがタッチをサポートしているかどうかを正しく検出できたとしても、本当に必要なのは、ユーザーが現在使用している入力デバイスを検出することです。この課題の詳細な説明と可能な解決策がここにあります

基本的に、ユーザーが画面に触れただけなのか、それともマウス/トラックパッドを使用したのかを判断する方法は、ページにtouchstartmouseoverイベントの両方を登録することです。

document.addEventListener('touchstart', functionref, false) // on user tap, "touchstart" fires first
document.addEventListener('mouseover', functionref, false) // followed by mouse event, ie: "mouseover"

タッチアクションは、これらのイベントの両方をトリガーしますが、touchstartほとんどのデバイスでは前者()が常に最初になります。したがって、この予測可能な一連のイベントを頼りに、can-touchクラスをドキュメントルートに動的に追加または削除して、現時点でのユーザーの現在の入力タイプをドキュメントに反映するメカニズムを作成できます。

;(function(){
    var isTouch = false //var to indicate current input type (is touch versus no touch) 
    var isTouchTimer 
    var curRootClass = '' //var indicating current document root class ("can-touch" or "")
     
    function addtouchclass(e){
        clearTimeout(isTouchTimer)
        isTouch = true
        if (curRootClass != 'can-touch'){ //add "can-touch' class if it's not already present
            curRootClass = 'can-touch'
            document.documentElement.classList.add(curRootClass)
        }
        isTouchTimer = setTimeout(function(){isTouch = false}, 500) //maintain "istouch" state for 500ms so removetouchclass doesn't get fired immediately following a touch event
    }
     
    function removetouchclass(e){
        if (!isTouch && curRootClass == 'can-touch'){ //remove 'can-touch' class if not triggered by a touch event and class is present
            isTouch = false
            curRootClass = ''
            document.documentElement.classList.remove('can-touch')
        }
    }
     
    document.addEventListener('touchstart', addtouchclass, false) //this event only gets called when input type is touch
    document.addEventListener('mouseover', removetouchclass, false) //this event gets called when input type is everything from touch to mouse/ trackpad
})();

詳細はこちら


3

この投稿を確認してください。タッチデバイスが検出された場合の処理​​、またはtouchstartイベントが呼び出された場合の処理​​について、非常に優れたコードスニペットが提供されています。

$(function(){
  if(window.Touch) {
    touch_detect.auto_detected();
  } else {
    document.ontouchstart = touch_detect.surface;
  }
}); // End loaded jQuery
var touch_detect = {
  auto_detected: function(event){
    /* add everything you want to do onLoad here (eg. activating hover controls) */
    alert('this was auto detected');
    activateTouchArea();
  },
  surface: function(event){
    /* add everything you want to do ontouchstart here (eg. drag & drop) - you can fire this in both places */
    alert('this was detected by touching');
    activateTouchArea();
  }
}; // touch_detect
function activateTouchArea(){
  /* make sure our screen doesn't scroll when we move the "touchable area" */
  var element = document.getElementById('element_id');
  element.addEventListener("touchstart", touchStart, false);
}
function touchStart(event) {
  /* modularize preventing the default behavior so we can use it again */
  event.preventDefault();
}

3

デバイスがタッチデバイスかどうかを判断するために画面幅を使用することは避けます。タッチスクリーンは699pxよりはるかに大きいので、Windows 8について考えてみてください。Navigatior.userAgentは、誤った予測を上書きするのに適しています。

この問題をチェックすることをお勧めしますModernizrでをます。

デバイスがタッチイベントをサポートしているか、タッチデバイスであるかをテストしますか?残念ながら、それは同じことではありません。


3

いいえ、それは不可能です。与えられた優れた答えは部分的なものに過ぎません。なぜなら、与えられた方法はすべて、偽陽性と偽陰性を生み出すからです。OS APIのため、ブラウザーでさえタッチスクリーンが存在するかどうかを常に認識しているわけではなく、特にKVMタイプの配置では、ブラウザーセッション中に事実が変わる可能性があります。

この優れた記事で詳細をご覧ください。

http://www.stucox.com/blog/you-cant-detect-a-touchscreen/

この記事では、タッチスクリーンを検出するための仮定を再考することをお勧めしていますが、それらはおそらく間違っています。(私は自分のアプリを自分で確認しましたが、私の仮定は確かに間違っていました!)

記事の結論は次のとおりです。

レイアウトについては、全員がタッチスクリーンを持っていると仮定します。マウスユーザーは、タッチユーザーが小さなUIコントロールを使用するよりもはるかに簡単に、大きなUIコントロールを使用できます。ホバー状態についても同様です。

イベントやインタラクションについては、誰もがタッチスクリーンを持っていると想定してください。キーボード、マウス、タッチ操作を並べて実装し、お互いを妨げないようにします。


3

これらの多くは機能しますが、jQueryを必要とするか、JavaScriptリンターが構文について文句を言います。あなたの最初の質問がこれを解決する「JavaScript」(jQueryではなく、Modernizrではない)方法を要求することを考えると、毎回機能する単純な関数は次のとおりです。それはまた、あなたが得ることができるのと同じくらい最小です。

function isTouchDevice() {
    return !!window.ontouchstart;
}

console.log(isTouchDevice());

私が言及する最後の利点の1つは、このコードがフレームワークとデバイスに依存しないことです。楽しい!


function isTouchScreen() { return window.matchMedia('(hover: none)').matches;}これは私のために働いたので、Googleが私をここに連れてきたときにバニラJSスレッドも期待していたので、私はここでこの答えに貢献を追加しています。
Daniel Lavedonio de Lima

2

Chrome 24はおそらくWindows 8向けのタッチイベントをサポートするようです。そのため、ここに投稿されたコードは機能しなくなりました。ブラウザでタッチがサポートされているかどうかを検出する代わりに、タッチイベントとクリックイベントの両方をバインドし、1つだけが呼び出されるようにします。

myCustomBind = function(controlName, callback) {

  $(controlName).bind('touchend click', function(e) {
    e.stopPropagation();
    e.preventDefault();

    callback.call();
  });
};

そしてそれを呼び出す:

myCustomBind('#mnuRealtime', function () { ... });

お役に立てれば !



2

デスクトップ用Firefoxを除くすべてのブラウザーが常にTRUEに対応 Firefoxは、タッチボタンをクリックしてもしなくても、開発者向けのレスポンシブデザインをサポートしているため、です。

Mozillaが次のバージョンでこれを修正することを願っています。

Firefox 28デスクトップを使用しています。

function isTouch()
{
    return !!("ontouchstart" in window) || !!(navigator.msMaxTouchPoints);
}

それはまだバージョン32.0であり、まだ修正されていません!狂気。なぜこれはトグルできないのですか?これは常にtrue:(
vsync

2

jQuery v1.11.3

提供された回答には多くの良い情報があります。しかし、最近、私は多くの時間を費やして、実際にすべてを1つにまとめて2つのことを達成するための実用的なソリューションにした。

  1. 使用しているデバイスがタッチスクリーンタイプのデバイスであることを検出します。
  2. デバイスがタップされたことを検出します。

この投稿とDetecting touch screen devices with Javascriptに加えて、Patrick Laukeによるこの投稿は非常に役に立ちました:https ://hacks.mozilla.org/2013/04/detecting-touch-its-the-why-not-the-how /

ここにコードがあります...

$(document).ready(function() {
//The page is "ready" and the document can be manipulated.

    if (('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0))
    {
      //If the device is a touch capable device, then...
      $(document).on("touchstart", "a", function() {

        //Do something on tap.

      });
    }
    else
    {
      null;
    }
});

重要!*.on( events [, selector ] [, data ], handler )メソッドには、「touchstart」イベント、またはタッチに関連するその他のイベントを処理できるセレクター(通常は要素)が必要です。この場合、ハイパーリンク要素「a」です。

JavaScriptで通常のマウスクリックを処理する必要はありません。CSSを使用して、次のようにハイパーリンク「a」要素のセレクターを使用してこれらのイベントを処理できるためです。

/* unvisited link */
a:link 
{

}

/* visited link */
a:visited 
{

}

/* mouse over link */
a:hover 
{

}

/* selected link */
a:active 
{

}

注:他のセレクターもあります...


1
var isTouchScreen = 'createTouch' in document;

または

var isTouchScreen = 'createTouch' in document || screen.width <= 699 || 
    ua.match(/(iPhone|iPod|iPad)/) || ua.match(/BlackBerry/) || 
    ua.match(/Android/);

私が思うより徹底的なチェックになるでしょう。


3
ua参照することに注意してくださいnavigator.userAgent。また、誰かがフルスクリーンモードではないブラウザを開いた場合、画面幅による検出は誤った結果をもたらす可能性があります。
HoLyVieR

1

私が使う:

if(jQuery.support.touch){
    alert('Touch enabled');
}

jQuery mobile 1.0.1


1

また、ページがタッチスクリーンデバイスに表示されているかどうかをJavascriptで検出する方法について、さまざまなオプションについても多く苦労しました。IMOには、現在のところ、オプションを適切に検出するための実際のオプションはありません。ブラウザは、デスクトップマシン上のタッチイベントを報告する(OSがタッチ対応の可能性があるため)か、一部のソリューションがすべてのモバイルデバイスで機能しない場合があります。

結局、最初から間違ったアプローチをとっていることに気づきました。タッチデバイスと非タッチデバイスでページの外観が似ている場合、プロパティの検出についてまったく心配する必要はないでしょう。私のシナリオはタッチデバイスのボタンをダブルタップするとボタンが1回タップされてボタンがアクティブになるので、ツールチップのボタンのツールチップを無効にします。

私の解決策は、ボタンの上にツールチップが必要ないようにビューをリファクタリングすることでした、そして結局すべてに欠点があるメソッドを使ってJavaScriptからタッチデバイスを検出する必要がありませんでした。


1

あなたはmodernizerをインストールして、シンプルなタッチイベントを使うことができます。これは非常に効果的で、Windowsの表面を含め、テストしたすべてのデバイスで機能します。

私はjsFiddleを作成しました

function isTouchDevice(){
    if(Modernizr.hasEvent('touchstart') || navigator.userAgent.search(/Touch/i) != -1){
         alert("is touch");
            return true;
         }else{
            alert("is not touch");
            return false;
    }
}

3
SOへようこそ!コード自体(コメント化されていないコードと同様)は、ほとんど答えを構成しません。スニペットの説明を追加すると、この回答を改善できます。
ebarr 2014年

1

実用的な答えは、コンテキストを考慮したもののようです。

1)パブリックサイト(ログインなし)
両方のオプションを一緒に使用するようにUIをコーディングします。

2)ログインサイト
ログインフォームでマウス移動が発生したかどうかをキャプチャし、これを非表示の入力に保存します。値はログイン認証情報とともに渡され、ユーザーのセッションに追加されますされるため、セッションの期間中使用できます。

ログインページにのみ追加するjquery:

$('#istouch').val(1); // <-- value will be submitted with login form

if (window.addEventListener) {
    window.addEventListener('mousemove', function mouseMoveListener(){
        // Update hidden input value to false, and stop listening
        $('#istouch').val(0); 
        window.removeEventListener('mousemove', mouseMoveListener);
    });
} 

(回答については、@ Dave Burtに+ 1、@ Martin Lantzschに+1)


1

問題

タッチとマウス入力の組み合わせを使用するハイブリッドデバイスのため、動的に実行できる必要があります、ユーザーがタッチユーザーである場合にコードの一部を実行するかどうかを制御する状態/変数を変更。

タッチデバイスも発射します mousemoveタップでします。

解決

  1. ロード時にタッチがfalseであると想定します。
  2. touchstartイベントが発生するまで待ち、それをtrueに設定します。
  3. touchstartが発生した場合は、mousemoveハンドラーを追加します。
  4. 2つのマウスムーブイベントの発生間隔が20ミリ秒未満の場合は、マウスを入力として使用していると想定します。イベントは不要になり、mousemoveはマウスデバイスにとって高価なイベントであるため、削除してください。
  5. touchstartが再び発生すると(ユーザーがtouchを使用するように戻った)、変数はtrueに戻ります。そして、動的な方法で決定されるようにプロセスを繰り返します。奇跡的にmousemoveがタッチ時に2度とんでもない速さで起動された場合(私のテストでは、20ミリ秒以内に実行することは事実上不可能です)、次のタッチスタートでtrueに戻ります。

Safari iOSとChrome for Androidでテストされています。

注:MS Surfaceなどのポインターイベントは100%確実ではありません。

Codepenデモ


const supportsTouch = 'ontouchstart' in window;
let isUsingTouch = false;

// `touchstart`, `pointerdown`
const touchHandler = () => {
  isUsingTouch = true;
  document.addEventListener('mousemove', mousemoveHandler);
};

// use a simple closure to store previous time as internal state
const mousemoveHandler = (() => {
  let time;

  return () => {
    const now = performance.now();

    if (now - time < 20) {
      isUsingTouch = false;
      document.removeEventListener('mousemove', mousemoveHandler);
    }

    time = now;
  }
})();

// add listeners
if (supportsTouch) {
  document.addEventListener('touchstart', touchHandler);
} else if (navigator.maxTouchPoints || navigator.msMaxTouchPoints) {
  document.addEventListener('pointerdown', touchHandler);
}

1

実際、私はこの質問を調査し、すべての状況を検討しました。私のプロジェクトでも大きな問題です。だから私は以下の機能に到達します、それはすべてのデバイスのすべてのブラウザのすべてのバージョンで動作します:

const isTouchDevice = () => {
  const prefixes = ['', '-webkit-', '-moz-', '-o-', '-ms-', ''];
  const mq = query => window.matchMedia(query).matches;

  if (
    'ontouchstart' in window ||
    (window.DocumentTouch && document instanceof DocumentTouch)
  ) {
    return true;
  }
  return mq(['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join(''));
};

ヒント:間違いなく、isTouchDeviceboolean値を返すだけです。


0

エクステントjQuery supportオブジェクト:

jQuery.support.touch = 'ontouchend' in document;

これで、次のようにどこでも確認できます。

if( jQuery.support.touch )
   // do touch stuff

0

これは今のところ私にとってはうまく機能しているようです:

//Checks if a touch screen
is_touch_screen = 'ontouchstart' in document.documentElement;

if (is_touch_screen) {
  // Do something if a touch screen
}
else {
  // Not a touch screen (i.e. desktop)
}

0

マウスが接続されている場合、ヒット率がかなり高い(実際には100%と言います)と、ページの準備ができた後、ユーザーがマウスを少なくともわずかな距離だけ移動したと想定できます。以下のメカニズムがこれを検出します。検出された場合、私はこれをタッチサポートの欠如の兆候と見なします。サポートされている場合は、マウスの使用中にそれほど重要ではないものと見なします。検出されない場合、タッチデバイスが想定されます。

編集このアプローチは、すべての目的に適合するとは限りません。これは、ロードされたページ、たとえば画像ビューアーでのユーザー操作に基づいてアクティブ化される機能を制御するために使用できます。以下のコードは、現在目立っているように、mousemoveイベントをマウスなしのデバイスにバインドしたままにします。他のアプローチの方が良いかもしれません。

おおよそ、次のようになります(jQueryでは申し訳ありませんが、純粋なJavascriptでも同様です)。

var mousedown, first, second = false;
var ticks = 10;
$(document).on('mousemove', (function(e) {
    if(UI.mousechecked) return;
    if(!first) {
        first = e.pageX;
        return;
        }
    if(!second && ticks-- === 0) {
        second = e.pageX;
        $(document).off('mousemove'); // or bind it to somewhat else
        }
    if(first  && second  && first !== second && !mousedown){
        // set whatever flags you want
        UI.hasmouse = true;
        UI.touch = false;
        UI.mousechecked = true;
    }

    return;
}));
$(document).one('mousedown', (function(e) {
    mousedown = true;
    return;
}));
$(document).one('mouseup', (function(e) {
    mousedown = false;
    return;
}));
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.