Javascript scroll event для iPhone/iPad?

Я не могу захватить событие прокрутки на iPad. Ни одна из этих работ, что я делаю неправильно?

window.onscroll=myFunction;

document.onscroll=myFunction;

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

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

Все они работают даже на Safari 3 в Windows. По иронии судьбы, КАЖДЫЙ браузер на ПК поддерживает window.onload=, если вы не против сбрасывать существующие события. Но iPad не идет.

Ответ 1

iPhoneOS захватывает события onscroll, но не так, как вы можете ожидать.

Панорамирование одним пальцем не генерирует никаких событий, пока пользователь не остановит панорамирование. Событие onscroll создается, когда страница перестает перемещаться и перерисовываться - как показано на рисунке 6-1.

Аналогично, прокрутка с двумя пальцами стреляет onscroll только после того, как вы остановили прокрутку.

Обычный способ установки обработчика работает, например.

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

(См. также https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html)

Ответ 2

Для iOS вам нужно использовать событие touchmove, а также прокрутить событие, подобное этому:

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
}

Ответ 3

Извините за добавление другого ответа на старое сообщение, но я обычно получаю событие прокрутки очень хорошо, используя этот код (он работает хотя бы на 6.1)

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

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

И это работает для меня. Единственное, чего он не делает, это дать событие прокрутки для замедления прокрутки (как только завершение замедления будет завершено, вы получите окончательное событие прокрутки, сделайте так, как вы это сделаете.), Но если вы отключите инерцию с помощью css, сделав это

-webkit-overflow-scrolling: none;

Вы не получите инерции на своих элементах, для тела, хотя вам может понадобиться классический

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

Ответ 4

Мне удалось получить отличное решение этой проблемы с iScroll, с ощущением прокрутки импульса и всего https://github.com/cubiq/iscroll Документ github отлично, и я в основном следовал за ним. Вот подробности моей реализации.

HTML: Я завернул прокручиваемую область моего контента в некоторых div, которые iScroll может использовать:

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

CSS Я использовал класс Modernizr для "касания", чтобы настроить мои изменения стиля только на сенсорные устройства (потому что я только создавал экземпляр iScroll на ощупь).

.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: Я включил iscroll-probe.js из загрузки iScroll, а затем инициализировал скроллер, как показано ниже, где updatePosition - это моя функция, которая реагирует на новую позицию прокрутки.

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

Вы должны использовать myScroller, чтобы получить текущую позицию сейчас, вместо того, чтобы смотреть на смещение прокрутки. Вот функция, взятая из http://markdalgleish.com/presentations/embracingtouch/ (очень полезная статья, но немного устаревшая)

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}; 
}

Единственный другой вопрос, который я получил иногда, я потерял часть своей страницы, которую я пытался прокрутить, и она откажется прокручивать. Мне пришлось добавлять некоторые вызовы myScroller.refresh() всякий раз, когда я менял содержимое #wrapper, и это решило проблему.

EDIT: Еще одна проблема заключалась в том, что iScroll ест все события "click". Я включил опцию, чтобы iScroll излучал событие "tap" и обрабатывал те, а не "click" события. К счастью, мне не нужно было много щелкать в области прокрутки, так что это было неважно.