jQuery Mobile's widget and navigation system has a full set of events at each stage of the page load and page change process that can be tapped into to take full control. This page will highlight the most commonly used events and what they do, and also provide chronologies of when these events are triggered during load and transitions.
When jQuery Mobile initializes, it triggers an event on the document
that is specifically designed for overriding framework and plugin defaults. That event is called mobileinit
, and by binding to it, you can ensure that any global or plugin configuration options are overridden to any value you'd like before they are used by the framework's initial execution.
$(document).bind("mobileinit", function(){
//apply overrides here
});
The tricky aspect of mobileinit is that you need to bind to it before jQuery Mobile executes, so a typical mobileinit workflow would occur in a script that is referenced after jQuery itself, but before jQuery Mobile.
It should be noted that while you can bind to other events from within a mobileinit
callback, it is likely that you'll get undesirable results in doing so. This is because many events, such as the page events below, are intended for external developers to use after jQuery Mobile's plugins have loaded.
In a jQuery Mobile application, each view is known as a page. Pages generally begin as a regular HTML element with a data-role="page"
attribute, and the framework's page widget enhances that element into a jQuery Mobile page control. In the process of enhancing that page, the widget dispatches several events that allow you to access that page and its child elements at different stages of creation.
These events are:
pagecreate
is the most useful event for progressively enhancing a page's markup when it first loads, and because of this, many of jQuery Mobile's standard widgets bind to pagecreate
to enhance markup within pages as well! If you bind to pagecreate
in any script that is referenced after the jQuery Mobile framework, any native jQuery Mobile widgets in that page will be enhanced before your event callback executes. In other words, you'll be dealing with enhanced jQuery Mobile components.pagecreate
event generally allows you to work with a page after its markup has been enhanced by jQuery Mobile, pagebeforecreate
gives you access when the markup has not yet been enhanced. pagebeforecreate
is useful for modifying markup before jQuery Mobile's widgets pageinit
is very similar to pagecreate
, except that none of jQuery Mobile's standard widgets bind to it, and it is guaranteed to execute after all bound pagecreate
callbacks have finished. If you need to bind to a page creation-time event via a script that is referenced before jQuery Mobile, binding to pageinit
will ensure that you deal with enhanced page controls (whereas pagecreate
will not, in that specific case.)After pages are created, they are often shown and hidden one or many times throughout the use of a jQuery Mobile app. For A-grade browsers with Ajax navigation support, the jQM navigation model manages these page behaviors and dispatches useful events at different steps in the process of showing, hiding, and changing.
The page showing events (pagebeforeshow
and pageshow
) are guaranteed to fire every time a page is shown, whether you're opening a single page, or transitioning between two pages. The target of the event is the page that is being shown.
The page hiding events (pagebeforehide
and pagehide
) only fire when transitioning between two pages, when an outgoing page is being hidden in favor of a new one. The target of the event is the page that is being shown.
When a single page is being shown, and no page is hidden, only the pagebeforeshow
and pageshow
events will fire, and in that order.
During a transition between two pages, all 4 of the events above will fire, in this order:
Here is an overview of the event chronology for a page change
You can bind to these events like you would with other jQuery events, using live()
or bind()
.
pageInit()
, not $(document).ready()
The first thing you learn in jQuery is to call code inside the $(document).ready()
function so everything will execute as soon as the DOM is loaded. However, in jQuery Mobile, Ajax is used to load the contents of each page into the DOM as you navigate, and the DOM ready handler only executes for the first page. To execute code whenever a new page is loaded and created, you can bind to the pageinit
event. This event is explained in detail at the bottom of this page.
pageCreate()
vs pageInit()
Prior to Beta 2 the recommendation to users wishing to manipulate jQuery Mobile enhanced page and child widget markup was to bind to the pagecreate
event. In Beta 2 an internal change was made to decouple each of the widgets by binding to the pagecreate
event in place of direct calls to the widget methods. As a result, users binding to the pagecreate
from within mobileinit
would find their binding executing before the markup had been enhanced by each of the plugins. In keeping with the lifecycle of the jQuery UI Widget Factory, the initialization method is invoked after the create method, so the pageinit
event provides the correct timing for post enhancement manipulation of the DOM and/or Javascript objects.
Whenever an external page is loaded into the application DOM, 2 events are fired. The first is pagebeforeload
. The 2nd event will be either pageload
or pageloadfailed
.
pagebeforeload
Triggered before any load request is made. Callbacks bound to this event can call preventDefault()
on the event to indicate that they are handling the load request. Callbacks that do this *MUST* make sure they call resolve()
or reject()
on the deferred object reference contained in the data object passed to the callback.
The data object, passed as the 2nd arg to the callback function contains the following properties:
url
(string)
absUrl
(string)
dataUrl
(string)
deferred
(object)
$( document ).bind( "pagebeforeload", function( event, data ){
// Let the framework know we're going to handle the load.
event.preventDefault();
// ... load the document then insert it into the DOM ...
// at some point, either in this callback, or through
// some other async means, call resolve, passing in
// the following args, plus a jQuery collection object
// containing the DOM element for the page.
data.deferred.resolve( data.absUrl, data.options, page );
});
or rejected like this:
$( document ).bind( "pagebeforeload", function( event, data ){
// Let the framework know we're going to handle the load.
event.preventDefault();
// ... load the document then insert it into the DOM ...
// at some point, if the load fails, either in this
// callback, or through some other async means, call
// reject like this:
data.deferred.reject( data.absUrl, data.options );
});
options
(object)
pageload
url
(string)
absUrl
(string)
dataUrl
(string)
options
(object)
xhr
(object)
textStatus
(null or string)
pageloadfailed
The data object, passed as the 2nd arg to the callback function contains the following properties:
url
(string)
absUrl
(string)
dataUrl
(string)
deferred
(object)
$( document ).bind( "pageloadfailed", function( event, data ){
// Let the framework know we're going to handle things.
event.preventDefault();
// ... attempt to load some other page ...
// at some point, either in this callback, or through
// some other async means, call resolve, passing in
// the following args, plus a jQuery collection object
// containing the DOM element for the page.
data.deferred.resolve( data.absUrl, data.options, page );
});
or rejected like this:
$( document ).bind( "pageloadfailed", function( event, data ){
// Let the framework know we're going to handle things.
event.preventDefault();
// ... attempt to load some other page ...
// at some point, if the load fails, either in this
// callback, or through some other async means, call
// reject like this:
data.deferred.reject( data.absUrl, data.options );
});
options
(object)
xhr
(object)
textStatus
(null or string)
errorThrown
(null, string, object)
Navigating between pages in the application is usually accomplished through a call to $.mobile.changePage()
. This function is responsible for making sure that the page we are navigating to is loaded and inserted into the DOM, and then kicking off the transition animations between the current active page, and the page the caller wants to to make active. During this process, which is usually asynchronous, changePage() will fire off 2 events. The first is pagebeforechange
. The second event depends on the success or failure of the change request. It will either be pagechange
or pagechangefailed
.
pagebeforechange
toPage
(object or string)
options
(object)
It should be noted that callbacks can modify both the toPage
and options
properties to alter the behavior of the current changePage()
call. So for example, the toPage
can be mapped to a different url from within a callback to do a sort of redirect.
pagechange
changePage()
request has finished loading the page into the DOM and all page transition animations have completed. Note that any pageshow or pagehide events will have fired *BEFORE* this event is triggered. Callbacks for this particular event will be passed a data object as the 2nd arg. The properties for this object are as follows:
toPage
(object or string)
options
(object)
pagechangefailed
changePage()
request fails to load the page. Callbacks for this particular event will be passed a data object as the 2nd arg. The properties for this object are as follows:
toPage
(object or string)
options
(object)
Page transitions are used to animate the change from the current active page (fromPage) to a new page (toPage). Events are triggered before and after these transitions so that observers can be notified whenever pages are shown or hidden. The events triggered are as follows:
pagebeforeshow
prevPage
(object)
pagebeforehide
nextPage
(object)
Note that this event will not be dispatched during the transition of the first page at application startup since there is no previously active page.
pageshow
prevPage
(object)
pagehide
nextPage
(object)
Note that this event will not be dispatched during the transition of the first page at application startup since there is no previously active page.
You can access the prevPage
or nextPage
properties via the second argument of a bound callback function. For example:
$( 'div' ).live( 'pageshow',function(event, ui){
alert( 'This page was just hidden: '+ ui.prevPage);
});
$( 'div' ).live( 'pagehide',function(event, ui){
alert( 'This page was just shown: '+ ui.nextPage);
});
Also, for these handlers to be invoked during the initial page load, you must bind them before jQuery Mobile executes. This can be done in the mobileinit
handler, as described on the global config page.
Internally, jQuery Mobile auto-initializes plugins based on the markup conventions found in a given "page". For example, an input
element with a type
of range
will automatically generate a custom slider control.
This auto-initialization is controlled by the "page" plugin, which dispatches events before and after it executes, allowing you to manipulate a page either pre-or-post initialization, or even provide your own intialization behavior and prevent the auto-initializations from occuring. Note that these events will only fire once per "page", as opposed to the show/hide events, which fire every time a page is shown and hidden.
pagebeforecreate
Triggered on the page being initialized, before most plugin auto-initialization occurs.
$( '#aboutPage' ).live( 'pagebeforecreate',function(event){
alert( 'This page was just inserted into the dom!' );
});
Note that by binding to pagebeforecreate
, you can manipulate markup before jQuery Mobile's default widgets are auto-initialized. For example, say you want to add data-attributes via JavaScript instead of in the HTML source, this is the event you'd use.
$( '#aboutPage' ).live( 'pagebeforecreate',function(event){
// manipulate this page before its widgets are auto-initialized
});
pagecreate
Triggered when the page has been created in the DOM (via ajax or other) but before all widgets have had an opportunity to enhance the contained markup. This event is most useful for user's wishing to create their own custom widgets for child markup enhancement as the jquery mobile widgets do.
$( '#aboutPage' ).live( 'pagecreate',function(event){
( ":jqmData(role='sweet-plugin')" ).sweetPlugin();
});
pageinit
Triggered on the page being initialized, after initialization occurs. We recommend binding to this event instead of DOM ready() because this will work regardless of whether the page is loaded directly or if the content is pulled into another page as part of the Ajax navigation system.
$( '#aboutPage' ).live( 'pageinit',function(event){
alert( 'This page was just enhanced by jQuery Mobile!' );
});
By default, the framework removes any non active dynamically loaded external pages from the DOM as soon as the user navigates away to a different page. The pageremove
event is dispatched just before the framework attempts to remove the a page from the DOM.
pageremove