Need help with jquery-mobile-iscrollview?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

412 Stars 193 Forks 286 Commits 71 Opened issues


JQuery Mobile widget plug-in for easy use of the iScroll javascript scroller.

Services available


Need anything else?

Contributors list

watusi/jquery-mobile-iscrollview, Version 1.3.6

JQuery Mobile widget plug-in for easy use of the iScroll scroller in JQuery Mobile projects.

iScroll is a javascript that can scroll content in a window within a web browser with very similar behaviour to native scrolling on mobile devices such as iPhone and Android. This means you can scroll a window within the browser using native-like scrollbars and physics. adapts the iScroll javascript to the jQuery Mobile environment.

It is an implementation of a JQuery Widget Factory widget. It follows the widget-factory-mobile Widget Factory Pattern.

Release Notes

Please see releaseNotes.txt for information on changes in this and prior releases.

iScroll Version 4.2.5

This widget is not yet compatible with iScroll version 4.2.1 through 4.2.5. Please stick with iScroll 4.2 for now. Some investigation and testing is needed due to changes in iScroll event code.

Also, iScroll 4.2.1 introduced and change that may not be desirable. Scrolling continues when your finger leaves the wrapper. While this is a nice feature for small scrollers, this is not always desirable. It is very odd on desktop browsers, as scroll continues when you drag with the mouse, even outside of the browser! It should be optional. (It will be in iScroll5).


1.4 - Fully implement usejQueryEvents

? - Option to un-enhance widget temporarily (and optionally hide headers/footers) during virtual-keyboard input on select devices (iOS first), to eliminate all form input problems when using a virtual keyboard.

? iOS keyboard handing for inputs. Guess keyboard height based on device/orientation/fullscreen. Resize wrapper to fit page in space above keyboard, center focused element.

? - Better support for collapsible content (scroll on expand if expanded content below window)

Plug for

This plugin works best when used with

It puts back the old, simultaneous, non-scrolling transitions that everybody knew and loved from jQuery Mobile 1.0. It's an ideal companion for! Stop fighting the goofy transitions in jQuery Mobile 1.1. If you're using iScroll, you probably don't need them.

What This is For

This widget is intended for use in any jQuery Mobile project, but it was designed to be especially useful for some specific uses.

First and foremost are native mobile applications that use HTML/CSS/Javascript in a webview for their user interface. It is especially desirable that such applications reproduce a "native" look and feel. A native look and feel is impossible to achieve without an embeddable scroller with native-like physics and scrollbar action.

While iScroll4 is useful to help achieve this goal, it is difficult to use along with jQuery Mobile. It is not an easy task to integrate iScroll4 with jQuery Mobile - at least not correctly and efficiently.

My intention is that this widget will handle 80% of use cases with very minimal effort.

The most common need for iScroll in jQuery Mobile projects is to have a fixed header and footer with a single vertically-scrollable area in-between.

This can be accomplished by simply including the required files in the

 and adding a
attribute to your content

If you need to do something different than this, this widget will probably work for you, but you will probably have to set some options and dig into the documentation a bit.

Because the primary target for this widget is native mobile applications, it has a large number of configurable options, which may be usable only in certain target environments. I want you to be able to tailor the widget to your specific needs when you are using it in specific, known environments.

Secondarily, it is intended to support websites that will be viewed on mobile browsers, and "full-screen" websites and "web apps" for mobile devices (i.e. "Add to Home Screen" in Mobile Safari).

Finally, it supports desktop browsers, and is regularly tested using current versions of FireFox, Safari, Chrome, and Opera. It generally works well in these browsers, and fortunately hasn't needed a lot of work to acheive compatability.

This widget is not well-tested on Android devices, and I very much appreciate assistance in ferreting-out Android issues. It is tested regularly in all three modes (Mobile Safari, full-screen, and UIWebView) on iPad 1(5.1), iPad 3(5.1), iPhone 4 (4.3.5) and iPhone 4S(5.1).


The most basic usage of this widget is simple: just add a

attribute to a container. All content inside this container will be scrolled.

Note that

itself scrolls only the first child of it's wrapper. However, by default, this plugin automatically creates a protective
around all children of the wrapper, and so unlike iscroll.js it will scroll all of the children of the wrapper element - not just the first.

As well, you may have no content in the wrapper initially. You might do this, for example, if you will be inserting dynamic content later. In this case, the plugin will create an empty

for you.

If, for some reason, you do not want the widget to create this protective container, set the

option to

The widget does not use the typical JQuery Mobile

attribute, because a common use case would be to use a
as the container, and, of course, you can't have two
attributes on the same element.

The widget will (normally) re-size the container to take up all available height within the viewport after fixed headers/footers are taken into account. This behaviour can be disabled using the

option, which should be se
for no more than one widget on a given page.

The widget has been designed to support multiple scrollers on a page - for example, you might want a second, gallery-like horizontal scroller. So, all data related to a scroller is stored in the scroller's container, not the page. Feel free to experiment with multiple scrollers - I just haven't had the need so haven't put the effort into testing and supporting that scenario.

Support for

headers/footers is limited, but improved over previous versions. Since this widget resizes the scroller to fit the page, there is no need for fixed positioning of header/footer. Resizing is fast enough that the footer stays "glued" to the bottom of the page fairly well.

Additional fixed-height elements (which are not headers or footers) outside of the scrolling region should be given the

attribute, if they would add to the height of the page. (Do not add the
attribute to sidebars.)


<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">

<link rel="stylesheet" href="">
<link rel="stylesheet" href="">
<link rel="stylesheet" href="">
<link rel="stylesheet" href="additional-site-specific-styles.css">

<script src="jquery-1.9.1.min.js"></script>
<script src=""></script>
<script src="iscroll.js"></script>
<script src=""></script>
<script src="additional-site-specific-scripts.js"></script>

<div data-role="page" class="index-page">

  <div data-role="header" data-position="fixed" data-tap-toggle="false" data-transition="none" data-id="header">
    <h1>INDEX PAGE</h1>

  <div data-role="content" class="example-wrapper" data-iscroll>
    <p>some content that will be scrolled</p>
    <p>Some more content that will be scrolled</p>
    <ul data-role="listview">
      <li>Item 1</li>
      <li>Item 2</li>
    <p>Even more content. It will scroll whatever is in the data-iscroll div.</p>

  <div data-role="footer" data-position="fixed" data-tap-toggle="false" data-transition="none" data-id="footer">
    <h1>My Footer</h1>


Fixed and persistent Toolbars (Headers/Footers)

This plugin now works fairly well with both fixed and persistent toolbars, as long as you use jQuery Mobile 1.1.1 or later.

Make sure you use

if you don't want goofy disppearing tolbars when the user taps on the toolbar!

Note, however: do not use

for Navbars! This is an apparent bug in jQuery Mobile.

is not possible for NavBars in any case, because the buttons cover the entire toolbar surface. There isn't anywhere for the user to tap-to-toggle.

If you add

to a Navbar, the Navbar will fail to work in certain circumstances when using certain browsers (Mobile Safari/iOS 5.1.1 on iPhone, but not on iPad or iOS 4.3.5). After a window resize (for example, orientation change), the Navbar will become non-responsive if
is present. In this case, just leave this option out completely.

You can also use persistent toolbars. The JQM documentation has in the past been ambiguous as to whether these can be used with toolbars other than Navbars. They can: at least with jQuery Mobile 1.1.1. The demo now uses fixed, persistent toolbars for both header and footer.

To use a persistent toolbar, assign the same

value to the toolbar in each page in which it appears. jQuery Mobile will move the toolbar out of the page temporarily during transitions, so that it will appear fixed. A "none" transition is used to transition the toolbars, so that elements that are positioned in the same place within the toolbar will appear to not change during the transition.

Because the page height is restricted to the viewport height (at least by default) when using this plugin, jQuery Mobile (1.1.1) will not fade the toolbar during transitions.

Bear in mind, though, that the combination of fixed toolbars and a page size that equals the viewport height (the default when using this plugin) may cause unwanted results in some enviroments. In particular, in Mobile Safari, this will cause the browser's navigation bar to show during page transitions. So, fixed toolbars are most appropriate only in a native environment (such as when using a WebView with PhoneGap.)

I am seeking feedback on how well fixed and persistent toolbars work (or don't) in different browsers and environments. So, I have enabled fixed/persistent toolbars in the demo. If this causes issues in your environment, please try with


In the demo, you can use see the difference between how jQuery Mobile 1.0.1 and 1.1.1 handle this. You can see that the header is fixed with 1.1.1 but slides with the page with 1.0.1. JQM tries to keep the footer fixed in 1.0.1 but is not completely successful. You will see that sometimes it stays fixed and sometimes it slides with the page transition. Ths seems related to queued transitions.

Additionally, you may notice that the footer is shown briefly in the wrong position during transitions. If this is a problem in your environment, you can use an inline footer, and the plugin will insure it always appears in the right place. However, you cannot implement a persistent toolbar in JQM 1.1 with an inline footer.

Dynamic Content

If you will be adding dynamic content that you want to have scrolled, you first need to understand the HTML structure that the plugin creates for you.

If you supply initial content, the plugin will create two

s around that content.

The outermost

is called the scroller, and contains everything that will be scrolled by iScroll. It is given a class of

If you supplied pull-down and/or pull-up blocks, they are moved to inside the scroller, after the scroller is created.

An additional

is also added around the scrolled content, sandwiched between the (possibly absent) pull-down and/or pull-up blocks. This
is given a class of
. This contains everthing that the scroller scrolls, other than any pull-down and/or pull-up blocks.

When you add dynamic content, make sure to add it inside the

that has class

What you wrote:


This is some content that I want to scroll

This is some more content

What the plugin produces:


This is some content that I want to scroll

This is some more content


Any time you alter the content of a scroller, in such a way that the dimensions of the scrolled content might be changed, you need to refresh the scroller widget using the



function has optional pre and post-refresh function arguments that can be used to perform some action before and/or after the refresh. For example, you might also refresh some other widget, such as a listview, prior to refreshing the scroller, or you might want to scroll to a particular position after the refresh has been performed. The callbacks are necessary because refresh is not performed immediately, but after a timeout that insures that the DOM has been fully updated with your new content.

Please see the section on the

function for full details.

Alternately, you can trigger an

event on the element whose dimensions you changed. The widget listens for any
events triggered on elements inside a scroller and refreshes automatically.
is triggered by jQuery Mobile on certain jQuery Mobile widgets, such as, for example, collapsibles. So, it is not necessary to call
when collapsibles are expanded or collapsed.

Padding Issues

Previous versions of this widget had some issues involving the way jQuery Mobile standard CSS applies padding and margin to content divs and listviews. The widget now handles this for you in the most common use cases.

By default, the widget removes any padding from your wrapper. It then adds a

inside the scroller, around your content (exclusive of any pull-down/pull-up block) and adds the padding that was removed from the wrapper. This provides correct padding for both normal and inset listviews.

The padding needs to be moved to inside the scroller (and to not include pull-down/pull-up) so that you will not see padding around the scroller itself.

There are two options that allow you to override this default behavior:



This widget supports "pull-to-refresh" functionality. You can have a block of HTML that is positioned above the top or below the bottom of the scroller that the user can pull down or pull up. These blocks can be revealed by scrolling, but the scroller will "snap back" after the user stops scrolling to again hide the block. If the user pulls past this block by a certain amount, (1/2 the height of the pull block) and then releases, some action that you specify will be performed. That action can be anything, but typically will be to perform some AJAX action to retrieve data from a server and refresh or add some content within the scroller.

In order to implement pull-to-refresh, you need to add a small amount of HTML markup to your page and either supply a function as an option value or else (recommended) bind or delegate to a jQuery event callback function.

You also need to include the file
in your
. Finally, this CSS file references an image file that contains an arrow icon and a
spinner icon. You can replace this with your own image file. If you rename or move this file, make
sure to edit the CSS file or override the rule in your own CSS file.

Pull Block

To implement pull-up and/or pull-down, structure your HTML similar to the following:

  • Item 1
  • Item 2

This is all you have to do to implement the pull-up and/or pull-down UI. The widget doesn't create the pull blocks for you, in order to provide you with the flexibility to format them as you please. The pull blocks can contain other elements, and the spans for the icon and/or label can be omitted.

All of the class names used for pull-down and pull-up are configurable in options. The example above uses the default class names.

Pull States

A pull block can be in one of three states:

  • Reset
    This is the initial state of the pull block
  • Pulled
    This is when the bock has been pulled, but not yet released
  • Loading
    This is when the block has been released, and some action is being performed

If the user scrolls back (without lifing) while in the

state, then the block returns to the

If the user pulls past the edge of the pull block (by 1/2 the height of the pull block), then the block will enter the Loading state.

After the action has been performed, and the scroller is refreshed, then the block returns to the


Pull Label Text

The widget has default text values that are inserted into the pull label element when the block enters each state. Each of these text values is a configurable widget option. The applicable options, and their default values are:

  • pullDownResetText
    "Pull down to refresh..."
  • pullDownPulledText
    "Release to refresh..."
  • pullDownLoadingText
  • pullUpResetText
    "Pull up to refresh..."
  • pullUpPulledText
    "Release to refresh..."
  • pullUpLoadingText

To change these options programatically, see the options documentation.

Alternately, you can change the default values in your HTML. When you change the defaults in HTML, it changes the corresponding option value.

To change the

text, simply insert it in the pull block's label

To change the

text, use a

To change the

test, use a


    Pull this here thing down to refresh!

Fancier Pull States

If you want to do something more elaborate when a pull block enters each state, you can either provide a callback option or (recommended) bind or delegate to a jQuery event callback function. The associated events are:

  • iscroll_onpulldownreset
  • iscroll_onpulldownpulled
  • iscroll_onpulldownloading
  • iscroll_onpullupreset
  • iscroll_onpulluppulled
  • iscroll_onpulluploading

Event and Callback Option Functions

In order to implement the pull-down and/or pull-up action, you need to supply a function. You can either supply this function as an option value or (recommended) bind or delegate to a jQuery event callback function.

The example code below is from the demo:

    $(document).delegate("div.pull-demo-page", "pageinit", function(event) {
        $(".iscroll-wrapper", this).bind( {
        "iscroll_onpulldown" : onPullDown,
        "iscroll_onpullup"   : onPullUp


Your callback function receives two parameters:


This is the event object that originally gave rise to the callback. This is probably not very useful to you.


This is map containing one member,

. This is a reference to the iscrollview object that made the callback.

Your callback should take whatever action you want when the user activates the pull-up/pull-down. This might typically involve retrieving some data from a server and inserting it into the scroller content. See the demo for an example.

Calling functions

The standard way of calling widget functions is by passing a sub-function name as a string parameter to the widget function. Any parameters to the function should follow.

Note: This method works for all versions of jQuery Mobile from 1.0 to 1.4.x. See below, though, for differences when using an alternative way of calling fucntions.

For example, to call the


The widget factory allows you to access widget functions directly, by accessing a data variable stored in the widget's element. For jQuery Mobile versions < 1.3:


The Widget Factory changed in jQuery Mobile version 1.3. Starting with this version, you can access this variable like this:


While this is a bit awkward, it is also more conventional. It is handy in case you need to make a series of calls to different widget functions. You can first get the instance into a variable.

    // JQM < 1.3
    var myView = $(".example-wrapper").jqmData("iscrollview");
    // JQM >= 1.3
    var myView = $(".example-wrapper").data("mobileIscrollview");

This means, as well, you can easily call any underlying iScroll function through the exposed

member variable. For example,
    // JQM < 1.3
    // JQM >= 1.3

So, if you replace iscroll.js with a newer version that has new functions, or if you need to call iScroll private functions, or access iScroll member variables, you can call them without any need to modify this widget.

This widget wraps all current iScroll public functions, so the above example can also be called like this:

    $(".example-wrapper").iscrollview("scrollTo", 0, 10, 200, true);

The exceptions are the

, and

is a standard widget factory function. In this widget, it calls the iScroll
function and then calls the base widget destroy. If you need direct access to iScroll's
function, you can access it directly using the
member variable.

The widget's

function insures that the underlying iScroll refresh function is called with the proper timing. If you need to call the iScroll refresh function directly, do so using the
member variable.

are standard widget functions. Each of these calls iScroll's corresponding function and then calls the underlying widget function.


Standard Widget Functions

These are functions that are typically implemented for ALL widgets:

option(key, [valueorobject])

See "Options", below.


Destroys the iScroll instance and removes page modifications. Also calls the underlying widget


Custom Widget Functions

These are additional functions implemented in this widget which do not have corresponding iScroll functions.


This will resize the wrapper to use all available viewport space after accounting for headers, footers, and other fixed-height elements outside of the wrapper. This is normally done for you automatically, but the automatic resize can be overriden with an option. Call this if you have change the page structure and so need to resize the wrapper. This is also normally called for you when page orientation or page size changes.

iScroll Functions

These are functions that exist in iScroll. They are available on the widget as a convenience. See "calling functions" for information on how to access any iScroll functions that are not implemented in the widget. (For example, because you have updated iScroll to a newer version, and this widget has not been updated yet.)

Please see the iScroll documentation for details on using these functions.

refresh(timeout, beforeCallback, afterCallback, noDefer)

Note that this performs the proper timing for the iScroll

function using
. If you want to call the iScroll
function directly, please see "calling functions" above.

If the timeout value is present, then the internal call of iScroll

will be delayed by this value. If the value is
, then the value of the
option will be used.
Refresh Callbacks

If present, the optional

function will be called just prior to refreshing iScroll. This is useful if you have updated content inside the scroller, and need to refresh widgets inside the scroller (such as a listview) prior to iScroll refresh. While this is similar to the
, the callback is specific to a particular call to

If your callback requires some context, you should use jQuery's $.proxy() function to provide a

reference that will be available when the callback executes.

If present, the optional

function will be called just after refreshing iScroll. This is useful if you want to perform some action on the scroller after updating content. For example, this might be used to scroll to a particular position or element within the scroller after updating content. This is particularly useful when adding content to the end of the scroller, when you might like to scroll the new content into view.
Deferred Refresh

Calls made to

for an iscrollview which is on a cached page that is not the active page are normally (depending on the value of the
option) deferred until the next
event for the page. This avoids unnecessary refreshes. Note that if the
option is true, then the scroller will always be refreshed on

Each deferred call to

overwrites the callback values from any previous deferred
call for the same iscrollview. This means that you should not use refresh callbacks to modify content, because there is no guarantee that any particular callback will be called - only that the callbacks for the last deferred
will be called.

Deferred calls only occur when the scroller being refreshed is not the active page. You might do this if you are caching pages, and some data arrives that you want to update on a page that is not currently the active page.

This is particularly useful in environments such as PhoneGap, Titanium, or Rhodes, where a controller is able to update pages asynchronously.


calls avoids a cascade of unnecessary refreshes when the document is resized in a desktop environment, or when a mobile device's orientation is changed. The refreshes for those pages that are cached in the DOM but not the active page are deferred until the next time they become the active page, and then only a single refresh will be performed.

As well, if content is updated while a page is not the active page, then deferring

avoids unnecessary duplicate refreshes. If content were to be updated several times while the page is not active, only a single refresh will be performed.
NoDefer Argument

If you want to force a refresh to a scroller on a non-active page to be performed immediately, you can set the

parameter to
. Note that the
parameter is intended for the widget's internal use, and you should not normally set it to
. You should normally just leave this parameter out of your call.

You can disable deferred refreshes completely by setting the

widget option to

scrollTo(x, y, time, relative)

Scroll to a particular

pixel position within the scroller.


parameter is the time in milliseconds over which to perform a smooth scroll. If omitted, the scroll is immediate.


parameter is
, then the
position is relative to the current scroll position.

scrollToElement(el, time)

Scroll to a particular element within the scroller. The

parameter can be either a reference to a DOM node object (not a jQuery object) or a CSS3 selector. jQuery selector extensions cannot be used here.


parameter is the time in milliseconds over which to perform a smooth scroll. If omitted, the default iScroll
time value is used. This is based on larger of x and x pixels scrolled, times 2. For example, if it will scroll 500px vertically (and less than 500px horizontally), then the scroll will take place over a period of 1000mSec.

scrollToPage(pageX, pageY, time)

The default time value, if not specified, is 400mSec. (Default iScroll.js value)


Note that this function also calls the default widget


Note: This has not been tested, and probably doesn't work correctly. Further, the iscroll-internal

probably doesn't do what you wish it would do. You can't re-enable iScroll by calling
after calling

If you do want to call the iScroll

function directly, please see "calling functions" above.


Note that this function also calls the default widget

function. If you want to call the iScroll
function directly, please see "calling functions" above.


zoom(x, y, scale, time)

The default time value, if not specified, is 200mSec (Default iScroll.js value)

iScroll Getters

This widget provides getters for some iScroll internal variables that might be useful to an application. These are all read-only.

For example, let's say you are adding elements to the end of a scrolled list. You'd like to scroll up (using scrollToElement) if the new element would be below the visible area. But if the list is intially empty, you'd want to avoid this until the scrolling area is initially full. So you need to compare the scroller height (scrollerH) to the wrapper height (wrapperH).

While wrapper and scroller height can be easily obtained using JQuery functions, these functions can still be useful because they reflect the precise internal state of the scroller.


Current x origin (left) of the scroller.


Current y origin top of the scroller.


The width, in pixels, of the wrapper. This is the visible width of the scrolling area.


The height, in pixels, of the wrapper. This is the visible height of the scrolling area.


The width, in pixels, of the scroller. This is the total width of the scroller, including visible and non-visible portions.


The height, in pixels, of the scroller. This is the total height of the scroller, including visible and non-visible portions.

iScroll Getters/Setters

This widget provides getters with options setter functionality for some iScroll internal variables that might be useful to an application. If a value is provided, then the functions act as setters. In any case, they return the value of the associated internal variable.


The minimum X scroll position. This defines the left-most position of scroll. The user can scroll past the minimum X, but then the scroller will snap-back to the mimimum X position.


The minimum Y scroll position. This defines the top-most position of the scroll. The user can scroll past the minimum Y, but then the scroller will snap-back to the minimum Y position.


The maximum X scroll position. This defines the right-most position of scroll. The user can scroll past the maximum X, but then the scroller will snap-back to the maximum X position.


The maximum Y scroll position. This defines the bottom-most position of the scroll. The user can drag past the maximum Y, but then the scroller will snap-back to the maximum Y position.

Public Members

The widget maintains several public data members that may be useful to you:


This is a reference the iScroll object.


A jQuery collection object containing the window (viewport).


A jQuery collection object containing the iscrollview wrapper element.


A jQuery collection object containing the scroller element.


a jQuery collection object containing the scroller content element.


a jQuery collection object containing any pull-down element. If there is no pull-down element, then the length of the collection will be zero.


A jQuery collection object containing any pull-up element. If there is no pull-up element, then the length of the collection will be zero.


A jQuery collection object containing the page that the widget is contained in.


Overriding Option Defaults

You can override the default options for new instances of this widget by setting the prototype options in


Any options that you set programatically or using

attributes will override the defaults.

Example: for all new instances of

, set the
option to the value
$.mobile.iscrollview.prototype.options.refreshDelay = 100;

If you want to override options for all instances of the widget, a good place to do that is at the same time that you override any jQuery Mobile default options.
triggers an
event that is triggered once it has loaded, and you may set any global options here.

Note that when

is triggered, this does not mean that any scroller(s) have been initialized. It only means that the iscrollview library is loaded, and so you may now set any global options.

It's common to bind to

after jQuery is loaded, but before loading jQuery Mobile. You can bind to
in the same place. Alternately, you can make changes to global options any time after
is loaded.


is ONLY available as a jQuery Event. There is no corresponding iscrollview callback function.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.