Hiểu các sự kiện chạm


80

Tôi đang cố gắng làm cho một số thư viện của mình hoạt động với các thiết bị cảm ứng, nhưng tôi đang gặp khó khăn khi cố gắng tìm hiểu cách chúng được hỗ trợ và cách chúng hoạt động.

Về cơ bản, có 5 sự kiện chạm , nhưng có vẻ như chỉ có sự đồng thuận giữa các trình duyệt di động về touchstartsự kiện này (duh). Tôi đã tạo một fiddle như một trường hợp thử nghiệm.

Tôi đã thử nghiệm điều này trên Galaxy Note của mình với Android 4 trên bo mạch, nhưng bạn cũng có thể kiểm tra liên kết bằng trình duyệt trên máy tính để bàn.

Mục đích là cố gắng tìm ra cách xử lý các vòi, vòi kép và vòi dài. Không có gì lạ mắt.

Về cơ bản, đây là những gì sẽ xảy ra:

Các trình duyệt cổ Android làm sự kiện liên lạc không cháy. Nó chỉ cố gắng bắt chước cú click chuột với vòi nước, bắn mousedown, mouseupclickcác sự kiện liên tiếp, nhưng vòi đôi chỉ phóng to trong và ngoài trang tha.

Chrome dành cho Android kích hoạt sự kiện bắt đầu cảm ứng khi ngón tay chạm vào màn hình. Nếu nó được phát hành đủ sớm, nó cháy rồi mousedown, mouseup, touchendvà cuối cùng là clicksự kiện.

Trong trường hợp vòi dài , sau khoảng một nửa thứ hai nó cháy mousedownmouseup, và touchendkhi ngón tay được nâng lên, không có clicksự kiện ở cuối.

Nếu bạn di chuyển ngón tay , nó sẽ kích hoạt một touchmovesự kiện vài lần, sau đó nó kích hoạt một touchcancelsự kiện và không có gì xảy ra sau đó, thậm chí không xảy ra touchendsự kiện khi nhấc ngón tay lên.

Một chạm đúp trigger zoom in / out tính năng, nhưng sự kiện-khôn ngoan nó bắn combo touchstart- toucheventhai lần, không có sự kiện chuột sa thải.

Firefox dành cho Android bắn một cách chính xác các touchstartsự kiện, và trong trường hợp cháy vòi ngắn mousedown, mouseup, touchendclicksau đó.

Trong trường hợp vòi dài , nó cháy mousedown, mouseupvà cuối cùng là touchendsự kiện. Chrome cũng vậy cho những thứ này.

Nhưng nếu bạn di chuyển ngón tay của bạn , nếu cháy touchmoveliên tục (như người ta có thể mong đợi) nhưng nó doesn không bắn các touchleavesự kiện khi lá ngón tay các phần tử với người nghe sự kiện, và không cháy, các touchcancelsự kiện khi ngón tay được ra khỏi khung nhìn trình duyệt .

Đối với các lần nhấn đúp , nó hoạt động giống như Chrome.

Opera Mobile làm điều tương tự của Chrome và Firefox chỉ với một lần nhấn ngắn, nhưng trong trường hợp nhấn lâu, sẽ kích hoạt một số loại tính năng chia sẻ mà tôi thực sự muốn tắt. Nếu bạn di chuyển ngón tay hoặc nhấn đúp, nó sẽ hoạt động giống như Firefox.

Chrome beta hiện thông thường cho vòi ngắn, nhưng trong trường hợp của vòi dài nó không cháy các mouseupsự kiện nữa, chỉ touchstart, sau đó mousedownsau một hiệp hai, sau đó touchendkhi các ngón tay được nâng lên. Khi ngón tay được di chuyển, bây giờ nó hoạt động giống như Firefox và Opera Mobile.

Trong trường hợp nhấn đúp , nó không kích hoạt các sự kiện chạm khi thu nhỏ mà chỉ kích hoạt khi phóng to.

Phiên bản beta của Chrome cho thấy hành vi kỳ lạ nhất, nhưng tôi thực sự không thể phàn nàn vì nó là bản beta.

Câu hỏi đặt ra là : có cách nào đơn giản và dễ dàng để cố gắng phát hiện các lần nhấn ngắn, vòi dài và nhấn đúp trong các trình duyệt phổ biến nhất của thiết bị cảm ứng không?

Thật tệ, tôi không thể kiểm tra nó trên các thiết bị iOS có Safari hoặc IE cho Windows Phone 7 / Phone 8 / RT, nhưng nếu một số bạn có thể, phản hồi của bạn sẽ rất được đánh giá cao.


1
Bạn đã thử Tocca.js chưa? gianlucaguarini.github.io/Tocca.js Nó cho phép tất cả các sự kiện liên lạc thiếu trên bất kỳ loại thiết bị và nó chỉ khoảng 1kb
Gianluca Guarini

Câu trả lời:


26

Nếu bạn chưa đọc, tôi khuyên bạn nên đọc mã nguồn cho Hammer.js

https://github.com/hammerjs/hammer.js/blob/master/hammer.js

Giữa các bình luận và mã khoảng 1400 dòng, có tài liệu tuyệt vời và mã rất dễ hiểu.

Bạn có thể thấy cách tác giả đã chọn để giải quyết rất nhiều sự kiện chung đụng:

giữ, nhấn, chạm đúp, kéo, kéo, bắt đầu, kéo, kéo lên, kéo xuống, kéo qua, kéo sang phải, vuốt, vuốt lên, vuốt xuống, vuốt qua, vuốt sang phải, biến đổi, bắt đầu chuyển đổi, chuyển đổi, xoay, chụm, pinchin, pinchout, chạm (bắt đầu phát hiện cử chỉ) , nhả (phát hiện cử chỉ kết thúc)

Tôi nghĩ rằng sau khi đọc mã nguồn, bạn sẽ hiểu rõ hơn về cách các sự kiện cảm ứng hoạt động và cách xác định những sự kiện nào mà trình duyệt có khả năng xử lý.

http://eightmedia.github.io/hammer.js/


Đoạn mã thú vị, có vẻ khá đầy đủ và rộng rãi. Tôi có thể mất một chút thời gian để phân tích nó.
MaxArt

9

Có một tài nguyên thực sự tuyệt vời https://patrickhlauke.github.io/touch/tests/results/ trình bày chi tiết thứ tự các sự kiện trên một số lượng trình duyệt đáng kinh ngạc. Nó cũng có vẻ được cập nhật thường xuyên (vào tháng 9 năm 2016, nó được cập nhật lần cuối vào tháng 8 năm 2016).

Ý chính là, về cơ bản là tất cả mọi thứ kích hoạt mouseovervà các sự kiện liên quan; hầu hết cũng kích hoạt các sự kiện chạm, thường hoàn thành (tiếp cận touchend) trước mouseovervà sau đó tiếp tục click(trừ khi thay đổi nội dung trang hủy bỏ điều này). Những trường hợp ngoại lệ khó xử đó rất may là tương đối hiếm (trình duyệt android bên thứ 3 và blackberry playbook).

Tài nguyên được liên kết đó đi vào mức độ chi tiết ấn tượng, đây là mẫu của ba bài kiểm tra đầu tiên trong số rất nhiều bài kiểm tra hệ điều hành, thiết bị và trình duyệt:

nhập mô tả hình ảnh ở đây

Tóm tắt một số điểm chính:

Trình duyệt di động

  • Tất cả các trình duyệt được liệt kê sẽ kích hoạt mouseovertrong lần nhấn đầu tiên. Chỉ một số trình duyệt Windows Phone mới kích hoạt nó bằng một lần nhấn thứ hai.
  • Tất cả kích hoạt click. Nó không chỉ định hủy clicknếu mouseoverthay đổi trang (tôi tin rằng hầu hết đều làm như vậy)
  • Hầu hết các trình duyệt kích hoạt mouseoversau touchstarttouchend. Điều này bao gồm iOS 7.1 Safari, Android gốc, Chrome, Opera và Firefox cho Android và một số (không phải tất cả các trình duyệt Windows phone)
  • Một số trình duyệt Windows Phone (tất cả Windows 8 / 8.1 và một phiên bản cho 10) và một số trình duyệt Android của bên thứ 3 (Dolphin, Maxathon, UC) kích hoạt mouseover sau touchstarttouchend.
  • Chỉ Blackberry Playbook mới kích hoạt mouseovergiữa touchstarttouchend
  • Chỉ có Opera Mini và Puffin (trình duyệt Android của bên thứ 3) thiếu touchstarthoặc touchend.

Trình duyệt máy tính để bàn

  • Các phiên bản cập nhật hợp lý của Chrome và Opera dành cho máy tính để bàn hoạt động giống như các phiên bản di động của chúng touchstarttouchendtiếp theo là mouseover.
  • Trình duyệt Firefox và Microsoft (IE <= 11 và nhiều phiên bản Edge) không kích hoạt bất kỳ touchstarttouchendsự kiện nào.
  • Không có dữ liệu trên máy Mac, nhưng có lẽ không có trình duyệt Ma nào hỗ trợ touchstarttouchenddo sự khan hiếm của giao diện màn hình cảm ứng Mac.

Ngoài ra còn có một lượng dữ liệu đáng kinh ngạc trên các trình duyệt kết hợp với các công nghệ hỗ trợ.


3

Có, bạn có thể bắt đầu hẹn giờ vào lúc touchstartkết thúc touchendvà thực hiện các lựa chọn của bạn từ đó.

Ngoài ra, bạn có thể thực hiện ... giả sử như vuốt, việc kích hoạt của tôi, touchmovebạn có thể nhận được các từ hợp của "ngón tay" và xem tôi đã đi touchendđược bao nhiêu trước khi được kích hoạt.

Tôi không biết có cách nào đơn giản hơn là sử dụng thư viện sự kiện cảm ứng không, nhưng tôi cho rằng bạn có thể viết một cách đơn giản cho các sự kiện 'chạm', 'chạm hai lần', 'vuốt' khá dễ dàng.


1
Nếu bạn nghĩ về nó và xem xét hoạt động của các trình duyệt ở trên, bạn sẽ thừa nhận rằng điều đó không dễ dàng chút nào. Ví dụ: nếu bạn chạm vào một phần tử, sau đó di chuyển ngón tay của bạn ra bên ngoài phần tử và sau đó nhấc ngón tay lên, đó sẽ không phải là một "lần nhấn" hợp lệ, nhưng bạn không thể phát hiện ra nó vì nó touchleavekhông bao giờ được kích hoạt.
MaxArt

Bạn làm cho một điểm tốt, NHƯNG; với mã hóa thích hợp, chẳng hạn như chúng tôi, nắm bắt phần tử e.target(tôi tin là) tại touchstart, nó có bằng với phần tử trên touchhend không? Nếu không, thì đó không phải là một vòi hợp lệ, đó là một cái bẫy. Tôi không nói rằng mã hóa một thư viện sẽ dễ dàng, nhưng nó không thực sự "cứng", tôi sẽ xếp hạng nó như là "trung bình" + những niềm vui là những gì nếu nó không được thử thách và làm cho chúng ta trở về stackoverflow xD
Alexandru Calin

Viết thư viện không phải là vấn đề đối với tôi, tôi thấy nó đầy thử thách, thỏa mãn và có phần thú vị. Nhưng bình luận của bạn chỉ gợi ý về một giải pháp, nhưng bạn xây dựng nó như thế nào? Bạn lưu giữ thông tin về touchstartsự kiện này ở đâu? Điều gì sẽ xảy ra nếu touchstartsự kiện thứ hai được kích hoạt trong khi đó (màn hình cảm ứng đa điểm)? Làm thế nào để bạn xử lý vòi dài? Đang sử dụng setTimeout, nhưng nếu ngón tay rời khỏi phần tử trong lúc đó thì sao? Làm thế nào để bạn phát hiện ra nó nếu không có sự kiện chạm nào được kích hoạt? Và cứ tiếp tục như vậy ... Tất nhiên là tôi sẽ thử, nhưng tôi đã hy vọng sẽ tìm thấy một tác động sâu sắc của các sự kiện chạm vào.
MaxArt

Bạn không thể kích hoạt sự kiện bắt đầu cảm ứng thứ hai mà sự kiện cảm ứng được kích hoạt, do đó bạn không thể có hai lần nhấn liên tục, vì vậy không có vấn đề gì. Bạn sẽ tiếp tục thông tin trong các biến và thiết lập lại chúng tại touchend
Alexandru Calin

Điều đó không chính xác, bạn có thể có một giây touchstarttrước khi lần đầu tiên touchendxảy ra. Hơn nữa, suy nghĩ về câu trả lời của bạn một lần nữa dẫn đến kết luận rằng nó sẽ không hữu ích, vì thuộc targettính của touchendsự kiện luôn bằng với phần tử mà lần chạm bắt đầu, ngay cả khi ngón tay được di chuyển ra bên ngoài phần tử!
MaxArt

3

Đây là quan sát mới nhất của tôi về các sự kiện chạm và chuột trên Android 4.3

Opera, Firefox và Chrome dường như có hành vi tiêu chuẩn

  1. Khi vuốt (touchstart-touchmove-touchhend):

    1. Không có sự kiện chuột nào (không bao gồm di chuột qua) kích hoạt.
    2. Di chuột chỉ kích hoạt nếu quá trình chạm và chạm xảy ra trên cùng một phần tử. (touchstart-touchmove-touchhend-mouseover)
    3. Nếu mặc định bị ngăn trên touchstart: hành vi vuốt mặc định không hoạt động. không có thay đổi nào xảy ra liên quan đến việc kích hoạt sự kiện chuột.
  2. Nhấn vào (chạm bắt đầu-chạm):

    1. Tất cả các sự kiện chuột di chuột qua-mousemove-mousedown-mouseup-click fire sau khi trì hoãn
    2. Nếu mặc định bị ngăn trên touchstart: chỉ kích hoạt di chuột qua.

Trình duyệt mặc định của Android có một số hành vi không chuẩn :

  1. Di chuột kích hoạt trước khi khởi động lại, có nghĩa là di chuột luôn kích hoạt.
  2. Tất cả các sự kiện chuột sẽ kích hoạt trên Tap, ngay cả khi mặc định bị chặn trên touchstart.
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.