iScroll 5 ready for beta test

After a long development phase iScroll 5 is finally out and is looking for beta testers. This is probably the most important iScroll release yet as it leaves the mobile-only realm to become a universal javascript scroller.

iScroll was born in 2008 to fill the lack of native scrolling in the mobile webkit (at the time iPhone only) browser.

Time has passed, mobile browsers are getting better and a javascript scroller is becoming less relevant. That’s the reason why iScroll is not just a scroller for mobile anymore but a cross browser solution to interact with DOM elements. It now supports not only touch events but also pointers, key presses, remote controls and of course the good old mouse.

iScroll now runs on a wide variety of devices from desktop to mobile, from tablet to webtv. Some platforms need some tweaking though and this is were I need your help and the reason for the nasty beta notation.

Go get iScroll 5 beta 1!

Important changes

v5 is not a drop in replacement for v4. The core mission changed and with it the API. Hopefully the migration won’t be too painful.

The first notable difference is that the object is now called IScroll (capital I) instead of iScroll (lower i), so to invoke a new instance you’d do like so:

var scroller = new IScroll('#id');

This has been long disputed and at the end I decided to do things right and capitalize the class.

Another important change is that the horizontal scroll is always disabled by default. If you want to scroll horizontally you have to explicitly set the option scrollX: true. This should help preserve some precious resources.

You’ll also notice that the momentum formula now feels more natural and performance drastically improved. I did my best to optimize the script on Android and I believe that we are now pretty close to the best the device can offer.

Lastly, to hook to one of the many custom events (eg: onScroll) you no longer pass a function within the options but you use the on(type, fn) method. Eg:

var scroller = new IScroll('#id');
scroller.on('scrollStart', function () { console.log('scroll started'); });

This should be enough to get you started, now it’s…

… Demo time!

There are more new features than a blog post could host. I’m working on a detailed documentation and on more demos, but I need your help to remove the word “beta.1” from the revision number.

The following are some of the demos I’d like you to test. Please report bugs on github or –if you are really lazy– send me a tweet.

Simple demo, to test the new momentum formula and augmented performace.

Custom easing functions. Try to pull down and release, or scroll down to the bottom.

Carousel with indicators, no additional code required

Horizontal iScroll preserving native vertical scroll (!)

Scroll with the keyboard

Minimap, you can scroll the detail view or the minimap itself

Parallax like there’s no tomorrow

Real time position probing

Scroll to element


Please note that more demos awaits you. Download the iScroll and try ’em all.

What the CLA!?

CLA stands for Contributor License Agreement, it basically says that all contributions to the script are released to the author (me in this case). This might look Nazi, but it’s actually the only way to ensure that the script will remain free and open source for the time being.

I’ve been contacted by various entities (even open source projects) that without a CLA couldn’t use the script, so I decided to give it a shot hoping that it won’t damage the script development.

To send pull requests you are required to sign an online form. Sorry about that, I hate this stuff as much as you do but we live in a nasty nasty world.

The future

This is only the beginning. First step is to exit beta phase then I’ll work on detailed documentation and on some new features such as Infinite Scrolling.

Waiting for suggestions and bug reports.

121 thoughts on “iScroll 5 ready for beta test”

  1. Hello Matteo,
    I try to enter text in an input element and it’s not working for me (not with 4 or 5 version). Do i miss something?

    1. Add the following to the css

      #scroller input, textarea, select {
      -webkit-user-select: auto;
      -moz-user-select: auto;
      -ms-user-select: auto;
      user-select: auto;

      1. I’m having the same problem, and adding the user-select property doesn’t fix it. Maybe there’s an option for iScroll we aren’t aware of that we should be passing?

      2. Well you advice works for me only on default-Anroid(4.3) browser

        Desktop-Firefox (v.22) and Desktop-Chrome(v. 28) can still not select the inputtextarea (and fire scrollstart twice btw). In android-chrome and android-firefox (actual versions) I can even not click any buttons.

  2. Very nice! Thank you very much for v5. I had been hoping that you had something like this in the works. Just one little request

    The text of your license is clearly the same as the MIT license. Howeve, you do not explicitly mention MIT license anywhere. It might help to have this mentioned since it makes it a whole lot easier to delcare and acknowledge the use of iScroll5

  3. Hello Mat,

    I have to said… Your work is amazing ! Thanks a lot to share it.

    version 5 is really more optimised than version 4.

    Good job !

  4. Hey Mat,
    is it possible to use select boxes in the iScroll container.
    By now, the click event is not passed through.
    Is there a workaround?

    1. I didn’t work on form fields yet.

      Try to use the click:true option. Also you may try to add useTransform:false but that impacts on performance heavily.

      1. I’ve tried the latest iscroll5(June 24), and the ‘click:true’ will cause the click event fire twice in chrome(pc) and android.
        My scenario is to click a button and hide the parent div and then show another one, in chrome, the second click event is fired on the same element(the button), but in android, the second click is fired on the after showed div and whatever in the position where the click happened will pick up the event.
        if I made ‘click:false’, then items could not be clicked in ios, but no problem in chrome and android.
        There’s no such issue with V4 since it has no click option, but clicking things inside a iscroll div is definitely a desired feature.
        BTW, Will v5 have a feature that enables long touching to enter selecting mode(select text or pics) on mobile browsers? And last not the least, thanks very much for your hard work on this great project.

      1. I am working with IScroll v5.0.4 and I am seeing the click event being raised twice when using both the following options:

        click: true,
        preventDefault: false,

        This is the case for Firefox, Chrome and Safari when testing on a desktop.

  5. I see that the demos doesn’t have i4’s pull-down-fresh ,can I do it use I5?

  6. Really extraordinary job, thank a lot !
    I’ve tried on different devices, it works as expected on iOS/Android but not on a Nokia Lumia with Windows Phone 7 OS. Is it a known “issue” ?

      1. How does the HW limit that ? Are there any ways around that or windows users just get a non-functioning site ?

    1. You can just user the default overflow:scroll CSS property. For me it works just great, you get inertia, but no bounce.

  7. Hello Matt, it’s me again, i have a suggest (im french, sry for my bad english).

    Like iscroll4 your script handle ‘orientationchange’ and ‘resize’ event to auto-refresh height, width, position, etc…

    Please, could you add option to let choose to activate this or not ?

    I explain why :

    Sometimes, me too in my script for mobile device i have a function who is triggered on ‘orientationchange’ and ‘resize’ event. In this function i could resize the width and height of some elements inside a scroller build with iscroll.
    I think you know what’s the problem. With no option, i have to call again iscroll.refresh() and iscroll.resetPosition() with a good delay to don’t break your own auto-refresh.

    Thanks for your read. I hope you can understood my problem.

  8. Great work!

    One question, however. Should there be a scrollbar? I don’t see one on my iPhone 5 with iOS 6.1.4.

      1. Hi Matteo,

        will you implement the “hideScrollbar” option? As far as I see, at the moment the “scrollbars” option toggles the bars on/off?

        Ciao jo

  9. Your work is awesome!

    Dide you fixed the automatic refresh upon DOM change to? That would be awesommer!

  10. I think that , in prototype._move :
    if ( timestamp – this.startTime > 300 ) {
    this.startTime = timestamp;
    // ….
    then in prototype._end :
    duration = utils.getTime() – this.startTime,

    If in the last touchpoint, _move record the
    time ,save to this.startTime, and at the
    same time , _end was triggered, duration will be zero , right? I’m not sure.

    I have set the duration to 0 manually, it
    dosen’t cause program error , one because
    JavaScript allow the denominator was 0, one
    because in me.momentum() , code checked the
    lowerMargin, even so , the momentum disappeared, although little probability of.

  11. Hi,

    Looks great! How far are you from the first non-beta version? days? months?

    thanks for the good work!

  12. WOW, that’s awesome! Can’t wait for a pull to refresh and infinite scrolling features!

  13. Matteo, I ran across your amazing work after looking for a lightweight scrolling solution for an android app. I’m going to make use of this right away.

    I tried all the demos above on a nexus 7 tablet. They all work as expected. One observation though, which is a little tricky to explain:

    When I drag at speed an let go to allow the scrolling it appears to work OK. When I’m scrolling more slowly and then let go, unless I’m really careful it seems to ‘flick’the scrolling to be faster than I was going previously. I’m guessing that in the process of removing my finger from the screen I am causing a quick flick that accelerates the scroll at the very last moment. It just seems too sensitive and spoils the effect.

    Is there a way to reduce this? For example, to add more inertia after a scroll is underway, or to reduce the acceleration from any actions in the last 50ms of a scroll?

    I know this sounds like a huge request, it would for me make the actions feel more natural.

    Happy to help with testing, or maybe even some debugging.

    Sorry I couldn’t respond on github. It seems to be down.

    Again, thanks for the great product!


    1. thanks for your feedback. Making the scroller feel more natural is at my top priority so I’m definitely interested in exploring this deeper.

      This would be a trial and error effort, though and –most notably– device dependent. I tried it on a Galaxy S2 and I can’t seem to be able to replicate the issue. Would you post a video somewhere?

      Maybe I could try to ignore very hysteric flicks and/or slowing down momentum a bit.

  14. Hi Matteo,

    I used to be working with onBeforeScrollStart, can I still use that? I tried on(‘beforeScrollStart’) but it didn’t work.

    Also, it would help me very much if you could specify the snap offset to the snap container (i use this now, see the +30 i added):

    x = Math.max(-el[i].offsetLeft+30, this.maxScrollX);

    Overall very good performance increase! Thanks!

    1. the snap threshold can be a float (up to 0.5) and it will be parsed as % of the snap container size. Eg: 0.3 will be 30% the size of the snap width/height.

      It can also be expressed in pixels. For that you can pass an integer.

      1. I don’t mean threshold but i meant offset to the container. I don’t want it to snap to the container, but to snap 30px right of the container, that’s what I changed in the js file.

        Would it be possible to add an option for that?

  15. Hi Matteo,

    I noticed the snap function is now a boolean, where version 4 was called with the element, like: snap: '.box' – is there a native way to attach a function or call an element to snap?

    Great work by the way,

      1. No worries, thanks for your help. I don’t know if it’s of any use to you, but I hack this version (and iScroll 4) so that it adds a ‘scrolling’ class when in motion. That way I can use this to detect whether or not the user intended to click, or drag the slider:

        var moving = false;
        .click(function(event) {
        if (!moving), key);
        moving = false;
        // Prevent click event
        if (event.preventDefault) { event.preventDefault(); } else { event.returnValue = false; }
        .mousedown(function() {
        $(window).mousemove(function() {
        if($(base.myScroll.scroller).hasClass("scrolling")) moving = true;
        else moving = false;

        Again don’t know if it’s any use to you but found it to be useful when I’m cramming the slider full of clickable content!

  16. Hello. First I thank you for this excellent work.
    Previously used iScroll 4 and had a problem with the slowness of this, I saw that in the introduction you say you fixed that problem, perfect.
    How I can place a “select” on the charts with checkDOMChanges?

    Thank you very much

  17. I set the useTransition to false, left and right sliding relatively smooth, but did not perform the sliding end of the function ‘scrollEnd’

  18. Hi,

    Is it possible to use 2 scrollbars in the same page?
    I would like to create a Master/Detail page like in the iPad, where Master and Detail are scrollable independently.
    For each Master and Detail, I have an header and footer fixed.
    If anyone knows how to do….


  19. This is awesome! Thank you so much. I was wondering if there was a way of programmatically controlling the carousel? I was hoping to build a carousel that moved forward at an interval but still let the user scrub if desired.

  20. IScroll 5 is awesome! Well done Matteo…
    I have 2 requests/considerations, if they are in there I apologize, I haven’t had time to really take a dive into the script.
    1) Making the scrollbar draggable. I believe someone made a revision to iScroll 4 to make this happen.
    2) Creating a listener to retrieve the Scroll X & Y values. This could really help with retrieving values when parallax’n & other scroll based trickery.

    Keep up the good work!

  21. Hi Mateo,
    This is the first time I’ve tried iScroll, but I hope it works out for me :).

    I have 2 questions though:
    1. Are you going to expose wheelDeltaX and Y to the options object ? It would be nice to have control over it ( 10 is a bit too low for me I think ). I’ve currently edited the source, which is less than ideal.

    2. ( haven’t found this yet, browsing through the source ) is there somewhere I can listen for scroll event through the plugin ( getting the current position from the top ? )


      1. Hey Matteo,

        I’ve been using iScroll since v4 and the click wheel being slow is the reason I only apply iScroll on touch-enabled devices. I would prefer to use iScroll no matter what.

        I haven’t looked into the source but if DeltaX/Y defaults to 10, as Norris says, can I suggest changing it to 30 as is the native default in most browsers/OSs.

        Can I also suggest that transitions be applied to click wheel scrolling (and IScroll5’s key-binding scrolling). This would mimic ‘smooth-scrolling’ which you can set in Chrome/Firefox settings.

        I also noticed in the scrollbars demo that the scrollbar no longer adjusts in size – akin to setting fixedScrollbars=true in iScroll4. And can the scrollbars be hidden? Like with hideScrollbar and fadeScrollbar in v4.

        Love the entire project. Well done for creating such a flexible solution to the problem!


  22. I have a feature request. I know iOS 7 and Mavericks added position:sticky;. Could you possibly make a feature to have fixed position and sticky position for iScroll? It’s nice. I would love to have that inside the iScroll wrapper because the way I do it is too much hacking.

  23. I’ve noticed you can turn momentum scroll on/off.

    Is there any way it can be set on only for one axis in iScroll 5?

    thanks –

  24. Forgot to mention, maybe this could be added without changing the API, by allowing an optional object parm, like below:

    options.momentum = true;
    options.momentum = false;
    options.momentum = { x : false, y : true };

  25. Passo solo per dirti che come al solito il tuo lavoro e’ fonte di ispirazione continua. Se mi sistemo col lavoro salto dentro al beta testing.

  26. Nice work!! I LOVE it

    Daniel, you might get a position:sticky; if you use the Real time position probing to be = or < to the position of the element. Then, switch to position:fixed: + top: this actual position.

    Could be an iScroll plugin actually. Not sure the core code needs that btw

  27. Hi Mat,

    We used the events onScrollMove and onBeforeScrollStart previously, but we can’t get these to fire with v5. We’ve tried myScroll.on(‘scrollMove’, function () {}) etc.
    We can get onScrollEnd to fire as myScroll.on(‘scrollEnd’, function () {}).

    Is there anything we are missing or do these events not work with the present release?


    1. here’s my solution: line
      /* REPLACE END: _move */ i guess 478 or so


      then call

      myScroll.on(‘scrollMove’, function () {}).


  28. I noticed that in scrollToElement the time will always be computed even if time is passed to the function.

    This doesn’t really work:

    time = time === undefined || null || ‘auto’ ? Math.max(Math.abs(pos.left)*2, Math.abs(*2) : time;

    Also when scrolling from the last element to the first element the time will always be 0, so no scrolling happens. Shouldn’t this include a offset from where it is currently instead of taking the position of the first element which always will be 0?

    Thanks for your great work.

  29. I really want to compliment you Matteo, your work is always an inspiration to me and makes life easier, not a little.
    I am very proud of the fact that in Italy there are JS Ninja on your level, I hope to join you soon 🙂

  30. Sometimes, when scrolling a fair distance (typically to the left, in my horizontal scroller), I get a JS exception:

    TypeError: 'undefined' is not an object (evaluating 'this.pages[i].length') iscroll5.js:1100

    I can see that it is trying to compute the page offset for the scroll, but I think the index is out of range. I’ve tried fixing it, but attempts broke other well-working scrolling parts. Any ideas? Thanks in advance for such a well working (even on Android 4.1) scroller!

  31. I have a ten images and i am using iscroll to scroll them. Sometimes the snap skips some img elements and I am not sure why this is happening. Here is the snippet of the code I have used.

    var myScroll;

    function loaded () {
    myScroll = new IScroll('#wrapper', {
    scrollX: true,
    scrollY: false,
    momentum: false,
    snapSpeed: 400,
    keyBindings: true


    document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);

  32. Thank you so much.
    I have problem with long forms on iPhone. I have rec video here
    When I use KeyboardFormAccessoryBar and go to the bottom document. #scroller go to top -> -50% ?
    Have you ever encountered this problem ?

    1. Check the container elements if there is $(el).scrollTop()!=0 && $(el).css(“overflow”)==”hidden” ,and then $(el).scrollTop(0) after losing focus, hope it will help.

  33. I would also suggest to add an option snapSpeed
    so we can set the speed oh the slide when the finger is released, i guess now is 200ms, but it can bee too fast for somebody

  34. Hey Matteo! Great job!

    I’ve run into an issue when trying to init a new IScroll object on an empty wrapper (I want to init it at app load time, then fill it with data dynamically and refresh it). Init maxes a call to refresh, which in turn makes a call to goToPage with x=0, y=0. this.pages is currently empty, so the line marked below errors. Incidentally, after the “x block” for the case where x = 0, it gets set to -1 (not sure if this is intended).

    goToPage: function (x, y, time, easing) {
    easing = easing || this.options.bounceEasing;

    if ( x >= this.pages.length ) {
    x = this.pages.length – 1;
    } else if ( x if ( y >= this.pages[0].length ) { //this.pages[0] === undefined
    y = this.pages[0].length – 1;
    } else if ( y < 0 ) {
    y = 0;

  35. Hi Matteo,
    Also it looks like if you specify a snap selector, the list of pages only gets updated the first time.
    In _initSnap() you have the following:

    if ( typeof this.options.snap == 'string' ) {
    this.options.snap = this.scroller.querySelectorAll(this.options.snap);

    When I try to refresh the scroller after adding more data to it, it doesn’t update the pages list and refuses to snap to it (because this.options.snap is no longer a string). I’d suggest preserving the user option and storing the pages elsewhere; seems a bit odd to overwrite a user-specified option directly.

  36. Great work Matteo.

    I am trying to use iscroll to replace the need for photoswipe on my webapp, by making a horizontal image scroller with zoom. Is there a way to prevent scrolling when zoomed? Was wondering if maybe I need some kind of on.(‘scrollStart’) function.

    Any ideas would be much appreciated!

  37. I have two split columns (like the twitter ipad app) and the scroll works great on the iphone/ipad; however, the items that are within the column have a click event which fires correctly on the desktop, but not on the ipad/iphone. the .click function isnt triggered and if i try to bind touchstart it obviously breaks the scrolling. Demo is on the target is really mobile devices rather than desktop so its more important that i get it working on those 🙂 not sure if its a bug or an incorrect implementation….

  38. Hello, I am trying to use the scrollbar with ajax page loading, but I’ve run in strange issues: the scrollbar starts normally, you click on the first link with ajax, and it works too, but if you click the third time it does not work anymore, after pressing F5 it works.

    This is what I’ve done:

    var contentScroll;

    function loadScrollbars () {
    contentScroll = new IScroll('#contentScroll', {
    scrollX: false,
    scrollY: true,
    momentum: false,
    snap: true,
    scrollbars: true,
    mouseWheel: true,
    checkDOMChanges: true,
    interactiveScrollbars: true


    $(document).ajaxComplete(function() {

    Don’t know what exactly should I do, please help.

  39. Genuis.

    Think of an inverted vertical infinite scroll, like twitter, which allows the top and bottom add items, not found one that works well.

  40. 1. I wanna use vertical scroll inside carousel in iscroll
    2. And Wanna use pull-to-refresh inside carousel in iscroll

    please give me some examples…

  41. maybe you already noticed but method “scrollToElement” and “scrollTo” don’t not set the this.currentPage

    that means eg. if you init iScroll5 and then use scrollToElement method the currentPage is still actually 0,0 causing a bug

  42. Hi, is there still a way of styling the scrollbar (and having it visible)? I notice the scrollbarClass option is gone. I see a but I can’t figure out what to do with it. I’m not seeing any documentation on this. I’d be grateful for any pointers in the right direction.

  43. Hello.

    In version 4, the problem with FORM, was resolved in the onBeforeScrollStart event . How does the 5?

    Thanks and great job!

    1. Hi, again.

      I made a small modification to support the Form fields. In both occurrences of _start, I included the following code:

      var target =;
      if (target.nodeName) {
      if (target.nodeName == ‘SELECT’ | | target.nodeName == ‘INPUT’ | | target.nodeName == ‘TEXTAREA’) return;

      Perhaps it would be good to have a choice of plug-in to show the tags to exclude.

      Another problem that came up is the scroll in two directions -horizontally and vertically- when using the mouse wheel. An option to block x or y I think would be appropriate.

      These are just my humble opinions.


  44. Hi Matteo,

    I am currently using iscroll v4. But I’ve got an issue with using iscroll on page having form elements. It has a very weird behavior. The form is jumping in and out. Does this issue already been solved in v5?

    Great work though. Thanks

  45. How can i use IScroll with requirejs and backbone? anyone can help with this pls….

  46. First of all: great job! I’m using v5 in our jQM 1.3.2 project for a right hand panel with responsive design; works wonderful!

    I just miss one behaviour I appreciated in v4, i.e. the scrollbar shrinking when scrollin “over the top/bottom”.
    1) is it possible in v5?
    2) is it possible to let the scrollbars disappear when finished scrolling and let it appear when start scrolling?

    Thanks for sharing your work with us ;>

  47. Hi Matteo,

    Is there any way of setting eventPassthrough or scrollX / scrollY to false on an initialized instance of the iScroll object, rather than having to re-init the object? I ask because I want to open a large content block inside the iScroll element (which pushes other content to new X/Y positions) and I don’t want to reset the pages array…


  48. Hi Matteo
    Just wanted to know whether iscroll works on Windows phones and tablets.

  49. Hi! What is the status about the current beta? is it still beta 1? what are the plans for a stable release?

  50. I am building a what’s on in my local area app and Its pretty much done apart from a little buggy thing to do with the horizontal scoll I’ve implimented using Iscroll5.

    I have several horizontal iscroll bars on a page and they work great until I try to scroll the page up and down on touch screen.

    If I try to scroll up and down when my finger is on an Iscroll section it will only go left and right.

    Any ideas of how I can scroll up and down as well as right and left when on an Iscroll element.

    the effect I’m going for can be seen in the BBC news App.

  51. i want to use snap: true on infinite horizontal scroll and different row height on vertical. Is it possible on IScroll 5?

  52. Hi,
    I have a form running Iscroll5 but it seems that when a user touch input or textarea field it doens’t scroll.
    I need to set this working so the user doesn’t get stucked when trying to fill the form on mobile.

    Where is my code:
    _this.scroller = new IScroll(_this.scrollWrapper[0], {
    mouseWheel: true,
    className: /(^|\s)default-btn|multiselect-header|btn-icon|label|submit-icon(\s|$)/

    A example of my form:

    I disable preventdefault on input and textarea but it doesn’t let me fill the form then.

Comments are closed.