Vertical scrolling in carousel gallery

3,309 views
Skip to first unread message

klaasm...@gmail.com

unread,
Apr 19, 2011, 6:15:05 AM4/19/11
to isc...@googlegroups.com
Hi Metteo,

I postet in the iScoll4 comment already. I asked for a way to be able to scroll vertically in a carousel gallery and keeping horizontal scrolling available.

You wrote:
You have to check the movement threshold (say 10px). After that threshold you know which direction the finger is moving, if it is moving horizontally you preventDefault and keep iScroll do its stuff. If moving vertically you can skip the iScroll and proceed with standard page-scroll.

After a while, I figured out how to get the touch movement on the device and the regognision seems to work so far. I just don't know how to do the normal scrollen when not preventDefault event takes place. Also I am not sure how to check the touch movment on the gallery only and not on the whole page (there is only text and no iscoll container).

I would be glad if you or someone else could help me out with this.

Best regards,
Klaas



<script type="text/javascript">

            function loaded() {
               
                // Image gallery
                myScroll = new iScroll('wrapper', {
                                       snap: true,
                                       momentum: false,
                                       hScrollbar: true,
                                       vScrollbar: false,
                                       onScrollEnd: function () {
                                       document.querySelector('#indicator > li.active').className = '';
                                       document.querySelector('#indicator > li:nth-child(' + (this.currPageX+1) + ')').className = 'active';
                                       }
                                       });
               
            }
            document.addEventListener('touchstart', function (e) {
                                       
                                        var startTouchAt = e.changedTouches[0].pageY;
                                       
                                        document.addEventListener('touchmove', function (e) {                                           
                                            var moveTouch = e.changedTouches[0].pageY;
                                            var plusMinus = startTouchAt - moveTouch;

                                            if ( (plusMinus > 10) || (plusMinus < -10) ) {
                                             //normal scrolling?!?
                                            } else {
                                              preventDefault();
                                              }
                                        }, true);
                                       
                                       
                                    }, true);
                                   
            document.addEventListener('DOMContentLoaded', loaded, false);
            </script>

Matteo Spinelli

unread,
Apr 20, 2011, 6:06:14 AM4/20/11
to isc...@googlegroups.com
have a look at the 2-way-iscroll code https://github.com/cubiq/2-way-iScroll

you'll find a modified version of iscroll with a very similar logic.

Basically to get the default scrolling you just need to "return" (and of course preventDefault() should be e.preventDefault())

M.

Kwirr

unread,
Jul 20, 2011, 3:47:56 AM7/20/11
to isc...@googlegroups.com
Hi Klaas,

I also needed this (horizontal gallery and keep normal scroll for vertical page-scrolling enabled) for a mobile website and did the following steps:

In the html-page I built the iscroll with "lockDirection":
var myScroll = new iScroll('scroller', { hScrollbar: false,
                                                 vScrollbar: false,
                                                 vscroll: false,
                                                 hscroll: true,
                                                 lockDirection: true,
                                                 snap: 'td'});
     }

And in the iScroll script I changed a few things:

line 92 : commented out e.preventDefault();
onBeforeScrollStart: function (e) { //e.preventDefault(); //changed: e.preventDefault only on horizontal scrolling
},


line 289: enable iScroll, when not enabled.
 if (!that.enabled ) {
            //changed: enable again, if not enabled
            this.enable();
            return;
 }

and line 422 ff. : change lockDirections:        // Lock direction
        if (that.options.lockDirection) {
            if (that.absDistX > that.absDistY + 5) {
               //preventDefault() for horizontal scrolling
                e.preventDefault();
                newY = that.y;
                deltaY = 0;
               
            } else if (that.absDistY > that.absDistX + 5) {
            //changed: disabled iScroll for vertical scrolling
            that.disable();
            return;

            }
           
        }

It does not work when viewing in Safari on a Desktop with user-agent IPhone, but on the mobile device it works quite well.
I hope this helps.

Tim Jones

unread,
Jul 27, 2011, 6:45:56 PM7/27/11
to isc...@googlegroups.com
I had this exact problem -- I used Kirr's patch and it seems to have solved it perfectly. Thank you!

I have only tested on my IPhone 4 so far. I will be testing on other devices shortly and will post my results here.

=Tim=


Message has been deleted

Matteo Spinelli

unread,
Jul 28, 2011, 4:55:51 AM7/28/11
to isc...@googlegroups.com
please note that you don't need to "replace" the original code. you can define your custom onBeforeScrollStart event at init time. Eg:

new iScroll('el', { onBeforeScrollStart: function (e) { .... } });

M

bfm

unread,
Jul 28, 2011, 5:39:51 AM7/28/11
to isc...@googlegroups.com
had loads of trouble with this issue. thanks for your straightforward solution, dima!

Tim Jones

unread,
Jul 29, 2011, 3:52:22 PM7/29/11
to isc...@googlegroups.com
On Jul 27, 2011, at 3:45 PM, Tim Jones wrote:
> I had this exact problem -- I used Kirr's patch and it seems to have solved it perfectly. Thank you!
>
> I have only tested on my IPhone 4 so far. I will be testing on other devices shortly and will post my results here.

In case anyone's interested: This patch seems to work just fine on Android, IPhone3G and IPhone4 devices using their native browsers.

In IPhone Opera and on Windows Mobile I wasn't able to get the IScroll carousel working at all.

=Tim=


GP

unread,
Aug 31, 2011, 9:45:20 AM8/31/11
to iScroll
If anyone's interested, I have improved this script. The script above
did not work as intended for me. This code I'm posting works this way:

- Horizontal carousel type
- Allowed to scroll whole page up/down.
- Scroll in only one direction at a time.
- If you start to drag horizontal, then you can't scroll the whole
page. And vice versa.
- There's one small bug that I can't fix; if you start drag in about
45 degree angle, you can still scroll in all directions
simultaneously. Maybe someone can fix this?


var myScroll = new iScroll('scroll-wrapper', {
snap: 'li',
momentum: false,
hScrollbar: false,
vScroll: false,
onBeforeScrollStart: function (e) {
point = e.touches[0];
pointStartX = point.pageX;
pointStartY = point.pageY;
null;
},
onBeforeScrollMove: function(e){
deltaX = Math.abs(point.pageX - pointStartX);
deltaY = Math.abs(point.pageY - pointStartY);
if (deltaX >= deltaY) {
e.preventDefault();
} else {
null;
}
}
});

bsheldon

unread,
Sep 1, 2011, 12:50:20 PM9/1/11
to isc...@googlegroups.com
@GP, appreciate this updated script, performs beautifully + saved me a lot of frustration!

Michael Brydebøl

unread,
Sep 14, 2011, 10:09:38 AM9/14/11
to isc...@googlegroups.com
I've tried to modify the script with your code but it won't work. I use the version v4.1.9 of iScroll.

Are there any further fixes for this script to get it working?

Michael Brydebøl

unread,
Sep 20, 2011, 6:14:13 AM9/20/11
to iScroll
It works now!

I just have to remove this line from the html doc:
document.addEventListener('touchmove', function (e) { /
*e.preventDefault();*/ }, false);

Don't know why I don't have thought of that before :)

/Michael

Changilainen

unread,
Sep 22, 2011, 2:06:25 AM9/22/11
to isc...@googlegroups.com
Why this doesn't work for me? I guess I'm using it wrong but how should I use it then? :)

<script type="text/javascript">

var scrollContent, scrollNav;

function loaded() {
    scrollContent = new iScroll('contentWrapper');
    scrollNav = new iScroll('navWrapper');
    var myScroll = new iScroll('wrapper', {

        snap: 'li',
        momentum: false,
        hScrollbar: false,
        vScroll: false,
        onBeforeScrollStart: function (e) {
            point = e.touches[0];
            pointStartX = point.pageX;
            pointStartY = point.pageY;
            null;
        },
        onBeforeScrollMove: function(e){
            deltaX = Math.abs(point.pageX - pointStartX);
            deltaY = Math.abs(point.pageY - pointStartY);
            if (deltaX >= deltaY) {
                e.preventDefault();
            } else {
                null;
            }
        }
    });
}

Michael Brydebøl

unread,
Sep 22, 2011, 2:33:44 AM9/22/11
to iScroll
@Changilainen, have you remembered to edit the iScroll script like
Kwirr wrote earlier?

You need to edit the iScroll script to get it to work :)

/Michael

Changilainen

unread,
Sep 22, 2011, 3:01:41 AM9/22/11
to isc...@googlegroups.com
I didn't but now I edited it and it still has some problems. I'm using iScroll 4.1.9. I'm trying to combine two examples, ipad example and carousel example.
When I open the HTML file in my iPad's Safari browser, scrolling has some problems. Horizontal scrolling in carousel doesn't work at all and vertical page scrolling works only if I swipe my finger in 45 degrees. When I change iPad's orientation to portrait, carousels horizontal scrolling starts to work but vertical page scrolling still works only in 45 degree swipes. Also the prev and next buttons doesn't change the content in carousel's div element. Where could be the problem?

iPodToucHack

unread,
Dec 1, 2012, 8:47:45 AM12/1/12
to isc...@googlegroups.com
This works even now with 4.2.5 version. I'd recommend putting the code in src/iscroll.js around line 128, replacing default values and adding an 'hasTouch' condition to prevent broken snaps when viewing from desktop browsers:

onBeforeScrollStart: function (e) {

                if(hasTouch) {

                    point = e.touches[0]; 

                    pointStartX = point.pageX; 

                    pointStartY = point.pageY; 

                    null;

                }

},

onScrollStart: null,

onBeforeScrollMove: function(e){

            if(hasTouch) {

                deltaX = Math.abs(point.pageX - pointStartX); 

                deltaY = Math.abs(point.pageY - pointStartY); 

                if (deltaX >= deltaY) { 

                        e.preventDefault(); 

                } else

                        null

                }

            }

}, 

It should be like this. I've tested it in my iOS 5 iPod touch and it works perfectly: the 45 degrees bug still occurs but it isn't critical. Be sure to apply @Kwirr's edits before applying this patch, which should be a core functionality IMHO.

Mark Stevens

unread,
May 20, 2013, 5:58:04 AM5/20/13
to isc...@googlegroups.com
Thanks for that code iPodToucHack. I modified it slightly to make the snapping less sensitive:

onBeforeScrollStart: function (e) {

                if (this.options.hasTouch) {

                    point = e.touches[0];

                    pointStartX = point.pageX;

                    pointStartY = point.pageY;

                }

            },

            onBeforeScrollMove: function (e) {

                if (this.options.hasTouch) {

                    var point = e.touches[0];

Reply all
Reply to author
Forward
0 new messages