document.ontouchmove и прокрутка на iOS 5 - PullRequest
47 голосов
/ 17 октября 2011

iOS 5 принесла много приятных вещей в JavaScript / Web Apps. Одним из них является улучшенная прокрутка. Если вы добавите

-webkit-overflow-scroll:touch;

в стиле элемента textarea, прокрутка будет хорошо работать одним пальцем.

Но есть проблема. Для предотвращения прокрутки всего экрана рекомендуется, чтобы веб-приложения добавили следующую строку кода:

document.ontouchmove = function(e) {e.preventDefault()};

Это, однако, отключает новую прокрутку.

У кого-нибудь есть хороший способ разрешить новую прокрутку внутри текстовой области, но не позволить прокрутить всю форму?

Ответы [ 5 ]

56 голосов
/ 18 октября 2011

Обновление За Комментарий Альваро , это решение может больше не работать с iOS 11.3.

Вы должны иметь возможность разрешить прокрутку, выбрав, вызывать или не вызывать warnDefault. Например.,

document.ontouchmove = function(e) {
    var target = e.currentTarget;
    while(target) {
        if(checkIfElementShouldScroll(target))
            return;
        target = target.parentNode;
    }

    e.preventDefault();
};

Кроме того, это может сработать, если событие не достигнет уровня документа.

elementYouWantToScroll.ontouchmove = function(e) {
    e.stopPropagation();
};

Редактировать Для всех, кто читает позже, альтернативный ответ работает и намного проще.

21 голосов
/ 03 июня 2013

Единственная проблема с ответом Брайана Никеля состоит в том, что (как упомянул user1012566) stopPropagation не предотвращает пузыри, когда вы выходите за границы прокручиваемого объекта.Вы можете предотвратить это с помощью следующего:

elem.addEventListener('touchstart', function(event){
    this.allowUp = (this.scrollTop > 0);
    this.allowDown = (this.scrollTop < this.scrollHeight - this.clientHeight);
    this.prevTop = null; 
    this.prevBot = null;
    this.lastY = event.pageY;
});

elem.addEventListener('touchmove', function(event){
    var up = (event.pageY > this.lastY), 
        down = !up;

    this.lastY = event.pageY;

    if ((up && this.allowUp) || (down && this.allowDown)) 
        event.stopPropagation();
    else 
        event.preventDefault();
});
16 голосов
/ 01 июня 2012

Для тех, кто пытается добиться этого с помощью PhoneGap, вы можете отключить эластичную прокрутку в cordova.plist, установите для UIWebViewBounce значение NO.Надеюсь, это поможет любому, кто потратит на это целую вечность (как я).

6 голосов
/ 13 апреля 2012

ScrollFix кажется идеальным решением. Я проверил это, и он работает как шарм!

https://github.com/joelambert/ScrollFix

/**
 * ScrollFix v0.1
 * http://www.joelambert.co.uk
 *
 * Copyright 2011, Joe Lambert.
 * Free to use under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 */

var ScrollFix = function(elem) {
    // Variables to track inputs
    var startY, startTopScroll;

    elem = elem || document.querySelector(elem);

    // If there is no element, then do nothing  
    if(!elem)
        return;

    // Handle the start of interactions
    elem.addEventListener('touchstart', function(event){
        startY = event.touches[0].pageY;
        startTopScroll = elem.scrollTop;

        if(startTopScroll <= 0)
            elem.scrollTop = 1;

        if(startTopScroll + elem.offsetHeight >= elem.scrollHeight)
            elem.scrollTop = elem.scrollHeight - elem.offsetHeight - 1;
    }, false);
};
2 голосов
/ 25 октября 2011

Было неприятно обнаружить известную проблему с stopPropagation и собственной прокруткой div.Похоже, что он не предотвращает всплывание onTouchMove, так что при прокрутке за пределы div (вверху вверх или внизу внизу) вся страница отскочит.

Дополнительные обсуждения здесь и здесь .

...