sự kiện cuộn javascript cho iPhone / iPad?


107

Tôi dường như không thể nắm bắt sự kiện cuộn trên iPad. Không có công việc nào trong số này, tôi đang làm gì sai?

window.onscroll=myFunction;

document.onscroll=myFunction;

window.attachEvent("scroll",myFunction,false);

document.attachEvent("scroll",myFunction,false);

Tất cả chúng đều hoạt động ngay cả trên Safari 3 trên Windows. Trớ trêu thay, MỌI trình duyệt trên PC đều hỗ trợ window.onload=nếu bạn không ngại chặn các sự kiện hiện có. Nhưng không đi trên iPad.

Câu trả lời:


146

IPhoneOS thực hiện ghi lại onscrollcác sự kiện, ngoại trừ cách bạn có thể mong đợi.

Xoay bằng một ngón tay không tạo ra bất kỳ sự kiện nào cho đến khi người dùng ngừng xoay - một onscrollsự kiện được tạo khi trang ngừng di chuyển và vẽ lại — như thể hiện trong Hình 6-1.

Tương tự, cuộn bằng 2 ngón tay onscrollchỉ kích hoạt sau khi bạn ngừng cuộn.

Cách thông thường để cài đặt trình xử lý hoạt động, ví dụ:

window.addEventListener('scroll', function() { alert("Scrolled"); });
// or
$(window).scroll(function() { alert("Scrolled"); });
// or
window.onscroll = function() { alert("Scrolled"); };
// etc 

(Xem thêm https://developer.apple.com/library/content/documentation/AppleApplication/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html )


23
Cảm ơn, điều đó đã buộc tôi phải nhìn nhận vấn đề xa hơn. Câu trả lời thực sự là việc phát hiện đỉnh của khung nhìn trên iphone / ipad chỉ hoạt động với window.pageYOffset và không document.body.scrollTop||document.documentElement.scrollTop giống như mọi trình duyệt / phần cứng khác đang tồn tại.
ck_

6
@ck_ Không may trên IPAD window.pageYOffsetkhông được cập nhật trong giai đoạn giảm tốc mà chỉ được cập nhật khi kết thúc cuộn.
Adaptabi

2
Việc ghi đè trực tiếp window.onscroll là một thực tiễn không tốt. Thêm một người nghe sự kiện sẽ tốt hơn. Sử dụng window.addEventListener ('scroll', function () {alert ('scrolled!');});
Kevin Dice,

4
ehm .. thực ra, window.onscroll đang chạy trên ipad của tôi mọi lúc, trong khi di chuyển và sau khi di chuyển, trong khi giảm tốc. có gì đó thay đổi không?
commonpike

Safari (và có thể những người khác) đã thay đổi sang sử dụng WKWebView với iOS 8. Chrome và Cordova vẫn sử dụng UIWebView, vì vậy chúng vẫn cho thấy sự cố với các sự kiện cuộn liên tục không được đưa ra. Có một plug-in WKWebView cho Cordova.
jiku

105

Đối với iOS, bạn cần sử dụng sự kiện touchmove cũng như sự kiện cuộn như sau:

document.addEventListener("touchmove", ScrollStart, false);
document.addEventListener("scroll", Scroll, false);

function ScrollStart() {
    //start of scroll event for iOS
}

function Scroll() {
    //end of scroll event for iOS
    //and
    //start/end of scroll event for other browsers
}

37
Sự kiện này chỉ được kích hoạt khi người dùng chủ động cuộn, sự kiện này không được kích hoạt trong giai đoạn giảm tốc của quá trình cuộn xung lượng.
Jon Tirsen

tôi đã thay đổi mã để bao gồm mã phát hiện cuộn cuối cho iOS
George Filippakos.

Bạn cũng có thể muốn thêm trình nghe cho "touchhend" sẽ hoạt động tương tự như cuộn trên máy tính để bàn.
BingeBoy

1
Lưu ý rằng điều này không cung cấp quyền truy cập vào các giai đoạn trong quá trình cuộn
Bến Sewards

3
đã ba năm. Tôi không thể nhận được bản cập nhật theo thời gian thực của vị trí cuộn trong quá trình giảm tốc. làm cách nào để viết ứng dụng giống như bản đồ của tôi ?????
FlavorScape

38

Xin lỗi vì đã thêm câu trả lời khác vào một bài đăng cũ nhưng tôi thường nhận được sự kiện cuộn rất tốt bằng cách sử dụng mã này (nó hoạt động ít nhất trên 6.1)

element.addEventListener('scroll', function() {
    console.log(this.scrollTop);
});

// This is the magic, this gives me "live" scroll events
element.addEventListener('gesturechange', function() {});

Và điều đó hiệu quả với tôi. Chỉ có điều nó không làm là đưa ra một sự kiện cuộn để giảm tốc độ cuộn (Khi quá trình giảm tốc hoàn tất, bạn sẽ có một sự kiện cuộn cuối cùng, hãy làm như bạn sẽ làm với nó.) Nhưng nếu bạn vô hiệu hóa quán tính với css bằng cách thực hiện điều này

-webkit-overflow-scrolling: none;

Bạn không có quán tính đối với các yếu tố của mình, đối với cơ thể mặc dù bạn có thể phải làm

document.addEventListener('touchmove', function(e) {e.preventDefault();}, true);

7
Tại sao lại từ chối một câu trả lời hợp lệ và không để lại một bình luận giải thích vấn đề với nó?
Dave Mackintosh

3
bởi vì việc giảm giá rất dễ dàng và nhanh chóng. : /
Zeshan Ahmed

5
Một câu trả lời LUÔN LUÔN "hợp lệ" theo tác giả của nó ... Không ai đăng một câu trả lời cố ý không hợp lệ. Nhưng đúng, họ nên giải thích lý do tại sao họ từ chối.
Matthieu Charbonnier

3
gesturechangesự kiện không phải là tiêu chuẩn và chỉ được hỗ trợ bởi Safari: developer.mozilla.org/en-US/docs/Web/Events/gesturechange
Nicolas Bouvrette

6

Tôi đã có thể tìm ra giải pháp tuyệt vời cho vấn đề này với iScroll, với cảm giác cuộn động lực và mọi thứ https://github.com/cubiq/iscroll Tài liệu github rất tuyệt và tôi chủ yếu theo dõi nó. Đây là chi tiết về việc triển khai của tôi.

HTML: Tôi đã bọc vùng có thể cuộn của nội dung của mình trong một số div mà iScroll có thể sử dụng:

<div id="wrapper">
  <div id="scroller">
    ... my scrollable content
  </div>
</div>

CSS: Tôi đã sử dụng lớp Modernizr cho "touch" để nhắm mục tiêu các thay đổi kiểu của tôi chỉ đến các thiết bị cảm ứng (vì tôi chỉ khởi tạo iScroll khi chạm).

.touch #wrapper {
  position: absolute;
  z-index: 1;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  overflow: hidden;
}
.touch #scroller {
  position: absolute;
  z-index: 1;
  width: 100%;
}

JS: Tôi đã bao gồm iscroll-probe.js từ bản tải xuống iScroll, sau đó khởi tạo cuộn như bên dưới, trong đó updatePosition là hàm của tôi phản ứng với vị trí cuộn mới.

# coffeescript
if Modernizr.touch
  myScroller = new IScroll('#wrapper', probeType: 3)
  myScroller.on 'scroll', updatePosition
  myScroller.on 'scrollEnd', updatePosition

Bạn phải sử dụng myScroller để có được vị trí hiện tại, thay vì nhìn vào phần bù cuộn. Đây là một chức năng được lấy từ http://markdalgleish.com/presentations/embracingtouch/ (một bài viết siêu hữu ích, nhưng hiện tại hơi lỗi thời)

function getScroll(elem, iscroll) {   
  var x, y;

  if (Modernizr.touch && iscroll) {
    x = iscroll.x * -1;
    y = iscroll.y * -1;   
  } else {
    x = elem.scrollTop;
    y = elem.scrollLeft;   
  }

  return {x: x, y: y}; 
}

Điểm khác duy nhất khác là thỉnh thoảng tôi sẽ mất một phần trang mà tôi đang cố cuộn đến và nó sẽ từ chối cuộn. Tôi phải thêm một số lệnh gọi vào myScroller.refresh () bất cứ khi nào tôi thay đổi nội dung của #wrapper và điều đó đã giải quyết được vấn đề.

CHỈNH SỬA: Một điểm khác là iScroll ăn tất cả các sự kiện "nhấp chuột". Tôi đã bật tùy chọn để iScroll phát ra sự kiện "nhấn" và xử lý các sự kiện đó thay vì "nhấp". Rất may, tôi không cần nhấp nhiều vào vùng cuộn, vì vậy đây không phải là vấn đề lớn.


1

Kể từ khi iOS 8 ra mắt, vấn đề này không còn tồn tại nữa. Sự kiện cuộn hiện cũng được kích hoạt trơn tru trong iOS Safari.

Vì vậy, nếu bạn đăng ký scrolltrình xử lý sự kiện và kiểm tra window.pageYOffsetbên trong trình xử lý sự kiện đó, mọi thứ hoạt động tốt.


1
Nó vẫn tồn tại trong một số trường hợp sử dụng như sử dụng Cordova. developer.telerik.com/featured/…
diosney

6
Kinh nghiệm của tôi là điều này vẫn còn là một vấn đề với các thiết bị iOS hiện tại vào năm 2019.
Chris
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.