การตรวจจับอุปกรณ์หน้าจอสัมผัสด้วย Javascript


129

ใน Javascript / jQuery ฉันจะตรวจสอบได้อย่างไรว่าอุปกรณ์ไคลเอนต์มีเมาส์?

ฉันมีไซต์ที่เลื่อนแผงข้อมูลเล็ก ๆ น้อย ๆ เมื่อผู้ใช้วางเมาส์เหนือรายการ ฉันใช้ jQuery.hoverIntent เพื่อตรวจจับโฮเวอร์ แต่เห็นได้ชัดว่าสิ่งนี้ใช้ไม่ได้กับอุปกรณ์หน้าจอสัมผัสเช่น iPhone / iPad / Android ในอุปกรณ์เหล่านั้นฉันต้องการเปลี่ยนกลับเพื่อแตะเพื่อแสดงแผงข้อมูล


6
ทำไมทำทั้งสองอย่างไม่ได้ ฟังก์ชันการแตะไม่เป็นที่ต้องการในอุปกรณ์ที่ไม่ใช่หน้าจอสัมผัสหรือไม่?
EMPraptor

1
เนื่องจากอุปกรณ์รุ่นใหม่บางรุ่นไม่รองรับ:hoverจึงน่าจะดีกว่า (เมื่อเขียนโค้ดสไตล์ชีตเดียวสำหรับอุปกรณ์หลายเครื่อง) เพื่อใช้:hoverเพื่อการเครื่องสำอางอย่างแท้จริง
ดูหมิ่น

@empraptor: จุดดี - ใช่ฉันทำได้ อย่างไรก็ตาม ... เรายังคิดที่จะแสดงแผงควบคุมบนอุปกรณ์หน้าจอสัมผัสอยู่เสมอซึ่งในกรณีนี้ฉันจะต้องสามารถตรวจจับการสนับสนุนได้
Brad Robinson

หากคุณสามารถแสดงแผงบนอุปกรณ์หน้าจอสัมผัสได้ตลอดเวลาคุณจะแสดงบนอุปกรณ์อื่นด้วยไม่ได้หรือ แผงควบคุมมีขนาดใหญ่เพียงใดและเหตุใดจึงควรแสดงเฉพาะเมื่อวางเมาส์ / แตะเท่านั้น
EMPraptor

คำตอบ:


12

+1 สำหรับการทำhoverและclickทั้งสองอย่าง อีกวิธีหนึ่งอาจใช้การสืบค้นสื่อ CSS และใช้สไตล์บางอย่างสำหรับหน้าจอขนาดเล็ก / อุปกรณ์มือถือเท่านั้นซึ่งเป็นลักษณะที่มีแนวโน้มที่จะมีฟังก์ชันการสัมผัส / แตะมากที่สุด ดังนั้นหากคุณมีสไตล์เฉพาะบางอย่างผ่าน CSS และจาก jQuery คุณตรวจสอบองค์ประกอบเหล่านั้นเพื่อหาคุณสมบัติสไตล์อุปกรณ์มือถือคุณสามารถเชื่อมต่อกับพวกเขาเพื่อเขียนโค้ดเฉพาะมือถือให้คุณได้

ดูที่นี่: http://www.forabeautifulweb.com/blog/about/hardboiled_css3_media_queries/


1
วิธีแก้ปัญหาที่ดีคุณอาจทำบางอย่างเช่นการตรวจสอบการวางเมาส์บนการผูก () เพื่อให้มันเริ่มทำงานในครั้งแรกเท่านั้น
Timothy Perez

ปัญหาคือถ้าคุณกำหนดเป้าหมายตามความกว้างของหน้าจอเมื่อคุณหมุนอุปกรณ์ของคุณ (ลองใช้ iphone 6+ 736x414) มันจะไม่มีรูปแบบเดียวกัน ดังนั้นไม่ใช่ทางออกที่ดีที่สุด: /
antoni

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

หมายเหตุ : เพียงเพราะอุปกรณ์รองรับเหตุการณ์การสัมผัสไม่จำเป็นต้องหมายความว่าเป็นอุปกรณ์หน้าจอสัมผัสเท่านั้น อุปกรณ์จำนวนมาก (เช่น Asus Zenbook ของฉัน) รองรับทั้งเหตุการณ์การคลิกและการสัมผัสแม้ว่าจะไม่มีกลไกการป้อนข้อมูลแบบสัมผัสที่แท้จริงก็ตาม เมื่อออกแบบเพื่อรองรับการสัมผัสให้รวมการสนับสนุนเหตุการณ์การคลิกไว้เสมอและอย่าถือว่าอุปกรณ์ใด ๆ เป็นเพียงอุปกรณ์เดียว


33
ตามที่อธิบายไว้ในเอกสาร Modernizr สิ่งนี้จะตรวจจับความสามารถของเบราว์เซอร์เท่านั้นไม่ใช่ความสามารถของอุปกรณ์ ... คุณจะได้รับผลบวกที่ผิดพลาดบนอุปกรณ์ที่ไม่มีอินพุตแบบสัมผัสที่ใช้เบราว์เซอร์ที่สามารถสัมผัสได้ ฉันไม่รู้วิธีตรวจจับความสามารถในการสัมผัสของอุปกรณ์โดยกำเนิดโดยไม่ต้องรอให้เหตุการณ์สัมผัสเกิดขึ้น
Stu Cox

12
เพื่อตรวจจับ IE 10 touch ที่ฉันใช้: (window.navigator.msMaxTouchPoints || ('ontouchstart' ใน document.documentElement));
Alexander Kellett

2
'ontouchstart' in document.documentElement ส่งคืนจริงอย่างไม่ถูกต้องบน BlackBerry 9300
Simpler

10
@typhon หากซอฟต์แวร์ (Win 8 เบราว์เซอร์สมัยใหม่) รองรับการสัมผัสสิ่งนี้จะเป็นจริงเสมอแม้ว่าคุณจะใช้ฮาร์ดแวร์ (เดสก์ท็อปจอภาพมาตรฐานเมาส์และคีย์บอร์ด) ที่ไม่รองรับการสัมผัส ดังนั้นโซลูชันนี้จึงล้าสมัย
Barney

1
funnyItsNotCamelCaseAsJsIsThroughout ฉันหมายความว่าผู้คนจะต้องคัดลอกวางและแก้ไขรหัส ... :)
รอส

20

พบการทดสอบสำหรับหน้าต่าง Touch ไม่ทำงานบน Android แต่สิ่งนี้ทำ:

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

ดูบทความ: วิธีใดที่ดีที่สุดในการตรวจจับอุปกรณ์ "หน้าจอสัมผัส" โดยใช้ JavaScript


สิ่งนี้ตรวจจับหน้าจอสัมผัส แต่ต้องระวังเพราะจะส่งคืนค่า TRUE สำหรับแล็ปท็อปที่มีหน้าจอสัมผัสด้วย นี่อาจเป็นปัญหาหากคุณพยายามแยกแยะว่าผู้ใช้มาจากโทรศัพท์ / แท็บเล็ตหรือคอมพิวเตอร์ / แล็ปท็อปเนื่องจากแล็ปท็อปที่มีหน้าจอสัมผัสจะส่งคืนค่า TRUE
รวม

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

เหตุผลในการใช้ maxTouchPoints ร่วมกับ msMaxTouchPoints:

Microsoft ได้แจ้งว่าตั้งแต่ Internet Explorer 11 เป็นต้นไปคุณสมบัตินี้ (msMaxTouchPoints) ซึ่งเป็นเวอร์ชันที่นำหน้าผู้จำหน่ายของ Microsoft อาจถูกลบออกและแนะนำให้ใช้ maxTouchPoints แทน

ที่มา: http://ctrlq.org/code/19616-detect-touch-screen-javascript


สิ่งนี้ใช้งานได้และทำงานได้ในเครื่องมือสำหรับนักพัฒนา Google Chrome จำลองอุปกรณ์ขอบคุณ
Behnam Mohammadi

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

ใช้ได้ทุกที่ !!


แล้วเมาส์จะทำอย่างไร? (คำถามจริง)
hexalys

มันจะง่ายกว่าที่จะทำisTouch = "ontouchstart" in window || navigator.msMaxTouchPoints;
แอนดรูว์


4

Google Chrome ดูเหมือนจะส่งคืนผลบวกที่ผิดพลาดในสิ่งนี้:

var isTouch = 'ontouchstart' in document.documentElement;

ฉันคิดว่ามันมีส่วนเกี่ยวข้องกับความสามารถในการ "จำลองเหตุการณ์การสัมผัส" (F12 -> การตั้งค่าที่มุมล่างขวา -> แท็บ "ลบล้าง" -> ช่องทำเครื่องหมายสุดท้าย) ฉันรู้ว่ามันถูกปิดโดยค่าเริ่มต้น แต่นั่นคือสิ่งที่ฉันเชื่อมโยงการเปลี่ยนแปลงในผลลัพธ์กับ (วิธีการ "ใน" ที่ใช้ใน Chrome) อย่างไรก็ตามสิ่งนี้ดูเหมือนจะใช้งานได้เท่าที่ฉันได้ทดสอบ:

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

เบราว์เซอร์ทั้งหมดที่ฉันเรียกใช้รหัสนั้นในสถานะtypeofคือ "object" แต่ฉันรู้สึกมั่นใจมากขึ้นเมื่อรู้ว่ามันคืออะไรก็ตาม แต่ไม่ได้กำหนด :-)

ทดสอบบน IE7, IE8, IE9, IE10, Chrome 23.0.1271.64, Chrome สำหรับ iPad 21.0.1180.80 และ iPad Safari คงจะดีไม่น้อยถ้ามีคนทำแบบทดสอบเพิ่มเติมและแบ่งปันผลลัพธ์


ทั้งสองวิธีส่งคืนผลบวกปลอมบนพีซี Win 8 ที่มี FF 23 และ Chrome 28 เป็นเช่นนี้เสมอหรือเป็นเพราะครั้งหนึ่งฉันเคยติดหน้าจอสัมผัสกับคอมพิวเตอร์เครื่องนี้ - อาจเป็นก่อนติดตั้ง FF และ Chrome - แต่ไม่ใช่อีกต่อไป ฉันไม่มีชุดตัวเลือก "เลียนแบบเหตุการณ์การแตะ"
typhon

เอ่อมันต้องดิ้นรนกับฮาร์ดแวร์ใหม่อยู่เสมอ เบราว์เซอร์ต้องทำงานกับเลเยอร์นามธรรมของระบบปฏิบัติการ ... ซึ่งไม่ได้ใช้ทุกอย่างเสมอไป ... ในระยะสั้นด้วย JS คุณต้องพึ่งพาเบราว์เซอร์ :) ไม่มีวิธีสากล
เถ้า

ทั้งสองอย่างนั้นกลับมาเป็นจริงบน Ubuntu Firefox บนแล็ปท็อปแบบไม่สัมผัส
NoBugs

4

เขียนสิ่งนี้สำหรับหนึ่งในไซต์ของฉันและอาจเป็นวิธีแก้ปัญหาที่เข้าใจผิดได้มากที่สุด โดยเฉพาะอย่างยิ่งเนื่องจากแม้แต่ Modernizr ก็สามารถตรวจจับการสัมผัสได้

หากคุณใช้ jQuery

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

หรือแค่ JS ล้วนๆ ...

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

4
ระวังด้วย: อย่างน้อยไอแพดก็
ใส่เม้าส์

14
ไอ้คุณ Apple!
Timothy Perez

และผู้ที่ใช้ IE บนแท็บเล็ต Windows อาจต้องการใช้ทั้งการสัมผัสและเมาส์
Sebazzz

โพสต์นี้เกิดขึ้นก่อนที่จะมีแท็บเล็ต Windows
Timothy Perez

@ s427 - Fecking IE ... เพียงแค่ตรวจสอบ IE8 ฉันไม่คิดว่าจะมีอุปกรณ์เคลื่อนที่ใด ๆ ที่มี <= IE8
Timothy Perez

4

สำหรับโพสต์ / ความคิดเห็นแรกของฉัน: เราทุกคนรู้ดีว่ามีการเรียกใช้ "touchstart" ก่อนคลิก เรารู้ด้วยว่าเมื่อผู้ใช้เปิดเพจของคุณเขาจะ: 1) เลื่อนเมาส์ 2) คลิก 3) แตะหน้าจอ (สำหรับการเลื่อนหรือ ... :))

ลองทำอะไร:

// -> เริ่ม: 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';
});

// <- จบ: jQuery

ขอให้มีความสุขในวันนี้!


3

ฉันได้ทดสอบรหัสต่อไปนี้ที่กล่าวถึงข้างต้นในการสนทนา

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

ทำงานบน Android Mozilla, chrome, Opera, เบราว์เซอร์เริ่มต้นของ Android และซาฟารีบน iPhone ...

ดูเหมือนจะมั่นคงสำหรับฉัน :)


ง่ายสุด ๆ และใช้งานได้ดีสำหรับฉัน ทดสอบบน Android (Galaxy Note รุ่นเก่า) และตัวเลียนแบบ (Chrome) และบน iPad
Ralf

ส่งคืนผลบวกลวงสำหรับฉันใน Chrome
James

3

บล็อกโพสต์ที่เป็นประโยชน์ในหัวข้อนี้ซึ่งเชื่อมโยงจากแหล่งที่มา Modernizr เพื่อตรวจจับเหตุการณ์การสัมผัส สรุป: ไม่สามารถตรวจจับอุปกรณ์หน้าจอสัมผัสจาก Javascript ได้อย่างน่าเชื่อถือ

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


2

สิ่งนี้ใช้ได้กับฉัน:

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

1
คุณได้ทดสอบอุปกรณ์ต่างๆ, เบราว์เซอร์, ระบบปฏิบัติการ, อุปกรณ์ต่างๆกี่แพลตฟอร์ม
BerggreenDK

1
FF, Chrome, Safari บน Android และ iOS (iPad)
Turtletrail

1
ดีพอ ฉันเพิ่งทดสอบบนเดสก์ท็อปและมี "ไม่ได้กำหนด" จำนวนมากซึ่งทำให้โครงสร้าง IF มีความยุ่งยากเล็กน้อย หากคุณปรับค่าการส่งคืนของคุณเพียงเล็กน้อยเช่นนี้ return true == ("ontouchstart" ในหน้าต่าง || window.DocumentTouch && document instance ของ DocumentTouch); แล้วคุณมี :-) จริงหรือเท็จ
BerggreenDK

2
ใน Chrome "ontouchstart" ในหน้าต่างเป็นจริงบนพีซีของฉันที่ไม่มีหน้าจอสัมผัสจึงไม่สามารถใช้งานได้ ดังที่กล่าวไว้ก่อนหน้านี้การทดสอบนี้จะทดสอบว่าเบราว์เซอร์สามารถสัมผัสได้หรือไม่ นอกจากนี้ true == ไม่ได้ทำอะไรและควรละเว้น
rakensi

1
เมื่อฉันลองสิ่งนี้ใน Chrome ด้วยโปรแกรมจำลองในตัวมันจะตรวจจับการสัมผัสเมื่อเปิดอยู่ในโปรแกรมจำลองและจะไม่ตรวจจับการสัมผัสเมื่อปิดอยู่ ทำงานได้ดีสำหรับฉัน แต่: ฉันใช้เวอร์ชันสั้นโดย Prasad (ด้านล่าง) ซึ่งไม่ได้ใช้ || ในรหัสของ Turtletrail และ: ฉันไม่สนใจว่ามันจะใช้ได้กับอุปกรณ์ 100% หรือเปล่า 99% จะทำเพื่อฉัน
Ralf

1

หากคุณใช้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)

นอกจากนี้ทราบว่าการทดสอบตัวแทนของผู้ใช้จะให้ช่วงกว้างของการตรวจพบโทรศัพท์มือถือของไมโครซอฟท์กว่าiemobileWindows Phone

ดูคำถาม SO นี้ด้วย


2
เป็นคำตอบเดียวกันสำหรับคำถาม 4 ข้อในตอนนี้ ... และนี่ไม่ใช่วิธีแก้ปัญหาสำหรับคำถามที่เขากำลังถาม
jycr753

1
ฉันเชื่อว่ามันตอบคำถามที่นี่
ปีเตอร์ - แพน

มันไม่ใช่คำตอบ แต่เป็นคำใบ้ที่ฉันคิดว่าใครต้องการตรวจสอบว่าอุปกรณ์นั้นสามารถสัมผัสได้ก่อนที่ผู้ใช้จะสัมผัสหรือไม่
Shahadat Hossain Khan

1

ใน jQuery Mobile คุณสามารถทำได้:

$.support.touch

ไม่รู้ว่าทำไมถึงเป็นแบบนี้ .. แต่ปลอดภัยจาก crossbrowser (เบราว์เซอร์ปัจจุบัน 2 เวอร์ชันล่าสุด)


0

ดังที่ได้กล่าวไปแล้วอุปกรณ์อาจรองรับทั้งการป้อนข้อมูลด้วยเมาส์และแบบสัมผัส บ่อยครั้งที่คำถามไม่ใช่ "สิ่งที่รองรับ" แต่เป็น "สิ่งที่ใช้ในปัจจุบัน"

สำหรับกรณีนี้คุณสามารถลงทะเบียนเหตุการณ์ของเมาส์ (รวมถึงตัวฟังโฮเวอร์) และสัมผัสเหตุการณ์เหมือนกันได้

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

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

...

JavaScript ควรเรียก Listener ที่ถูกต้องโดยอัตโนมัติตามข้อมูลที่ผู้ใช้ป้อน ดังนั้นในกรณีของการสัมผัสonTouchStartCallbackจะถูกยิงเลียนแบบรหัสโฮเวอร์ของคุณ

โปรดทราบว่าการสัมผัสอาจทำให้ผู้ฟังทั้งสองประเภทสัมผัสและเมาส์ event.preventDefault()แต่ผู้ฟังสัมผัสไปครั้งแรกและสามารถป้องกันไม่ให้ผู้ฟังเมาส์ที่ตามมาจากการยิงโดยโทร

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

อ่านเพิ่มเติมที่นี่


-3

สำหรับการพัฒนา iPad ฉันใช้:

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

จากนั้นฉันสามารถเลือกที่จะเชื่อมโยงกับเหตุการณ์ที่ใช้การสัมผัส (เช่น ontouchstart) หรือเหตุการณ์ที่ใช้เมาส์ (เช่น onmousedown) ฉันยังไม่ได้ทดสอบบน Android


1
สิ่งนี้ใช้ไม่ได้กับ Opera Mobile 10 หรือ Internet Explorer Mobile 6 (Windows Mobile 6.5)
doubleJ

4
คำแนะนำ crossbrowser / cross OS / cross platform ที่ไม่ดี
BerggreenDK
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.