เพิ่มการแตะไปยังเว็บไซต์

หน้าจอสัมผัสมีให้บริการในอุปกรณ์ต่างๆ มากขึ้นเรื่อยๆ ตั้งแต่โทรศัพท์ไปจนถึงหน้าจอเดสก์ท็อป แอปของคุณควรตอบสนองต่อการแตะในลักษณะที่เข้าใจง่ายและสวยงาม

หน้าจอสัมผัสมีให้บริการในอุปกรณ์ต่างๆ มากขึ้นเรื่อยๆ ตั้งแต่โทรศัพท์ไปจนถึงหน้าจอเดสก์ท็อป เมื่อผู้ใช้เลือกโต้ตอบกับ UI แอปของคุณควรตอบสนองต่อการสัมผัสของผู้ใช้ในลักษณะที่ใช้งานง่าย

ตอบสนองต่อสถานะขององค์ประกอบ

คุณเคยแตะหรือคลิกองค์ประกอบในหน้าเว็บแล้วสงสัยว่าเว็บไซต์ตรวจพบองค์ประกอบนั้นจริงๆ ไหม

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

องค์ประกอบ DOM สามารถรับค่าสถานะเริ่มต้น โฟกัส โฮเวอร์ และใช้งานอยู่ หากต้องการเปลี่ยน UI สำหรับสถานะแต่ละสถานะเหล่านี้ เราต้องใช้สไตล์กับคลาสจำลอง :hover, :focus และ :active ดังที่แสดงด้านล่าง

.btn {
  background-color: #4285f4;
}

.btn:hover {
  background-color: #296cdb;
}

.btn:focus {
  background-color: #0f52c1;

  /* The outline parameter suppresses the border
  color / outline when focused */
  outline: 0;
}

.btn:active {
  background-color: #0039a8;
}

ลองใช้

รูปภาพแสดงสีต่างๆ สำหรับสถานะของปุ่ม

ในเบราว์เซอร์ในอุปกรณ์เคลื่อนที่ส่วนใหญ่ สถานะโฮเวอร์และ/หรือโฟกัสจะมีผลกับองค์ประกอบหลังจากมีการแตะ

พิจารณาให้ดีว่าคุณตั้งค่าสไตล์ใดและมีลักษณะเป็นอย่างไรเมื่อผู้ใช้แตะเสร็จแล้ว

การระงับสไตล์เบราว์เซอร์เริ่มต้น

เมื่อเพิ่มสไตล์สำหรับสถานะต่างๆ แล้ว คุณจะเห็นว่าเบราว์เซอร์ส่วนใหญ่ใช้สไตล์ของตัวเองเพื่อตอบสนองต่อการแตะของผู้ใช้ สาเหตุหลักๆ ก็คือเมื่ออุปกรณ์เคลื่อนที่เปิดตัวครั้งแรก เว็บไซต์จํานวนหนึ่งไม่มีการจัดรูปแบบสําหรับสถานะ :active ด้วยเหตุนี้ เบราว์เซอร์หลายรุ่นจึงเพิ่มสีหรือสไตล์ไฮไลต์เพิ่มเติมเพื่อให้ความคิดเห็นแก่ผู้ใช้

เบราว์เซอร์ส่วนใหญ่ใช้พร็อพเพอร์ตี้ outline CSS เพื่อแสดงวงแหวนรอบองค์ประกอบเมื่อโฟกัสองค์ประกอบนั้น คุณซ่อนข้อมูลนี้ได้ด้วยวิธีต่อไปนี้

.btn:focus {
    outline: 0;

    /* Add replacement focus styling here (i.e. border) */
}

Safari และ Chrome จะเพิ่มสีไฮไลต์การแตะ ซึ่งสามารถป้องกันได้ด้วย-webkit-tap-highlight-colorคุณสมบัติ CSS ต่อไปนี้

/* Webkit / Chrome Specific CSS to remove tap
highlight color */
.btn {
  -webkit-tap-highlight-color: transparent;
}

ลองใช้

Internet Explorer ใน Windows Phone มีลักษณะการทำงานที่คล้ายกัน แต่จะแสดงผ่านเมตาแท็กดังนี้

<meta name="msapplication-tap-highlight" content="no">

Firefox มีผลข้างเคียง 2 ประการที่ต้องจัดการ

คลาสเทียม -moz-focus-inner ซึ่งจะเพิ่มโครงร่างในองค์ประกอบที่แตะได้ คุณนำออกได้โดยการตั้งค่า border: 0

หากใช้องค์ประกอบ <button> ใน Firefox ระบบจะใช้การไล่ระดับสี ซึ่งคุณนำออกได้โดยการตั้งค่า background-image: none

/* Firefox Specific CSS to remove button
differences and focus ring */
.btn {
  background-image: none;
}

.btn::-moz-focus-inner {
  border: 0;
}

ลองใช้

การปิดใช้การเลือกของผู้ใช้

เมื่อสร้าง UI คุณอาจต้องการให้ผู้ใช้โต้ตอบกับองค์ประกอบ แต่ต้องการปิดใช้ลักษณะการทำงานเริ่มต้นของการเลือกข้อความด้วยการกดค้างหรือลากเมาส์เหนือ UI

คุณทําได้ด้วยuser-selectพร็อพเพอร์ตี้ CSS แต่โปรดทราบว่าการทําเช่นนี้กับเนื้อหาอาจสร้างความหงุดหงิดให้กับผู้ใช้หากต้องการเลือกข้อความในองค์ประกอบ ดังนั้นโปรดใช้ฟีเจอร์นี้อย่างระมัดระวังและใช้ในปริมาณที่พอเหมาะ

/* Example: Disable selecting text on a paragraph element: */
p.disable-text-selection {
  user-select: none;
}

ใช้ท่าทางสัมผัสที่กำหนดเอง

หากมีแนวคิดสำหรับการโต้ตอบและท่าทางสัมผัสที่กําหนดเองสําหรับเว็บไซต์ โปรดคํานึงถึง 2 หัวข้อต่อไปนี้

  1. วิธีรองรับเบราว์เซอร์ทุกประเภท
  2. วิธีรักษาอัตราเฟรมให้สูง

ในบทความนี้ เราจะพูดถึงหัวข้อเหล่านี้โดยเฉพาะ ซึ่งครอบคลุม API ที่เราจําเป็นต้องรองรับเพื่อเข้าถึงเบราว์เซอร์ทั้งหมด จากนั้นจะพูดถึงวิธีใช้เหตุการณ์เหล่านี้อย่างมีประสิทธิภาพ

คุณอาจต้องการให้ผู้ใช้โต้ตอบกับองค์ประกอบทีละรายการหรือต้องการให้ผู้ใช้โต้ตอบกับองค์ประกอบหลายรายการพร้อมกัน ทั้งนี้ขึ้นอยู่กับสิ่งที่คุณต้องการให้ท่าทางสัมผัสทำ

เราจะดูตัวอย่าง 2 รายการในบทความนี้ ซึ่งทั้ง 2 ตัวอย่างจะแสดงให้เห็นถึงการสนับสนุนเบราว์เซอร์ทั้งหมดและวิธีรักษาอัตราเฟรมให้สูง

ตัวอย่าง GIF ของการแตะเอกสาร

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

ซึ่งมีประโยชน์เนื่องจากมีความยืดหยุ่นมากสําหรับผู้ใช้ แต่ใช้การจํากัดวิธีที่ผู้ใช้โต้ตอบกับ UI

ตัวอย่าง GIF ของการแตะองค์ประกอบ

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

วิธีนี้มีความยืดหยุ่นมากกว่าสำหรับผู้ใช้ แต่จะทำให้ตรรกะซับซ้อนในการจัดการ UI มากขึ้นและมีความยืดหยุ่นน้อยลงต่อข้อผิดพลาดของผู้ใช้

เพิ่ม Listener เหตุการณ์

ใน Chrome (เวอร์ชัน 55 ขึ้นไป) เราขอแนะนำให้ใช้ Internet Explorer และ Edge PointerEvents เพื่อใช้ท่าทางสัมผัสที่กำหนดเอง

ในเบราว์เซอร์อื่นๆ ให้ใช้ TouchEvents และ MouseEvents

ฟีเจอร์ที่ยอดเยี่ยมของ PointerEvents คือสามารถผสานอินพุตหลายประเภท ซึ่งรวมถึงเหตุการณ์เมาส์ การสัมผัส และเพน เข้าเป็นชุดการเรียกกลับชุดเดียว เหตุการณ์ที่จะฟัง ได้แก่ pointerdown, pointermove, pointerup และ pointercancel

ค่าที่เทียบเท่าในเบราว์เซอร์อื่นๆ คือ touchstart, touchmove, touchend และ touchcancel สำหรับเหตุการณ์การแตะ และหากคุณต้องการใช้ท่าทางสัมผัสเดียวกันสำหรับการป้อนข้อมูลด้วยเมาส์ คุณจะต้องใช้ mousedown, mousemove และ mouseup

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

การใช้เหตุการณ์เหล่านี้ต้องมีการเรียกใช้เมธอด addEventListener() ในองค์ประกอบ DOM พร้อมด้วยชื่อของเหตุการณ์ ฟังก์ชัน Callback และบูลีน บูลีนจะกําหนดว่าคุณควรจับเหตุการณ์ก่อนหรือหลังจากที่องค์ประกอบอื่นๆ มีโอกาสจับและตีความเหตุการณ์ (true หมายความว่าคุณต้องการให้เหตุการณ์อยู่ก่อนองค์ประกอบอื่นๆ)

ต่อไปนี้คือตัวอย่างการฟังการเริ่มต้นการโต้ตอบ

// Check if pointer events are supported.
if (window.PointerEvent) {
  // Add Pointer Event Listener
  swipeFrontElement.addEventListener('pointerdown', this.handleGestureStart, true);
  swipeFrontElement.addEventListener('pointermove', this.handleGestureMove, true);
  swipeFrontElement.addEventListener('pointerup', this.handleGestureEnd, true);
  swipeFrontElement.addEventListener('pointercancel', this.handleGestureEnd, true);
} else {
  // Add Touch Listener
  swipeFrontElement.addEventListener('touchstart', this.handleGestureStart, true);
  swipeFrontElement.addEventListener('touchmove', this.handleGestureMove, true);
  swipeFrontElement.addEventListener('touchend', this.handleGestureEnd, true);
  swipeFrontElement.addEventListener('touchcancel', this.handleGestureEnd, true);

  // Add Mouse Listener
  swipeFrontElement.addEventListener('mousedown', this.handleGestureStart, true);
}

ลองใช้

จัดการการโต้ตอบกับองค์ประกอบเดียว

ในข้อมูลโค้ดสั้นๆ ด้านบน เราได้เพิ่มเฉพาะ Listener เหตุการณ์เริ่มต้นสําหรับเหตุการณ์เมาส์เท่านั้น สาเหตุคือเหตุการณ์เมาส์จะทริกเกอร์ก็ต่อเมื่อเคอร์เซอร์วางเหนือองค์ประกอบที่เพิ่ม Listener เหตุการณ์เท่านั้น

TouchEvents จะติดตามท่าทางสัมผัสหลังจากที่เริ่มขึ้น ไม่ว่าการแตะจะเกิดขึ้นที่ใดก็ตาม และ PointerEvents จะติดตามเหตุการณ์ไม่ว่าการแตะจะเกิดขึ้นที่ใดก็ตามหลังจากที่เราเรียก setPointerCapture ในองค์ประกอบ DOM

สําหรับเหตุการณ์การเลื่อนเมาส์และสิ้นสุด เราจะเพิ่ม Listener เหตุการณ์ในเมธอดเริ่มต้นท่าทางสัมผัส และเพิ่ม Listener ลงในเอกสาร ซึ่งหมายความว่าจะติดตามเคอร์เซอร์ได้จนกว่าท่าทางสัมผัสจะเสร็จสมบูรณ์

ขั้นตอนในการติดตั้งใช้งานมีดังนี้

  1. เพิ่ม Listener ของ TouchEvent และ PointerEvent ทั้งหมด สําหรับ MouseEvent ให้เพิ่มเฉพาะเหตุการณ์เริ่มต้น
  2. ในแบ็กคอลท่าทางเริ่มต้น ให้เชื่อมโยงเหตุการณ์การเลื่อนเมาส์และเหตุการณ์สิ้นสุดกับเอกสาร วิธีนี้จะทำให้ระบบได้รับเหตุการณ์เมาส์ทั้งหมด ไม่ว่าเหตุการณ์จะเกิดขึ้นกับองค์ประกอบเดิมหรือไม่ก็ตาม สําหรับ PointerEvents เราจำเป็นต้องเรียก setPointerCapture() ในองค์ประกอบเดิมเพื่อรับเหตุการณ์เพิ่มเติมทั้งหมด จากนั้นจัดการกับจุดเริ่มต้นของท่าทาง
  3. จัดการเหตุการณ์การย้าย
  4. ที่เหตุการณ์สิ้นสุด ให้นำการเลื่อนเมาส์และสิ้นสุด Listener ออกจากเอกสาร แล้วสิ้นสุดท่าทางสัมผัส

ด้านล่างนี้คือข้อมูลโค้ดของเมธอด handleGestureStart() ซึ่งเพิ่มเหตุการณ์ย้ายและสิ้นสุดลงในเอกสาร

// Handle the start of gestures
this.handleGestureStart = function(evt) {
  evt.preventDefault();

  if(evt.touches && evt.touches.length > 1) {
    return;
  }

  // Add the move and end listeners
  if (window.PointerEvent) {
    evt.target.setPointerCapture(evt.pointerId);
  } else {
    // Add Mouse Listeners
    document.addEventListener('mousemove', this.handleGestureMove, true);
    document.addEventListener('mouseup', this.handleGestureEnd, true);
  }

  initialTouchPos = getGesturePointFromEvent(evt);

  swipeFrontElement.style.transition = 'initial';
}.bind(this);

ลองใช้

แคล็กแบ็กสิ้นสุดที่เราเพิ่มคือ handleGestureEnd() ซึ่งจะนำ Listener เหตุการณ์การย้ายและสิ้นสุดออกจากเอกสาร และปล่อยการจับเคอร์เซอร์เมื่อท่าทางสัมผัสเสร็จสิ้น ดังนี้

// Handle end gestures
this.handleGestureEnd = function(evt) {
  evt.preventDefault();

  if (evt.touches && evt.touches.length > 0) {
    return;
  }

  rafPending = false;

  // Remove Event Listeners
  if (window.PointerEvent) {
    evt.target.releasePointerCapture(evt.pointerId);
  } else {
    // Remove Mouse Listeners
    document.removeEventListener('mousemove', this.handleGestureMove, true);
    document.removeEventListener('mouseup', this.handleGestureEnd, true);
  }

  updateSwipeRestPosition();

  initialTouchPos = null;
}.bind(this);

ลองใช้

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

แผนภาพนี้แสดงสิ่งที่เหตุการณ์การสัมผัสทําขณะที่เราเพิ่มเหตุการณ์ย้ายและสิ้นสุดลงในเอกสารเมื่อเริ่มใช้ท่าทางสัมผัส

ภาพแสดงการเชื่อมโยงเหตุการณ์การแตะกับเอกสารใน
`touchstart`

การตอบสนองต่อการสัมผัสอย่างมีประสิทธิภาพ

เมื่อจัดการเหตุการณ์เริ่มต้นและสิ้นสุดแล้ว เราก็จะตอบสนองต่อเหตุการณ์การแตะได้

สําหรับเหตุการณ์เริ่มต้นและย้าย คุณสามารถดึงข้อมูล x และ y จากเหตุการณ์ได้อย่างง่ายดาย

ตัวอย่างต่อไปนี้จะตรวจสอบว่าเหตุการณ์มาจาก TouchEvent หรือไม่ โดยตรวจสอบว่า targetTouches มีอยู่หรือไม่ หากใช่ ระบบจะแยก clientX และ clientY จากการแตะครั้งแรก หากเหตุการณ์เป็น PointerEvent หรือ MouseEvent ระบบจะดึงข้อมูล clientX และ clientY โดยตรงจากเหตุการณ์นั้น

function getGesturePointFromEvent(evt) {
    var point = {};

    if (evt.targetTouches) {
      // Prefer Touch Events
      point.x = evt.targetTouches[0].clientX;
      point.y = evt.targetTouches[0].clientY;
    } else {
      // Either Mouse event or Pointer Event
      point.x = evt.clientX;
      point.y = evt.clientY;
    }

    return point;
  }

ลองใช้

TouchEvent มี 3 รายการที่มีข้อมูลการแตะ ดังนี้

  • touches: รายการการแตะทั้งหมดบนหน้าจอในปัจจุบัน ไม่ว่าจะแตะองค์ประกอบ DOM ใดก็ตาม
  • targetTouches: รายการการแตะในองค์ประกอบ DOM ที่เหตุการณ์เชื่อมโยงอยู่
  • changedTouches: รายการการแตะที่เปลี่ยนแปลงซึ่งส่งผลให้เหตุการณ์เริ่มทำงาน

ในกรณีส่วนใหญ่ targetTouches มีทุกอย่างที่คุณต้องการ (ดูข้อมูลเพิ่มเติมเกี่ยวกับรายการเหล่านี้ได้ที่รายการการแตะ)

ใช้ requestAnimationFrame

เนื่องจาก Callback ของเหตุการณ์จะทํางานในเธรดหลัก เราจึงต้องการเรียกใช้โค้ดให้น้อยที่สุดเท่าที่จะเป็นไปได้ใน Callback ของเหตุการณ์ เพื่อรักษาอัตราเฟรมให้สูงและป้องกันอาการกระตุก

การใช้ requestAnimationFrame() ทำให้เรามีโอกาสอัปเดต UI ก่อนที่เบราว์เซอร์จะวาดเฟรม และจะช่วยให้เราย้ายงานบางอย่างออกจากการเรียกกลับเหตุการณ์ได้

หากไม่คุ้นเคยกับ requestAnimationFrame() ให้ดูข้อมูลเพิ่มเติมที่นี่

การติดตั้งใช้งานโดยทั่วไปคือการบันทึกพิกัด x และ y ตั้งแต่เริ่มต้นและย้ายเหตุการณ์ และขอเฟรมภาพเคลื่อนไหวภายในการเรียกกลับของเหตุการณ์การย้าย

ในตัวอย่างนี้ เราจัดเก็บตำแหน่งการสัมผัสเริ่มต้นใน handleGestureStart() (มองหา initialTouchPos)

// Handle the start of gestures
this.handleGestureStart = function(evt) {
  evt.preventDefault();

  if (evt.touches && evt.touches.length > 1) {
    return;
  }

  // Add the move and end listeners
  if (window.PointerEvent) {
    evt.target.setPointerCapture(evt.pointerId);
  } else {
    // Add Mouse Listeners
    document.addEventListener('mousemove', this.handleGestureMove, true);
    document.addEventListener('mouseup', this.handleGestureEnd, true);
  }

  initialTouchPos = getGesturePointFromEvent(evt);

  swipeFrontElement.style.transition = 'initial';
}.bind(this);

เมธอด handleGestureMove() จะจัดเก็บตําแหน่งของเหตุการณ์ก่อนที่จะขอเฟรมภาพเคลื่อนไหว หากจําเป็น โดยส่งฟังก์ชัน onAnimFrame() ของเราเป็น Callback ดังนี้

this.handleGestureMove = function (evt) {
  evt.preventDefault();

  if (!initialTouchPos) {
    return;
  }

  lastTouchPos = getGesturePointFromEvent(evt);

  if (rafPending) {
    return;
  }

  rafPending = true;

  window.requestAnimFrame(onAnimFrame);
}.bind(this);

ค่า onAnimFrame คือฟังก์ชันที่เมื่อเรียกใช้แล้วจะเปลี่ยน UI เพื่อย้ายไปมา เมื่อส่งฟังก์ชันนี้ไปยัง requestAnimationFrame() เราจะบอกเบราว์เซอร์ให้เรียกใช้ฟังก์ชันก่อนที่จะอัปเดตหน้าเว็บ (เช่น แสดงการเปลี่ยนแปลงในหน้าเว็บ)

ใน handleGestureMove() callback เราจะตรวจสอบในขั้นต้นว่า rafPending เป็นเท็จหรือไม่ ซึ่งบ่งชี้ว่า requestAnimationFrame() ได้เรียก onAnimFrame() หรือไม่นับตั้งแต่เหตุการณ์ย้ายครั้งล่าสุด ซึ่งหมายความว่าเรามี requestAnimationFrame() รายการเดียวที่รอเรียกใช้ในเวลาใดก็ตาม

เมื่อเรียกใช้การเรียกคืน onAnimFrame() เราจะตั้งค่าการเปลี่ยนรูปแบบในองค์ประกอบที่ต้องการย้ายก่อนที่จะอัปเดต rafPending เป็น false ซึ่งจะช่วยให้เหตุการณ์การแตะครั้งถัดไปขอเฟรมภาพเคลื่อนไหวใหม่ได้

function onAnimFrame() {
  if (!rafPending) {
    return;
  }

  var differenceInX = initialTouchPos.x - lastTouchPos.x;
  var newXTransform = (currentXPosition - differenceInX)+'px';
  var transformStyle = 'translateX('+newXTransform+')';

  swipeFrontElement.style.webkitTransform = transformStyle;
  swipeFrontElement.style.MozTransform = transformStyle;
  swipeFrontElement.style.msTransform = transformStyle;
  swipeFrontElement.style.transform = transformStyle;

  rafPending = false;
}

ควบคุมท่าทางสัมผัสโดยใช้การสัมผัส

พร็อพเพอร์ตี้ CSS touch-action ช่วยให้คุณควบคุมลักษณะการทํางานของการแตะเริ่มต้นขององค์ประกอบได้ ในตัวอย่างนี้ เราใช้ touch-action: none เพื่อไม่ให้เบราว์เซอร์ดำเนินการใดๆ กับการแตะของผู้ใช้ ซึ่งช่วยให้เราขัดจังหวะเหตุการณ์การแตะทั้งหมดได้

/* Pass all touches to javascript: */
button.custom-touch-logic {
  touch-action: none;
}

การใช้ touch-action: none นั้นค่อนข้างเป็นตัวเลือกใหม่เนื่องจากจะป้องกันการทำงานเริ่มต้นของเบราว์เซอร์ทั้งหมด ในหลายกรณี ตัวเลือกใดตัวเลือกหนึ่งด้านล่างอาจเป็นวิธีแก้ปัญหาที่ดีกว่า

touch-action ให้คุณปิดใช้ท่าทางสัมผัสที่เบราว์เซอร์นำมาใช้ ตัวอย่างเช่น IE10+ รองรับท่าทางสัมผัสการแตะสองครั้งเพื่อซูม การตั้งค่า touch-action เป็น manipulation จะเป็นการป้องกันการแตะ 2 ครั้งตามค่าเริ่มต้น

วิธีนี้ช่วยให้คุณใช้ท่าทางสัมผัสแตะสองครั้งด้วยตัวเองได้

ด้านล่างนี้คือรายการค่า touch-action ที่พบได้ทั่วไป

พารามิเตอร์การทํางานด้วยการแตะ
touch-action: none เบราว์เซอร์จะไม่จัดการการโต้ตอบด้วยการสัมผัส
touch-action: pinch-zoom ปิดใช้การโต้ตอบทั้งหมดของเบราว์เซอร์ เช่น "touch-action: none" ยกเว้น "pinch-zoom" ซึ่งเบราว์เซอร์จะยังคงจัดการ
touch-action: pan-y pinch-zoom จัดการการเลื่อนแนวนอนใน JavaScript โดยไม่ต้องปิดใช้การเลื่อนแนวตั้งหรือการบีบนิ้ว (เช่น ภาพหมุน)
touch-action: manipulation ปิดใช้ท่าทางสัมผัสการแตะสองครั้ง ซึ่งจะหลีกเลี่ยงการหน่วงเวลาการคลิกโดยเบราว์เซอร์ ออกจากการเลื่อนและการซูมด้วยสองนิ้วไปยังเบราว์เซอร์

การรองรับ IE เวอร์ชันเก่า

หากต้องการรองรับ IE10 คุณจะต้องจัดการกับPointerEventsเวอร์ชันที่มีคำนำหน้าของผู้ให้บริการ

หากต้องการตรวจสอบการรองรับ PointerEvents โดยทั่วไปคุณจะต้องมองหา window.PointerEvent แต่ใน IE10 คุณจะต้องมองหา window.navigator.msPointerEnabled

ชื่อเหตุการณ์ที่มีคํานําหน้าของผู้ให้บริการ ได้แก่ 'MSPointerDown', 'MSPointerUp' และ 'MSPointerMove'

ตัวอย่างด้านล่างแสดงวิธีตรวจหาการสนับสนุนและเปลี่ยนชื่อเหตุการณ์

var pointerDownName = 'pointerdown';
var pointerUpName = 'pointerup';
var pointerMoveName = 'pointermove';

if (window.navigator.msPointerEnabled) {
  pointerDownName = 'MSPointerDown';
  pointerUpName = 'MSPointerUp';
  pointerMoveName = 'MSPointerMove';
}

// Simple way to check if some form of pointerevents is enabled or not
window.PointerEventsSupport = false;
if (window.PointerEvent || window.navigator.msPointerEnabled) {
  window.PointerEventsSupport = true;
}

โปรดดูข้อมูลเพิ่มเติมในบทความเกี่ยวกับการอัปเดตจาก Microsoft

ข้อมูลอ้างอิง

คลาสจำลองสำหรับสถานะการสัมผัส

ระดับ ตัวอย่าง คำอธิบาย
:วางเมาส์
ปุ่มในสถานะ &quot;กดแล้ว&quot;
แสดงเมื่อวางเคอร์เซอร์เหนือองค์ประกอบ การเปลี่ยนแปลงใน UI เมื่อวางเมาส์เหนือโฆษณาจะมีประโยชน์ในการกระตุ้นให้ผู้ใช้โต้ตอบกับองค์ประกอบ
:focus
ปุ่มที่มีสถานะโฟกัส
ป้อนเมื่อผู้ใช้แท็บผ่านองค์ประกอบในหน้า สถานะโฟกัสช่วยให้ผู้ใช้ทราบว่ากำลังโต้ตอบกับองค์ประกอบใดอยู่ และช่วยให้ผู้ใช้ไปยังส่วนต่างๆ ของ UI ได้อย่างง่ายดายโดยใช้แป้นพิมพ์
:active
ปุ่มในสถานะ &quot;กดแล้ว&quot;
เริ่มต้นเมื่อมีการกําหนดองค์ประกอบ เช่น เมื่อผู้ใช้คลิกหรือแตะองค์ประกอบ

ดูข้อมูลอ้างอิงเหตุการณ์การสัมผัสที่สมบูรณ์ได้ที่นี่ เหตุการณ์การสัมผัส W3C

เหตุการณ์การแตะ เมาส์ และตัวชี้

เหตุการณ์เหล่านี้เป็นองค์ประกอบพื้นฐานในการเพิ่มท่าทางสัมผัสใหม่ลงในแอปพลิเคชัน

เหตุการณ์การสัมผัส เมาส์ เคอร์เซอร์
touchstart, mousedown, pointerdown เหตุการณ์นี้จะเรียกใช้เมื่อนิ้วแตะองค์ประกอบเป็นครั้งแรกหรือเมื่อผู้ใช้คลิกเมาส์ลง
touchmove, mousemove, pointermove เหตุการณ์นี้จะเกิดขึ้นเมื่อผู้ใช้ใช้นิ้วลากไปบนหน้าจอหรือลากด้วยเมาส์
touchend, mouseup, pointerup เหตุการณ์นี้จะเกิดขึ้นเมื่อผู้ใช้ยกนิ้วออกจากหน้าจอหรือปล่อยเมาส์
touchcancel pointercancel เหตุการณ์นี้จะเกิดขึ้นเมื่อเบราว์เซอร์ยกเลิกท่าทางสัมผัส เช่น ผู้ใช้แตะเว็บแอปแล้วเปลี่ยนแท็บ

รายการแบบสัมผัส

เหตุการณ์การสัมผัสแต่ละรายการมีแอตทริบิวต์รายการ 3 รายการ ได้แก่

แอตทริบิวต์เหตุการณ์การสัมผัส
touches รายการการสัมผัสทั้งหมดบนหน้าจอในปัจจุบัน โดยไม่คำนึงถึงองค์ประกอบที่สัมผัส
targetTouches รายการการแตะซึ่งเริ่มต้นจากองค์ประกอบที่เป็นเป้าหมายของเหตุการณ์ปัจจุบัน เช่น หากเชื่อมโยงกับ <button> คุณจะได้รับเฉพาะการแตะบนปุ่มนั้น หากเชื่อมโยงกับเอกสาร คุณจะได้รับเหตุการณ์การสัมผัสทั้งหมดในเอกสาร
changedTouches รายการการแตะที่มีการเปลี่ยนแปลงซึ่งทําให้ระบบเรียกเหตุการณ์
  • สําหรับเหตุการณ์ touchstart แสดงรายการทัชพอยต์ที่เพิ่งเริ่มทํางานกับเหตุการณ์ปัจจุบัน
  • สําหรับเหตุการณ์ touchmove รายการทัชพอยต์ที่ย้ายตั้งแต่เหตุการณ์ล่าสุด
  • สําหรับเหตุการณ์ touchend และ touchcancel รายการทัชพอยต์ที่เพิ่งนําออกจากแพลตฟอร์ม

การเปิดใช้การรองรับสถานะที่ใช้งานอยู่ใน iOS

ขออภัย Safari ใน iOS ไม่ได้ใช้สถานะ active โดยค่าเริ่มต้น คุณต้องเพิ่ม Listener เหตุการณ์ touchstart ลงในเนื้อหาเอกสารหรือองค์ประกอบแต่ละรายการเพื่อให้ใช้งานได้

คุณควรดำเนินการนี้โดยใช้การทดสอบ User Agent เพื่อให้ทำงานเฉพาะในอุปกรณ์ iOS เท่านั้น

การเพิ่มการเริ่มต้นการแตะลงใน body มีข้อดีคือใช้กับองค์ประกอบทั้งหมดใน DOM ได้ แต่อาจมีปัญหาด้านประสิทธิภาพเมื่อเลื่อนหน้าเว็บ

window.onload = function() {
  if (/iP(hone|ad)/.test(window.navigator.userAgent)) {
    document.body.addEventListener('touchstart', function() {}, false);
  }
};

อีกทางเลือกหนึ่งคือเพิ่ม Listeners การเริ่มการแตะไปยังองค์ประกอบทั้งหมดที่โต้ตอบได้ในหน้าเว็บ ซึ่งจะช่วยลดความกังวลเกี่ยวกับประสิทธิภาพได้บ้าง

window.onload = function() {
  if (/iP(hone|ad)/.test(window.navigator.userAgent)) {
    var elements = document.querySelectorAll('button');
    var emptyFunction = function() {};

    for (var i = 0; i < elements.length; i++) {
        elements[i].addEventListener('touchstart', emptyFunction, false);
    }
  }
};