jQuery Mobile offers several custom events that build upon native events to create useful hooks for development. Note that these events employ various touch, mouse, and window events, depending on event existence, so you can bind to them for use in both handheld and desktop environments. You can bind to these events like you would with other jQuery events, using live()
or bind()
.
$(document).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.
$(document).bind('pagecreate')
vs $(document).bind('pageinit')
Prior to Beta 2 the recommendation to users wishing to manipulate jQuery Mobile enhanced pages 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
in 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.
In short, if you were previously using pagecreate
to manipulate the enhanced markup before the page was shown, it's very likely you'll want to migrate to 'pageinit'.
tap
Triggers after a quick, complete touch event.
taphold
Triggers after a held complete touch event.
$.event.special.tap.tapholdThreshold
(default: 750ms) – This value dictates how long the user must hold their tap before the taphold event is fired on the target element.swipe
Triggers when a horizontal drag of 30px or more (and less than 75px vertically) occurs within 1 second duration but these can be configured:
$.event.special.swipe.scrollSupressionThreshold
(default: 10px) – More than this horizontal displacement, and we will suppress scrolling.$.event.special.swipe.durationThreshold
(default: 1000ms) – More time than this, and it isn't a swipe.$.event.special.swipe.horizontalDistanceThreshold
(default: 30px) – Swipe horizontal displacement must be more than this.$.event.special.swipe.verticalDistanceThreshold
(default: 75px) – Swipe vertical displacement must be less than this.swipeleft
swiperight
We provide a set of "virtual" mouse events that attempt to abstract away mouse and touch events. This allows the developer to register listeners for the basic mouse events, such as mousedown, mousemove, mouseup, and click, and the plugin will take care of registering the correct listeners behind the scenes to invoke the listener at the fastest possible time for that device. In touch environments, the plugin retains the order of event firing that is seen in traditional mouse environments, so for example, vmouseup is always dispatched before vmousedown, and vmousedown before vclick, etc. The virtual mouse events also normalize how coordinate information is extracted from the event, so in touch based environments, coordinates are available from the pageX, pageY, screenX, screenY, clientX, and clientY properties, directly on the event object.
vmouseover
mouseover
eventsvmouseout
mouseout
eventsvmousedown
mousedown
eventsvmousemove
mousemove
eventsvmouseup
mouseup
eventsvclick
click
events. On touch devices, this event is dispatched *AFTER* vmouseup. vmousecancel
mousecancel
events Use vclick with caution on touch devices. Webkit based browsers synthesize mousedown
, mouseup
, and click
events roughly 300ms after the touchend
event is dispatched. The target of the synthesized mouse events are calculated at the time they are dispatched and are based on the location of the touch events and, in some cases, the implementation specific heuristics which leads to different target calculations on different devices and even different OS versions for the same device. This means the target element within the original touch events could be different from the target element within the synthesized mouse events.
We recommend using click
instead of vclick
anytime the action being triggered has the possibility of changing the content underneath the point that was touched on screen. This includes page transitions and other behaviors such as collapse/expand that could result in the screen shifting or content being completely replaced.
Applications can call preventDefault()
on a vclick
event to cancel an element's default click behavior. On mouse based devices, calling preventDefault()
on a vclick
event equates to calling preventDefault()
on the real click
event during the bubble event phase. On touch based devices, it's a bit more complicated since the actual click
event is dispatched about 300ms after the vclick
event is dispatched. For touch devices, calling preventDefault()
on a vclick
event triggers some code in the vmouse plugin that attempts to catch the next click
event that gets dispatched by the browser, during the capture event phase, and calls preventDefault()
and stopPropagation()
on it. As mentioned in the warning above, it is sometimes difficult to match up a touch event with its corresponding mouse event because the targets can differ. For this reason, the vmouse plugin also falls back to attempting to identify a corresponding click
event by coordinates. There are still cases where both target and coordinate identification fail, which results in the click
event being dispatched and either triggering the default action of the element, or in the case where content has been shifted or replaced, triggering a click on a different element. If this happens on a regular basis for a given element/control, we suggest you use click
for triggering your action.
The virtual mouse events can also be configured:
$.vmouse.moveDistanceThreshold
(default: 10px) – More than this, then it is a scroll event. The vmousecancel event is called and the TouchMove event is cancelled.$.vmouse.clickDistanceThreshold
(default: 10px) – If a vclick event was already captured and is in the block list, then vclicks less than this distance are ignored.$.vmouse.resetTimerDuration
(default: 1500ms) – More time than this, then it is not a touch event. Scroll, TouchMove and TouchEnd events use this. The block list is cleared.orientationchange
orientation
property equal to either "portrait" or "landscape". Note that we currently bind to the resize event when orientationchange
is not natively supported, or when $.mobile.orientationChangeEnabled
is set to false. The timing of the orientationchange
with relation to the change of the client height and width is different between browsers, though the current implementation will give you the correct value for event.orientation
derived from window.orientation
. This means that if your bindings are dependent on the height and width values you may want to disable orientationChange
all together with $.mobile.orientationChangeEnabled = false
to let the fallback resize code trigger your bindings.
scrollstart
scrollstop
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 to which we are navigating 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 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 initialization behavior and prevent the auto-initializations from occurring. 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 page from the DOM.
pageremove
Some components within the framework, such as collapsible and listview search, dynamically hide and show content based on user events. This hiding/showing of content affects the size of the page and may result in the browser adjusting/scrolling the viewport to accommodate the new page size. Since this has the potential to affect other components such as fixed headers and footers, components like collapsible and listview trigger a custom updatelayout
event to notify other components that they may need to adjust their layouts in response to their content changes. Developers who are building dynamic applications that inject, hide, or remove content from the page, or manipulate it in any way that affects the dimensions of the page, can also manually trigger this updatelayout
event to ensure components on the page update in response to the changes.
updatelayout
$( '#foo' ).hide().trigger( 'updatelayout' );
jQuery Mobile exposes the animationComplete
plugin, which you can utilize after adding or removing a class that applies a CSS transition. It can be used with page transition events. For example:
$(document).bind("pagehide", function(event, ui) {
$(ui.nextPage).animationComplete(function() {
alert('Animation completed');
});
});