подія прокрутки javascript для iPhone / iPad?


107

Я не можу захопити захоплення прокрутки на iPad. Жоден із цих робіт, що я роблю неправильно?

window.onscroll=myFunction;

document.onscroll=myFunction;

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

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

Всі вони працюють навіть на Safari 3 в Windows. Як не дивно, КОЖЕН браузер на ПК підтримує, window.onload=якщо ви не заперечуєте над крадіжкою існуючих подій. Але не варто переходити на iPad.

Відповіді:


146

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 )


23
Дякую, що змусило мене далі розглянути проблему. Реальний відповідь виявляв у верхній частині вікна перегляду на Iphone / Ipad працює тільки з window.pageYOffset і не document.body.scrollTop||document.documentElement.scrollTop як і будь-який інший браузер / апаратних засобів в існуванні.
ck_

6
@ck_ Unfortunatelly на IPAD window.pageYOffsetне оновлюється у фазі уповільнення, а лише тоді, коли прокрутка закінчується.
Адаптабі

2
Це неправильна практика безпосередньо замінити window.onscroll. Додавання слухача подій було б краще. Використовуйте window.addEventListener ('прокрутка', функція () {alert ('scroll!');});
Кевін Діс

4
Ем .. насправді window.onscroll весь час спрацьовує на моєму ipad, під час панорамування та після панорамування, уповільнюючись. щось змінилося?
commonpike

Safari (і, можливо, інші) змінили використання WKWebView з iOS 8. Chrome і Cordova все ще використовують UIWebView, тому вони все ще виставляють проблему, коли події безперервної прокрутки не видаються. Однак для Кордови є плагін WKWebView.
джику

105

Для 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
}

37
Ця подія запускається лише тоді, коли користувач активно прокручує, вона не запускається під час фази уповільнення прокрутки імпульсу.
Джон Тірсен

я змінив код, щоб включити код виявлення кінцевої прокрутки для iOS
Джордж Філіппакос,

Ви також можете додати слухача для "touchend", який буде діяти аналогічно прокрутці на робочому столі.
BingeBoy

1
Зауважте, що це не забезпечує доступ до фази прокрутки
Бен Сьюардс

3
минуло три роки. Я не можу отримати оновлення позиції прокрутки в режимі реального часу під час уповільнення. як я повинен написати свою програму, схожу на карти ?????
FlavorScape

38

Вибачте за те, що я додав ще одну відповідь до старої публікації, але зазвичай я дуже добре отримую подію прокрутки, використовуючи цей код (він працює принаймні в 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);

7
Чому спростуйте дійсну відповідь, а не залишайте коментар, що пояснює проблему?
Дейв Макінтош

3
тому що зворотний потік простий і швидкий. : /
Зешан Ахмед

5
Відповідь ЗАВЖДИ "дійсна" за її автором ... Ніхто не публікує свідомо неправдиву відповідь. Але так, вони повинні були пояснити, чому вони виступають проти.
Матьє Шарбоньє

3
gesturechangeподії нестандартні і підтримуються лише Safari: developer.mozilla.org/en-US/docs/Web/Events/gesturechange
Nicolas Bouvrette

6

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

HTML: Я загорнув область прокрутки свого вмісту в деякі диви, якими 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 з'їдає всі події "натискання". Я ввімкнув опцію, щоб iScroll випромінював подію "tap" і обробляв їх замість подій "click". На щастя, мені не потрібно було багато клацати в області прокрутки, так що це було не багато.


1

Після виходу iOS 8 ця проблема вже не існує. Подія прокрутки тепер плавно запускається і в iOS Safari.

Отже, якщо ви зареєструєте scrollобробник подій і перевірте window.pageYOffsetвсередині цього обробника подій, все працює добре.


1
Він існує ще в деяких випадках використання, таких як використання Кордови. developer.telerik.com/featured/…
diosney

6
Мій досвід полягає в тому, що це все ще залишається проблемою з сучасними пристроями iOS у 2019 році.
Кріс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.