Подтвердить что ты не робот

IScroll с естественной прокруткой по одной оси

Я использую самый замечательный инструмент javascript iScroll4 http://cubiq.org/iscroll-4 на мобильном сайте для iOS и Android. Вот как выглядит мой макет:

layout problem

В области горизонтальной прокрутки используется iScroll4 со следующими настройками:

   var myScroll = new iScroll('frame',  { hScrollbar: false, vScrollbar: false, vScroll: false })

Горизонтальная часть прокрутки отлично работает. Эта проблема - это то, что происходит, когда пользователь пытается прокрутить вверх или вниз по странице, поместив палец в область горизонтальной прокрутки. Поэтому мне нужна собственная вертикальная прокрутка и горизонтальная прокрутка iScroll в той же области.

То, что я пробовал до сих пор: Удаление e.preventDefault() в коде iScroll (разрешает естественную прокрутку, но в овах BOTH). Удаление e.preventDefault(), а затем отключить горизонтальную прокрутку страницы с помощью этого:

var touchMove;

document.ontouchstart = function(e){
    touchMove = e.touches[0];
}

document.ontouchmove = function(e){
    var theTouch = e.touches[0] || e.changedTouches[0];
    var Xer      = rs(touchMove.pageX - theTouch.pageX).toPos();
    var Yer      = rs(touchMove.pageY - theTouch.pageY).toPos();        
    touchMove    = theTouch;
    if(Yer > Xer){ e.preventDefault(); }
}

который, кажется, ничего не делает. Как я могу разрешить собственную вертикальную прокрутку в области горизонтальной прокрутки без потери горизонтальной прокрутки iScroll? Я действительно в тупике. Спасибо заранее.

(только для записи rs (foo).toPos() - функция, которая делает foo положительным числом независимо от его значения).

4b9b3361

Ответ 1

Предлагаемое редактирование для превосходного решения @Lukx. Новые версии iScroll4 помещают e.preventDefault() в onBeforeScrollMove, которые можно переопределить. Поместив блок if в эту опцию, по умолчанию не допускается вертикальная прокрутка, а вертикаль может прокручиваться изначально.

myScroll = new iScroll('scrollpanel', {
    // other options go here...
    vScroll: false,
    onBeforeScrollStart: function ( e ) {
        if ( this.absDistX > (this.absDistY + 5 ) ) {
            // user is scrolling the x axis, so prevent the browsers' native scrolling
            e.preventDefault();
        }
    },
});

Ответ 2

Если вы хотите добиться эффекта, описанного Fresheyeball без взлома ядра, и без изменения iScroll для swipeview, iScroll 4 предлагает вам прослушиватели событий для работы.

myScroll = new iScroll('scrollpanel', {
    // other options go here...
    vScroll: false,
    onBeforeScrollMove: function ( e ) {
        if ( this.absDistX > (this.absDistY + 5 ) ) {
            // user is scrolling the x axis, so prevent the browsers' native scrolling
            e.preventDefault();
        } else {
            // delegate the scrolling to window object
        window.scrollBy( 0, -this.distY );
    }
    },
});

Таким образом, onBeforeScrollMove -Handler проверяет, является ли направление прокрутки горизонтальным, а затем предотвращает обработчик по умолчанию, тем самым эффективно блокируя действие прокрутки до оси X (попробуйте прокомментировать это, вы увидеть разницу). В противном случае, если направление прокрутки должно быть вертикальным, мы прокручиваем браузер с помощью метода window.scrollBy(). Это не совсем родное, но отлично работает.

Надеюсь, что поможет

Lukx

[EDIT] Мое первоначальное решение, которое не использовало window.scrollBy(), не работало на более медленных телефонах Samsung, поэтому мне нужно было адаптировать ответ.

Ответ 3

С iscroll 5 вы можете установить eventPassthrough: true для достижения этого. См. http://iscrolljs.com/#configuring

Ответ 4

OLD ANSWER

UPDATE специально для написания этой проблемы был написан специальный pluggin: http://cubiq.org/swipeview

Я нашел способ!

добавьте переменную в верхнюю часть документа: если android равен 15 и iOS равен 3

 var scrollTolerance = ( rs().isDevice('android') )?15:3;

отключить исходный файл e.preventDefault(); для прокрутки. Это находится в onBeforeScrollStart:

в _move только под

 timestamp = e.timeStamp || Date.now();

добавить эту строку

if( Math.sqrt(deltaX*deltaX) > scrollTolerance){e.preventDefault();}

Что это значит: вы, возможно, предположили, что scrollTolerance устанавливает отклонение в направлении пальца. Мы не хотим требовать идеального вертикального угла, чтобы получить прокрутку вниз по родному свитку. Также iOS не обнаруживает должным образом и никогда не будет выше 4 по какой-то причине, поэтому я использовал 3. Затем мы отключили стандарт iScroll e.preventDefault(); который предотвращает естественную вертикальную прокрутку на нашей двускатной области. Затем вставляем e.preventDefault(); только при перемещении и на основании направления пальца от допуска.

Это не работает идеально. Но приемлемо и работает на iOS и Android. Если кто-нибудь видит лучшие способы, напишите здесь. Это то, что я (и предполагаю, что другие) нужно использовать регулярно, и у нас должно быть идеальное твердое решение.

Спасибо.

Ответ 5

Пожалуйста, проверьте это решение у Адама. https://gist.github.com/hotmeteor/2231984

Я думаю, что трюк состоит в том, чтобы добавить чек onBeforeScrollMove. Сначала получите начальную позицию касания в onBeforeScrollTouchStart, а затем в onBeforeScrollMove проверьте новую позицию, а затем отключите требуемый прокрутку в зависимости от разницы.

Ответ 6

iScroll 5 поддерживает естественную прокрутку любой оси!

http://iscrolljs.com/

Ответ 7

на iScroll5 просто установите для параметра eventPassthrougt значение true. Это исправляет его.