Phát hiện các thiết bị màn hình cảm ứng bằng Javascript


129

Trong Javascript / jQuery, làm cách nào tôi có thể phát hiện nếu thiết bị khách có chuột?

Tôi đã có một trang web trượt lên một bảng thông tin nhỏ khi người dùng di chuột qua một mục. Tôi đang sử dụng jQuery.hoverIntent để phát hiện di chuột, nhưng điều này rõ ràng không hoạt động trên các thiết bị màn hình cảm ứng như iPhone / iPad / Android. Vì vậy, trên các thiết bị đó tôi muốn hoàn nguyên để nhấn để hiển thị bảng thông tin.


6
Tại sao bạn không thể làm cả hai? Là chức năng nhấn không mong muốn trong các thiết bị không có màn hình cảm ứng?
EMPraptor

1
Vì một số thiết bị mới hơn không hỗ trợ :hover, có lẽ tốt hơn (khi mã hóa một biểu định kiểu cho nhiều thiết bị) để sử dụng :hovercho mục đích hoàn toàn là mỹ phẩm.
vét vào

@empraptor: điểm tốt - vâng tôi có thể làm điều đó. Tuy nhiên ... chúng tôi cũng đã nghĩ đến việc luôn hiển thị bảng điều khiển trên các thiết bị màn hình cảm ứng - trong trường hợp đó tôi sẽ cần có khả năng phát hiện hỗ trợ.
Brad Robinson

Nếu bạn luôn có thể hiển thị bảng điều khiển trên các thiết bị màn hình cảm ứng, bạn cũng không thể hiển thị bảng đó trên các thiết bị khác? Bảng điều khiển lớn như thế nào và tại sao nó chỉ mong muốn hiển thị trên bảng di chuột / tap?
EMPraptor

Câu trả lời:


12

+1 để làm hoverclickcả hai. Một cách khác có thể là sử dụng truy vấn phương tiện CSS và chỉ sử dụng một số kiểu cho màn hình / thiết bị di động nhỏ hơn, đây là những kiểu có nhiều khả năng có chức năng chạm / chạm. Vì vậy, nếu bạn có một số kiểu cụ thể thông qua CSS và từ jQuery, bạn kiểm tra các yếu tố đó cho các thuộc tính kiểu thiết bị di động mà bạn có thể nối vào chúng để viết mã cụ thể cho thiết bị di động.

Xem tại đây: http://www.forabeautitableweb.com/blog/about/hardboiled_css3_media_queries/


1
Giải pháp tốt, có lẽ bạn có thể làm một cái gì đó như kiểm tra di chuột với liên kết một () để nó chỉ kích hoạt lần đầu tiên.
Timothy Perez

Vấn đề là nếu bạn nhắm mục tiêu theo chiều rộng màn hình thì khi bạn xoay thiết bị của mình (hãy lấy iphone 6+ 736x414) nó sẽ không có cùng kiểu dáng. Vì vậy, không phải là giải pháp tốt nhất: /
antoni

266
var isTouchDevice = 'ontouchstart' in document.documentElement;

Lưu ý : Chỉ vì một thiết bị hỗ trợ các sự kiện cảm ứng không nhất thiết có nghĩa là nó chỉ là một thiết bị màn hình cảm ứng. Nhiều thiết bị (như Asus Zenbook của tôi) hỗ trợ cả các sự kiện nhấp và chạm, ngay cả khi chúng không có bất kỳ cơ chế nhập liệu cảm ứng thực tế nào. Khi thiết kế để hỗ trợ cảm ứng, luôn luôn bao gồm hỗ trợ sự kiện nhấp và không bao giờ cho rằng bất kỳ thiết bị nào là độc quyền của một hoặc khác.


33
Như được mô tả trong các tài liệu Modernizr, điều này chỉ phát hiện khả năng của trình duyệt , không phải khả năng của thiết bị ... bạn sẽ nhận được kết quả dương tính giả trên các thiết bị không có đầu vào cảm ứng chạy trình duyệt có khả năng cảm ứng. Tôi không biết cách nào để phát hiện khả năng cảm ứng của thiết bị , mà không cần chờ sự kiện chạm xảy ra.
Stu Cox

12
Để phát hiện IE 10 touch tôi đang sử dụng: (window.navigator.msMaxTouchPoints || ('ontouchstart' trong document.documentEuity));
Alexander Kellett

2
'ontouchstart' in document.documentElement trả về không đúng sự thật trên BlackBerry 9300
Đơn giản hơn

10
@typhon nếu phần mềm (Win 8, trình duyệt hiện đại) hỗ trợ cảm ứng, điều này sẽ luôn đúng - ngay cả khi bạn đang sử dụng phần cứng (máy tính để bàn, màn hình chuẩn, chuột và bàn phím) không hỗ trợ cảm ứng. Do đó giải pháp này đã hết hạn.
Barney

1
funnyItsNotCamelCaseAsJsIsThông qua. Ý tôi là mọi người bây giờ sẽ cần sao chép, dán VÀ chỉnh sửa mã ... :)
Ross

20

Đã tìm thấy thử nghiệm cho window.Touch không hoạt động trên Android nhưng điều này không:

function is_touch_device() {
  return !!('ontouchstart' in window);
}

Xem bài viết: Cách tốt nhất để phát hiện thiết bị 'màn hình cảm ứng' bằng JavaScript là gì?


Điều này không phát hiện màn hình cảm ứng nhưng hãy cẩn thận vì nó cũng trả về TRUE cho máy tính xách tay có màn hình cảm ứng. Đây có thể là một vấn đề nếu bạn đang cố gắng phân biệt nếu người dùng đến từ điện thoại / máy tính bảng HOẶC máy tính / máy tính xách tay vì đối với máy tính xách tay có màn hình cảm ứng, nó sẽ trả về ĐÚNG.
Kết hợp

8
return (('ontouchstart' in window)
      || (navigator.maxTouchPoints > 0)
      || (navigator.msMaxTouchPoints > 0));

Lý do sử dụng maxTouchPoints cùng với msMaxTouchPoints:

Microsoft đã tuyên bố rằng bắt đầu với Internet Explorer 11, phiên bản tiền tố của nhà cung cấp Microsoft (msMaxTouchPoints) có thể bị xóa và khuyên bạn nên sử dụng maxTouchPoints.

Nguồn: http://ctrlq.org/code/19616-detect-touch-screen-javascript


điều này đã hoạt động và làm việc trong các công cụ phát triển google chrome mô phỏng thiết bị cảm ơn bạn
Behnam Mohammadi

7
if ("ontouchstart" in window || navigator.msMaxTouchPoints) {
    isTouch = true;
} else {
    isTouch = false;
}

Hoạt động mọi lúc mọi nơi !!


Và điều đó có liên quan gì đến một con chuột? (câu hỏi thực tế)
hexalys

Nó sẽ đơn giản hơn để làmisTouch = "ontouchstart" in window || navigator.msMaxTouchPoints;
Andrew


4

Google Chrome dường như trả lại dương tính giả trên cái này:

var isTouch = 'ontouchstart' in document.documentElement;

Tôi cho rằng nó có liên quan đến khả năng "mô phỏng các sự kiện chạm" (F12 -> cài đặt ở góc dưới bên phải -> tab "ghi đè" -> hộp kiểm cuối cùng). Tôi biết nó bị tắt theo mặc định nhưng đó là những gì tôi kết nối thay đổi kết quả với (phương thức "trong" được sử dụng để hoạt động trong Chrome). Tuy nhiên, điều này dường như đang hoạt động, theo như tôi đã thử nghiệm:

var isTouch = !!("undefined" != typeof document.documentElement.ontouchstart);

Tất cả các trình duyệt tôi đã chạy mã trên nhà nước typeof là "đối tượng" nhưng tôi cảm thấy chắc chắn hơn khi biết rằng đó là bất cứ điều gì nhưng không xác định :-)

Đã thử nghiệm trên IE7, IE8, IE9, IE10, Chrome 23.0.1271.64, Chrome cho iPad 21.0.1180.80 và iPad Safari. Sẽ thật tuyệt nếu ai đó thực hiện thêm một số thử nghiệm và chia sẻ kết quả.


Cả hai phương pháp đều trả về kết quả dương tính giả trên PC Win 8 với FF 23 và Chrome 28. Đây có phải luôn luôn như vậy hay là do tôi đã từng có một màn hình cảm ứng được gắn vào máy tính này - có lẽ trước khi cài đặt FF và Chrome - nhưng không còn nữa? Tôi không có tùy chọn "mô phỏng sự kiện chạm".
cơn bão

Uh, nó luôn luôn là một cuộc đấu tranh với phần cứng mới. Các trình duyệt phải làm việc với các lớp trừu tượng của hệ điều hành ... không phải lúc nào cũng thực hiện mọi thứ ... tóm lại, với JS, bạn phải dựa vào trình duyệt :) Không bao giờ có một cách phổ quát.
Tro

Cả hai đều trả về true trên Ubuntu Firefox trên máy tính xách tay không cảm ứng.
NoBugs

4

Đã viết điều này cho một trong những trang web của tôi và có lẽ là giải pháp hoàn hảo nhất. Đặc biệt là ngay cả Modernizr có thể nhận được dương tính giả khi phát hiện cảm ứng.

Nếu bạn đang sử dụng jQuery

$(window).one({
  mouseover : function(){
    Modernizr.touch = false; // Add this line if you have Modernizr
    $('html').removeClass('touch').addClass('mouse');
  } 
});

hoặc chỉ là JS thuần túy ...

window.onmouseover = function(){ 
    window.onmouseover = null;
    document.getElementsByTagName("html")[0].className += " mouse";
}

4
Mặc dù vậy, hãy cẩn thận: ít nhất iPad cũng ném onmouseovers
Joril

14
Apple chết tiệt!
Timothy Perez

Và những người sử dụng IE trên máy tính bảng Windows có thể muốn sử dụng cả cảm ứng và chuột.
Sabazzz

Bài đăng này được thực hiện trước khi Windows Tablet ra đời.
Timothy Perez

@ s427 - Tìm kiếm IE ... chỉ cần kiểm tra IE8. Tôi không nghĩ có bất kỳ thiết bị di động nào có <= IE8.
Timothy Perez

4

Đối với bài đăng / nhận xét đầu tiên của tôi: Tất cả chúng ta đều biết rằng 'touchstart' được kích hoạt trước khi nhấp. Chúng tôi cũng biết rằng khi người dùng mở trang của bạn, họ sẽ: 1) di chuyển chuột 2) nhấp 3) chạm vào màn hình (để cuộn hoặc ... :))

Hãy thử một cái gì đó:

// -> Bắt đầu: jQuery

var hasTouchCapabilities = 'ontouchstart' in window && (navigator.maxTouchPoints || navigator.msMaxTouchPoints);
var isTouchDevice = hasTouchCapabilities ? 'maybe':'nope';

//attach a once called event handler to window

$(window).one('touchstart mousemove click',function(e){

    if ( isTouchDevice === 'maybe' && e.type === 'touchstart' )
        isTouchDevice = 'yes';
});

// <- Kết thúc: jQuery

Chúc một ngày tốt lành!


3

Tôi đã thử nghiệm mã sau đây được đề cập ở trên trong cuộc thảo luận

 function is_touch_device() {
    return !!('ontouchstart' in window);
 }

hoạt động trên Android Mozilla, chrome, Opera, trình duyệt mặc định android và safari trên iphone ... tất cả đều tích cực ...

có vẻ vững chắc đối với tôi :)


Siêu đơn giản và hoạt động tốt cho tôi. Đã thử nghiệm trên Android (Galaxy Note cũ) và với trình giả lập (Chrome) và trên iPad.
Ralf

Trả lại kết quả dương tính giả cho tôi trên Chrome.
James


2

Điều này làm việc cho tôi:

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

1
bạn đã thử nghiệm bao nhiêu nền tảng, hệ điều hành, hệ điều hành?
BerggreenDK

1
FF, Chrome, Safari trên Android và iOS (iPad)
Turtletrail

1
Đủ đẹp Tôi vừa thử nghiệm trên máy tính để bàn và nhận được rất nhiều "không xác định", điều này làm cho cấu trúc IF hơi bị hack. Nếu bạn điều chỉnh giá trị trả về của mình chỉ một chút, như thế này: return true == ("ontouchstart" trong cửa sổ | | window.DocumentTouch && document instanceof DocumentTouch); Sau đó, bạn có đúng hoặc sai :-)
BerggreenDK

2
Trong Chrome, "ontouchstart" trong cửa sổ là đúng trên PC của tôi mà không có màn hình cảm ứng, vì vậy điều này không hoạt động. Như đã nhận xét trước đó, điều này kiểm tra nếu trình duyệt có khả năng cảm ứng. Ngoài ra, true == không làm gì cả và nên bỏ qua.
rakensi

1
Khi tôi thử điều này trong Chrome với trình giả lập tích hợp, nó sẽ phát hiện cảm ứng khi được bật trong trình giả lập và sẽ không phát hiện cảm ứng khi tắt. Vì vậy, làm việc tốt cho tôi. Nhưng: Tôi sử dụng phiên bản ngắn của Prasad (bên dưới) không sử dụng | | trong mã của Turtletrail. Và: Tôi không quan tâm nếu nó hoạt động cho 100% thiết bị. 99% sẽ làm cho tôi.
Ralf

1

Nếu bạn sử dụng Modernizr , nó rất dễ sử dụng Modernizr.touchnhư đã đề cập trước đó.

Tuy nhiên, tôi thích sử dụng kết hợp Modernizr.touchthử nghiệm tác nhân người dùng và để an toàn.

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
    }

Nếu bạn không sử dụng Modernizr, bạn chỉ cần thay thế Modernizr.touchchức năng trên bằng('ontouchstart' in document.documentElement)

Cũng lưu ý rằng việc kiểm tra tác nhân người dùng iemobilesẽ cung cấp cho bạn phạm vi rộng hơn các thiết bị di động Microsoft được phát hiện hơn Windows Phone.

Cũng xem câu hỏi SO này


2
Có phải cùng một câu trả lời cho 4 câu hỏi bây giờ ... và đây không phải là một giải pháp cho câu hỏi mà anh ta đang hỏi.
jycr753

1
Tôi tin rằng nó trả lời câu hỏi ở đây
Peter-Pan

Đây không phải là câu trả lời nhưng đó là một gợi ý tôi nghĩ cho ai muốn phát hiện xem thiết bị có thể chạm vào trước khi người dùng chạm vào nó hay không
Shahadat Hossain Khan

1

Trong jQuery Mobile, bạn chỉ cần làm:

$.support.touch

Không biết tại sao điều này lại không có giấy tờ .. nhưng nó là an toàn chéo (2 phiên bản mới nhất của trình duyệt hiện tại).


0

Như đã đề cập, một thiết bị có thể hỗ trợ cả đầu vào chuột và cảm ứng. Rất thường xuyên, câu hỏi không phải là "những gì được hỗ trợ" mà là "những gì hiện đang được sử dụng".

Trong trường hợp này, bạn chỉ cần đăng ký các sự kiện chuột (bao gồm cả trình nghe di chuột) và các sự kiện chạm như nhau.

element.addEventListener('touchstart',onTouchStartCallback,false);

element.addEventListener('onmousedown',onMouseDownCallback,false);

...

JavaScript sẽ tự động gọi người nghe chính xác dựa trên đầu vào của người dùng. Vì vậy, trong trường hợp có sự kiện chạm, onTouchStartCallbacksẽ được kích hoạt, mô phỏng mã di chuột của bạn.

Lưu ý rằng một cú chạm có thể kích hoạt cả hai loại người nghe, chạm và chuột. Tuy nhiên, trình nghe cảm ứng đi trước và có thể ngăn người nghe chuột tiếp theo bắn bằng cách gọi event.preventDefault().

function onTouchStartCallback(ev) {
    // Call preventDefault() to prevent any further handling
    ev.preventDefault();
    your code...
}

Đọc thêm ở đây .


-3

Để phát triển iPad tôi đang sử dụng:

  if (window.Touch)
  {
    alert("touchy touchy");
  }
  else
  {
    alert("no touchy touchy");
  }

Sau đó, tôi có thể liên kết có chọn lọc với các sự kiện dựa trên cảm ứng (ví dụ: ontouchstart) hoặc các sự kiện dựa trên chuột (ví dụ: onmousedown). Tôi chưa thử nghiệm trên Android.


1
Điều này không hoạt động với Opera Mobile 10 hoặc Internet Explorer Mobile 6 (Windows Mobile 6.5).
doubleJ

4
crossbrowser xấu / hệ điều hành chéo / tư vấn đa nền tảng.
BerggreenDK
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.