Событие прокрутки javascript для 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.
6 ответов
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
Для 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
}
Извините за добавление другого ответа к старому сообщению, но я обычно получаю событие прокрутки очень хорошо, используя этот код (он работает по крайней мере на 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);
Мне удалось получить отличное решение этой проблемы с помощью iScroll, с ощущением прокрутки импульса и всего остального https://github.com/cubiq/iscroll Документ github великолепен, и я в основном следовал ему. Вот подробности моей реализации.
HTML: я обернул прокручиваемую область моего контента в некоторые элементы div, которые iScroll может использовать:
<div id="wrapper">
<div id="scroller">
... my scrollable content
</div>
</div>
CSS: я использовал класс Modernizr для "touch", чтобы нацелить изменения стиля только на сенсорные устройства (потому что я только создавал 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, и это решало проблему.
РЕДАКТИРОВАТЬ: Еще один недостаток заключается в том, что iScroll съедает все события "щелчка". Я включил опцию, чтобы iScroll генерировал событие "tap", и обрабатывал их вместо событий "click". К счастью, мне не нужно было много нажатий в области прокрутки, так что это не имело большого значения.
Поскольку вышла iOS 8, этой проблемы больше не существует. Событие прокрутки теперь запускается плавно и в iOS Safari.
Итак, если вы зарегистрируете scroll
обработчик событий и проверка window.pageYOffset
внутри этого обработчика событий все работает просто отлично.
После некоторого тестирования на ios я обнаружил, что это подходит для ios и рабочего стола, если вас не беспокоит эта задержка в 120 мс на рабочем столе. Работает как шарм.
let isScrolling;
document.addEventListener("scroll", () => {
// Clear our timeout throughout the scroll
window.clearTimeout( isScrolling );
// Set a timeout to run after scrolling ends
isScrolling = setTimeout(function() {
// Run the callback
console.log( 'Scrolling has stopped.' );
}, 120);
});