Tôi đang cố gắng xử lý một lần nhấp nút. "Nút" là div tùy chỉnh cũng có thể chứa trẻ em. Gọi lại nhấp chuột sẽ kích hoạt khi người dùng đã nhấp và thả bên trong phần tử. Nếu người dùng nhấp vào bên trong và sau đó kéo và phát hành bên ngoài, trình xử lý sẽ không kích hoạt. Tôi cần phải làm việc này trên cả máy tính để bàn và thiết bị di động, do đó tôi đang sử dụng các sự kiện mousedown/mouseup
và touchstart/touchend
.Cách phát hiện sự kiện chạm bên ngoài phần tử
tôi cần phải thay đổi lớp nút từ "ép" thành "bình thường" ngay cả khi các phiên bản sử dụng bên ngoài, vì vậy tôi cần phải thêm một người biết lắng nghe để nắm bắt những sự kiện phát hành trong tài liệu:
var $myElement = $("#myelement"); //This is a div and can also contain children.
$myElement.on("mousedown touchstart", function(e){
$(this).addClass("pressed");
$(document).on("mouseup touchend", function listener(e){
$myElement.removeClass("pressed");
$(document).off("mouseup touchend", listener);
var $target = $(e.target);
if ($target.is($myElement) || $target.parents().is($myElement)){
//FIXME
alert("Inside!");
//do something here
return false;
} else {
//FIXME
alert("Outside!");
//let event bubble
}
});
return false;
});
Nó hoạt động tốt với các nhấp chuột, nhưng nó không hoạt động như mong đợi với các sự kiện cảm ứng. Tôi đã thử nghiệm điều này trong Chrome dành cho Android và khi nhấn vào phần tử, sau đó kéo ra, "Bên trong!" cảnh báo được hiển thị.
Vấn đề là trong tình trạng này:
if ($target.is($myElement) || $target.parents().is($myElement)){
Tôi đang cố gắng để kiểm tra xem sự kiện touchend
đã xảy ra trong nút hoặc bất kỳ của những đứa trẻ. Nếu nút không có con, khi nhấp vào nó và sau đó phát hành bên ngoài, phần đầu tiên của mệnh đề OR sẽ chuyển thành true. Nếu nút có con và tôi bấm vào các trẻ em, sau đó phát hành trong bất kỳ phần nào khác của màn hình, phần thứ hai của mệnh đề là đúng sự thật.
Điều gì sai với mã này?
Cảm ơn trước.
CẬP NHẬT
Tôi cũng đã thử nghiệm trong BlackBerry 10 với cùng kết quả. Rõ ràng mục tiêu cho sự kiện touchend
là nút (hoặc trẻ em), ngay cả khi tôi đã nhấp vào bên ngoài. Đây có phải là cách nó được cho là hoạt động không?
CẬP NHẬT
Và đây là lý do. Đây là what the W3C docs say about the event:
Mục tiêu của sự kiện này phải Element cùng đã nhận được sự kiện touchstart khi điểm tiếp xúc này đã được đặt trên bề mặt, ngay cả khi các điểm tiếp xúc đã kể từ khi chuyển ngoài khu vực tương tác của các phần tử mục tiêu.
Điều đó không có ý nghĩa với tôi, nhưng dù sao điều này giải thích được vấn đề của tôi. Tôi đã giả định sự kiện touchend
sẽ được gọi qua yếu tố mà ngón tay được nhả ra. Có thể phát hiện ra ngón tay bên ngoài bằng cách sử dụng một cách tiếp cận khác không?
CẬP NHẬT
Tôi đã cố gắng lấy tọa độ của touchevent
để lấy nguyên tố ở đó bằng cách sử dụng document.elementFromPoint
. Vấn đề là sự kiện này không chứa tọa độ (các danh sách changedTouches
và touches
trống). Tôi đã kiểm tra một cách khó khăn sự kiện trong trình gỡ lỗi và không có cách nào để lấy lại các hợp âm từ nó ngoài sự kiện ban đầu. Sau đó, tôi nghĩ rằng tôi có thể lưu trữ sự kiện touchmove
cuối cùng và nhận các coords từ đó, nhưng một lần nữa sự kiện này không có tọa độ riêng! Tại sao trên Trái Đất lại có hai sự kiện này khi chúng vô dụng? Và tôi đã thử nghiệm phương pháp này trong iOS, Android và BB10 với kết quả giống nhau.
Tôi đã từ bỏ. Tôi sẽ gọi lại cuộc gọi ngay cả khi người dùng đã nhấp vào bên ngoài.Tôi không thể tin rằng đó là năm 2013 guys và không có (đơn giản) cách để làm điều này? Tôi có thể sử dụng kéo & thả api nhưng theo this nó không được hỗ trợ trên thiết bị di động (Gotta yêu thích phát triển web di động).
Mặc dù nó không thể giúp bạn trực tiếp, tôi đã đặt cùng một kịch bản VanillaJS thực hiện khá nhiều điều tương tự và đăng một phiên bản đơn giản của mã đó [ở đây] (http://stackoverflow.com/questions/13030210/onclick-event-is-occuring-two-times-in-iphone-hybrid-app/13030622 # 13030622) –
@EliasVanOotegem cảm ơn, tôi đã đọc lướt qua nó, nhưng tôi chưa thể kiểm tra nó. Tôi hiện đang đọc nguồn của một số thư viện bạn đã liên kết. Có lẽ tôi đang cố gắng phát minh lại bánh xe ở đây. –