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 положительным числом независимо от его значения).
Ответы
Ответ 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. Это исправляет его.