Vì vậy, giả sử chúng tôi muốn tạo một ứng dụng web giống như một ứng dụng gốc với "Thêm vào màn hình chính". Một trong những bước đầu tiên là tắt tính năng cuộn mặc định. Dễ dàng, phải không?iOS Tắt tính năng Cuộn trang bằng tính năng cuộn quá mức: chạm vào
// window or document
window.addEventListener("touchmove", function(event) {
// no more scrolling
event.preventDefault();
}, false);
Đó là tất cả tiền phạt và dandy cho đến khi bạn thêm overflow-scrolling
vào danh sách kết hợp. Để chính xác, trên iOS, nó sẽ là -webkit-overflow-scrolling: touch
.
/* #scrollable happens to be a ul */
#scrollable {
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
Bằng cách thêm ngăn sự kiện, cuộn được tăng tốc phần cứng trong vùng chứa không hoạt động, rõ ràng không phải là hiệu quả dự định.
Các giải pháp rõ ràng trông giống như sau:
// you could do this for multiple elements, of course
var scrollable = document.querySelector("#scrollable");
scrollable.addEventListener("touchmove", function(event) {
// no more bubbling :)
event.stopPropagation();
}, false);
giải pháp này giới thiệu một vấn đề, tuy nhiên, nếu bạn cố gắng để di chuyển sang trái hoặc phải trong #scrollable
, nó quay ngược lại cho người nghe cuộn mặc định. Rõ ràng, sau đó, bạn nên theo dõi các sự kiện để xem sự kiện touchmove
có đang theo dõi sang trái hoặc sang phải không? Thật không may, không, vì nó cũng sẽ, trong những trường hợp tôi không hoàn toàn hiểu, hãy hoàn nguyên về trình nghe cuộn mặc định khi cuộn dọc trong vùng chứa.
Bây giờ làm gì? Để làm cho vấn đề tồi tệ hơn, chúng tôi sẽ lý tưởng có thể xử lý click
hoặc nhấp như các sự kiện trên cá nhân li
s (đọc: touchstart
):
var items = scrollable.querySelectorAll("#scrollable li");
for (var item = 0; item < items.length; item++) {
items[item].addEventListener("touchstart", function() {
// handle the touch start
}, false);
}
Để khắc phục vấn đề này, chúng ta có thể chuyển sang đơn giản là sử dụng click
sự kiện, nhưng điều đó mặc định mục tiêu làm cho webapp "cảm thấy" có nguồn gốc do sự chậm trễ giữa khai thác và phản hồi. Để giải quyết việc này, chúng ta sẽ thêm một người biết lắng nghe sự kiện cho touchstart
và touchend
:
var items = scrollable.querySelectorAll("#scrollable li");
var activeItem = null, startTouch = null;
for (var item = 0; item < items.length; item++) {
items[item].addEventListener("touchstart", function(event) {
startTouch = event.touches[0];
activeItem = this;
}, false);
items[item].addEventListener("touchend", function(event) {
var touch = event.changedTouches[0];
var deltaX = touch.pageX - startTouch.pageX
var deltaY = touch.pageY - startTouch.pageY;
// require the touchstart to be within 10 pixels of the touchend
if (deltaX * deltaX + deltaY * deltaY <= 100)
// handle "click" event
}, false);
}
Đó là tất cả tốt và tốt, nhưng chúng tôi vẫn chưa giải quyết được vấn đề với trang mặc định di chuyển chiếm quyền điều khiển một số touchmove
sự kiện. Ý tưởng nào?