Friday, March 30, 2012

Jquery Mobile Methods and utilities


jQuery Mobile exposes several methods and properties on the $.mobile object for use in your applications.
$.mobile.changePage (method)
Programmatically change from one page to another. This method is used internally for transitions that occur as a result of clicking a link or submitting a form, when those features are enabled.
Arguments
to
  • String, url to transition to ("about/us.html")
  • jQuery object ($("#about"))
  • Array specifying two page references [from,to] for transitioning from a known page. From is otherwise assumed to be the current page in view (or $.mobile.activePage ).
  • Object for sending form data. ({url: url, data: serialized form data, type: "get" or "post"}
transition (string, examples: "pop", "slide"," "none")
reverse (boolean, default: false). True will cause a reverse-direction transition.
changeHash (boolean, default: true). Update the hash to the to page's URL when page change is complete.
Examples:
   
//transition to the "about us" page with a slideup transition    
$.mobile.changePage("about/us.html", "slideup"); 

//transition to the "search results" page, using data from a form with an ID of "search""   
$.mobile.changePage({
 url: "searchresults.php", 
 type: "get", 
 data: $("form#search").serialize()
});  

//transition to the "confirm" page with a "pop" transition without tracking it in history   
$.mobile.changePage("../alerts/confirm.html", "pop", false, false); 
  
   
   
jqmData(), jqmRemoveData(), and jqmHasData() (method)
When working with jQuery Mobile, jqmData and jqmRemoveData should be used in place of jQuery core's data and removeData methods (note that this includes $.fn.data, $.fn.removeData, and the $.data, $.removeData, and $.hasData utilities), as they automatically incorporate getting and setting of namespaced data attributes (even if no namespace is currently in use).
Arguments:
See jQuery's data and removeData methods
Also:
When finding elements by their jQuery Mobile data attribute, please use the custom selector :jqmData(), as it automatically incorporates namespaced data attributes into the lookup when they are in use. For example, instead of calling $("div[data-role='page']"), you should use $("div:jqmData(role='page')"), which internally maps to $("div[data-"+ $.mobile.ns +"role='page']")without forcing you to concatenate a namespace into your selectors manually.
$.mobile.pageLoading (method)
Show or hide the page loading message, which is configurable via $.mobile.loadingMessage.
Arguments:
Done (boolean, defaults to false, meaning loading has started). True will hide the loading message.
Examples:
   
//cue the page loader    
$.mobile.pageLoading(); 

//hide the page loader    
$.mobile.pageLoading( true ); 
   
   
$.mobile.path (methods, properties)
Utilities for getting, setting, and manipulating url paths. TODO: document as public API is finalized.
$.mobile.base (methods, properties)
Utilities for working with generated base element. TODO: document as public API is finalized.
$.mobile.silentScroll (method)
Scroll to a particular Y position without triggering scroll event listeners.
Arguments:
yPos (number, defaults to 0). Pass any number to scroll to that Y location.
Examples:
   
//scroll to Y 100px    
$.mobile.silentScroll(100); 
   
   
$.mobile.addResolutionBreakpoints (method)
Add width breakpoints to the min/max width classes that are added to the HTML element.
Arguments:
values (number or array). Pass any number or array of numbers to add to the resolution classes. Read more about this feature here: Orientation & resolution targeting.
Examples:
   
//add a 400px breakpoint    
$.mobile.addResolutionBreakpoints(400); 
//add 2 more breakpoints    
$.mobile.addResolutionBreakpoints([600,800]); 
   
   
$.mobile.activePage (property)
Reference to the page currently in view.

Jquery Mobile Api Events


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().

Touch events

tap
Triggers after a quick, complete touch event.
taphold
Triggers after a held complete touch event (close to one second).
swipe
Triggers when a horizontal drag of 30px or more (and less than 20px vertically) occurs within 1 second duration.
swipeleft
Triggers when a swipe event occurred moving in the left direction.
swiperight
Triggers when a swipe event occurred moving in the right direction.

Orientation change event

orientationchange
Triggers when a device orientation changes (by turning it vertically or horizontally). When bound to this event, your callback function can leverage a second argument, which contains an orientation property equal to either "portrait" or "landscape". These values are also added as classes to the HTML element, allowing you to leverage them in your CSS selectors. Note that we currently bind to the resize event when orientationChange is not natively supported.

Scroll events

scrollstart
Triggers when a scroll begins. Note that iOS devices freeze DOM manipulation during scroll, queuing them to apply when the scroll finishes. We're currently investigating ways to allow DOM manipulations to apply before a scroll starts.
scrollstop
Triggers when a scroll finishes.

Page show/hide events

Whenever a page is shown or hidden in jQuery Mobile, two events are triggered on that page. The events triggered depend on whether that page is being shown or hidden, so when a page transition occurs, there are actually 4 events triggered: 2 for each page.
pagebeforeshow
Triggered on the page being shown, before its transition begins.
pagebeforehide
Triggered on the page being hidden, before its transition begins.
pageshow
Triggered on the page being shown, after its transition completes.
pagehide
Triggered on the page being hidden, after its transition completes.
Note that all four of these events expose a reference to either the next page (nextPage) or previous page (prevPage), depending on whether the page is being shown or hidden, and whether that next or previous page exists (the first ever page shown does not have a previous page to reference, but an empty jQuery object is provided just the same). You can access this reference 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.

Page initialization events

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 initialization occurs.
pagecreate
Triggered on the page being initialized, after initialization occurs.
  
$('#aboutPage').live('pagebeforecreate',function(event){
  alert('This page was just inserted into the dom!');
});

$('#aboutPage').live('pagecreate',function(event){
  alert('This page was just enhanced by jQuery Mobile!');
});
  
  
Note that by binding to pagebeforecreate and returning false, you can prevent the page plugin from making its manipulations.
  
$('#aboutPage').live('pagebeforecreate',function(event){
  //run your own enhancement scripting here...
  return false;
});

  
  
Note on Page IDs in Alpha 2 release (no longer an issue): In jQuery Mobile Alpha 2 and older, page elements utilized the ID attribute for storing the location from which they came. When you place an ID attribute on a page that is brought into jQuery Mobile's single-page environment through Ajax, jQuery Mobile wraps that page with a new "page" div element, preserving any CSS references to your ID. However, this means that your IDattribute is no longer on the "page" element, so you must keep this in mind when binding to page events (pagebeforecreatepagecreate, etc). To avoid issues, try using a class if possible.

Animation Events

jQuery Mobile exposes the animationComplete plugin, which you can utilize after adding or removing a class that applies a CSS transition.

Monday, March 26, 2012

Jquery Mobile Anatomy of a Page


The jQuery Mobile "page" structure is optimized to support either single pages, or local internal linked "pages" within a page.
The goal of this model is to allow developers to create websites using best practices — where ordinary links will "just work" without any special configuration — while creating a rich, native-like experience that can't be achieved with standard HTTP requests.

Mobile page structure

A jQuery Mobile site must start with an HTML5 'doctype' to take full advantage of all of the framework's features. (Older devices with browsers that don't understand HTML5 will safely ignore the 'doctype' and various custom attributes.)
In the 'head', references to jQuery, jQuery Mobile and the mobile theme CSS are all required to start things off. jQuery Mobile 1.1 works with both 1.6.4 and 1.7.1 versions of jQuery core. We recommend linking to the files hosted on the jQuery CDN for best performance:

<!DOCTYPE html> 
<html> 
 <head> 
 <title>Page Title</title> 
 
 <meta name="viewport" content="width=device-width, initial-scale=1"> 

 <link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0-rc.1/jquery.mobile-1.1.0-rc.1.min.css" />
 <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
 <script src="http://code.jquery.com/mobile/1.1.0-rc.1/jquery.mobile-1.1.0-rc.1.min.js"></script>
</head> 

<body> 
...content goes here...
</body>
</html>

Viewport meta tag

Note above that there is a meta viewport tag in the head to specify how the browser should display the page zoom level and dimensions. If this isn't set, many mobile browsers will use a "virtual" page width around 900 pixels to make it work well with existing desktop sites but the screens may look zoomed out and too wide. By setting the viewport attributes to content="width=device-width, initial-scale=1", the width will be set to the pixel width of the device screen.
<meta name="viewport" content="width=device-width, initial-scale=1"> 
These settings do not disable the user's ability to zoom the pages, which is nice from an accessibility perspective. There is a minor issue in iOS that doesn't properly set the width when changing orientations with these viewport settings, but this will hopefully be fixed a a future release. You can set other viewport values to disable zooming if required since this is part of your page content, not the library.

Inside the body: Pages

Inside the <body> tag, each view or "page" on the mobile device is identified with an element (usually a div) with the data-role="page" attribute. View the data- attribute reference to see all the possible attributes you can add to pages.
<div data-role="page"> 
 ...
</div> 
Within the "page" container, any valid HTML markup can be used, but for typical pages in jQuery Mobile, the immediate children of a "page" are divs with data-roles of "header""content", and "footer".
<div data-role="page"> 
 <div data-role="header">...</div> 
 <div data-role="content">...</div> 
 <div data-role="footer">...</div> 
</div> 

Putting it together: Basic single page template

Putting it all together, this is the standard boilerplate page template you should start with on a project:

<!DOCTYPE html> 
<html> 
 <head> 
 <title>Page Title</title> 
 
 <meta name="viewport" content="width=device-width, initial-scale=1"> 

 <link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0-rc.1/jquery.mobile-1.1.0-rc.1.min.css" />
 <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
 <script src="http://code.jquery.com/mobile/1.1.0-rc.1/jquery.mobile-1.1.0-rc.1.min.js"></script>
</head> 
<body> 

<div data-role="page">

 <div data-role="header">
  <h1>Page Title</h1>
 </div><!-- /header -->

 <div data-role="content"> 
  <p>Page content goes here.</p>  
 </div><!-- /content -->

 <div data-role="footer">
  <h4>Page Footer</h4>
 </div><!-- /footer -->
</div><!-- /page -->

</body>
</html>
View boilerplate template

Multi-page template structure

A single HTML document can contain multiple 'pages' that are loaded together by stacking multiple divs with a data-role of "page". Each 'page' block needs a unique ID (id="foo") that will be used to link internally between 'pages' (href="#foo"). When a link is clicked, the framework will look for an internal 'page' with the ID and transition it into view.
Here is an example of a 2 "page" site built with two jQuery Mobile divs navigated by linking to an ID placed on each page wrapper. Note that the IDs on the page wrappers are only needed to support the internal page linking, and are optional if each page is a separate HTML document. Here is what two pages look inside the body element.

<body> 

<!-- Start of first page -->
<div data-role="page" id="foo">

 <div data-role="header">
  <h1>Foo</h1>
 </div><!-- /header -->

 <div data-role="content"> 
  <p>I'm first in the source order so I'm shown as the page.</p>  
  <p>View internal page called <a href="#bar">bar</a></p> 
 </div><!-- /content -->

 <div data-role="footer">
  <h4>Page Footer</h4>
 </div><!-- /footer -->
</div><!-- /page -->


<!-- Start of second page -->
<div data-role="page" id="bar">

 <div data-role="header">
  <h1>Bar</h1>
 </div><!-- /header -->

 <div data-role="content"> 
  <p>I'm the second in the source order so I'm hidden when the page loads. I'm just shown if a link that references my ID is beeing clicked.</p>  
  <p><a href="#foo">Back to foo</a></p> 
 </div><!-- /content -->

 <div data-role="footer">
  <h4>Page Footer</h4>
 </div><!-- /footer -->
</div><!-- /page -->
</body>
View multi-page template
PLEASE NOTE: Since we are using the hash to track navigation history for all the Ajax 'pages', it's not currently possible to deep link to an anchor (index.html#foo) on a page in jQuery Mobile, because the framework will look for a 'page' with an ID of #foo instead of the native behavior of scrolling to the content with that ID.

Conventions, not requirements

Although the page structure outlined above is a recommended approach for a standard web app built with jQuery Mobile, the framework is very flexible with document structure. The page, header, content, and footer data-role elements are optional and are mostly helpful for providing some basic formatting and structure. The page wrapper that used to be required for auto-initialization to work is now optional for single page documents, so there isn't any required markup at all. For a web page with a custom layout, all of these structural elements can be omitted and the Ajax navigation and all widgets will work just like they do in the boilerplate structure. Behind the scenes, the framework will inject the page wrapper if it's not included in the markup because it’s needed for managing pages, but the starting markup can now be extremely simple.
Note that in a multi-page setup, you are required to have page wrappers in your markup in order to group the content into multiple pages.

Jquery Mobile Dialogs


Creating dialogs

Any page can be presented as a modal dialog by adding the data-rel="dialog" attribute to the page anchor link. When the "dialog" attribute is applied, the framework adds styles to add rounded corners, margins around the page and a dark background to make the "dialog" appear to be suspended above the page.
<a href="foo.html" data-rel="dialog">Open dialog</a>
Open dialog

Transitions

By default, the dialog will open with a 'pop' transition. Like all pages, you can specify any page transition you want on the dialog by adding the data-transition attribute to the link. To make it feel more dialog-like, we recommend specifying a transition of "pop", "slideup" or "flip".
<a href="foo.html" data-rel="dialog" data-transition="pop">Open dialog</a>

Closing dialogs

When any link is clicked within in a dialog, the framework will automatically close the dialog and transition to the requested page, just as if the dialog were a normal page. To create a "cancel" button in a dialog, just link to the page that triggered the dialog to open and add thedata-rel="back" attribute to your link. This pattern of linking to the previous page is also usable in non-JS devices as well.
For JavaScript-generated links, you can simply set the href attribute to "#" and use the data-rel="back" attribute. You can also call the dialog's close() method to programmatically close dialogs, for example: $('.ui-dialog').dialog('close').

Setting the close button text

Just like the page plugin, you can set a dialog's close button text through an option or data attribute. The option can be configured for all dialogs by binding to the mobileinit event and setting the $.mobile.dialog.prototype.options.closeBtnText property to a string of your choosing, or you can place the data attribute data-close-btn-text to configure the text from your markup.

History & Back button behavior

Since dialogs are typically used to support actions within a page, the framework does not include dialogs in the hash state history tracking. This means that dialogs will not appear in your browsing history chronology when the Back button is clicked. For example, if you are on a page, click a link to open a dialog, close the dialog, then navigate to another page, if you were to click the browser's Back button at that point you will navigate back to the first page, not the dialog.

Styling & theming

Dialogs can be styled with different theme swatches, just like any page by adding data-theme attributes to the header, content, or footer containers. Here is an example of a different dialog design:
An alternate color scheme
Dialogs appear to be floating above an overlay layer. This overlay adopts the swatch A content color by default, but the data-overlay-theme attribute can be added to the page wrapper to set the overlay to any swatch letter. Here is an example of a dialog with the overlay set to swatch e:
Custom overlay swatch
Dialogs can also be used more like a control sheet to offer multiple buttons by removing the header:
Share photos...

Dialog width and margins

For the sake of readability, dialogs have a default max-width of 500 pixels (plus 15px padding on each side). There is also a 10% topmargin to give dialogs larger top margin on larger screens, but collapse to a small margin on smartphones. To override these styles, add the following CSS override rule to your stylesheet and tweak as needed:
.ui-dialog .ui-header, 
.ui-dialog .ui-content, 
.ui-dialog .ui-footer { 
 max-width: 500px; 
 margin: 10% auto 15px auto; 
}

Jquery Mobile Prefetching & caching pages


Prefetching pages

Usually, it's a good idea to store your app's pages in several single-page templates instead of one large multi-page template. This minimizes the size of the page's DOM.
When using single-page templates, you can prefetch pages into the DOM so that they're available instantly when the user visits them. To prefetch a page, add the data-prefetch attribute to a link that points to the page. jQuery Mobile then loads the target page in the background after the primary page has loaded and the pagecreate event has triggered. For example:

<a href="prefetchThisPage.html" data-prefetch> ... </a>
You can prefetch as many linked pages as you like. Just add data-prefetch to all the links you want to prefetch.
Alternatively, you can prefetch a page programmatically using $.mobile.loadPage():

$.mobile.loadPage( pageUrl, { showLoadMsg: false } );
Another advantage of prefetching a page is that the user doesn't see the Ajax loading message when visiting the prefetched page. The Ajax loading message only appears if the framework hasn't finished prefetching the page by the time the link is followed.
Prefetching pages naturally creates additional HTTP requests and uses bandwidth, so it's wise to use this feature only in situations where it's highly likely that the prefetched page will be visited. A common scenario is a photo gallery, where you can prefetch the "previous" and "next" photo pages so that the user can move quickly between photos.

DOM size management

For animated page transitions to work, the pages you're transitioning from and to both need to be in the DOM. However, keeping old pages in the DOM quickly fills the browser's memory, and can cause some mobile browsers to slow down or even crash.
jQuery Mobile therefore has a simple mechanism to keep the DOM tidy. Whenever it loads a page via Ajax, jQuery Mobile flags the page to be removed from the DOM when you navigate away from it later (technically, on the pagehide event). If you revisit a removed page, the browser may be able to retrieve the page's HTML file from its cache. If not, it refetches the file from the server. (In the case of nested list views, jQuery Mobile removes all the pages that make up the nested list once you navigate to a page that's not part of the list.)
Pages inside a multi-page template aren't affected by this feature at all - jQuery Mobile only removes pages loaded via Ajax.

Caching pages in the DOM

If you prefer, you can tell jQuery Mobile to keep previously-visited pages in the DOM instead of removing them. This lets you cache pages so that they're available instantly if the user returns to them.
To keep all previously-visited pages in the DOM, set the domCache option on the page plugin to true, like this:

$.mobile.page.prototype.options.domCache = true;
Alternatively, to cache just a particular page, you can add the data-dom-cache="true" attribute to the page's container:

<div data-role="page" id="cacheMe" data-dom-cache="true">
You can also cache a page programmatically like this:

pageContainerElement.page({ domCache: true });
The drawback of DOM caching is that the DOM can get very large, resulting in slowdowns and memory issues on some devices. If you enable DOM caching, take care to manage the DOM yourself and test thoroughly on a range of devices.

jQuery Mobile's navigation model


A "page" in jQuery Mobile consists of an element (usually a div) with a data-role attribute set to "page", which generally containsdiv elements with roles of "header""content", and "footer", each containing common markup, forms, and custom jQuery Mobile widgets.
The basic workflow with page loading is as follows: first, a page is requested with a normal HTTP request, and subsequent "pages" are then requested and injected into that page's DOM. Because of this, the DOM may have a number of "pages" in it at a time, each of which can be re-visited by linking to its data-url attribute.
When a url is initially requested, there may be one or more "pages" in the response, and only the first one will be shown. The advantage of storing more than one "page" is that it allows you to pre-fetch static pages that are likely to be visited.

Hash and Ajax driven page navigation

By default all navigation within jQuery Mobile is based on changes and updates to location.hash. Whenever possible, page changes will use a smooth transition between the current "page" and the next, whether it is either already present in the DOM, or is automatically loaded via Ajax.
Hash values created by jQuery Mobile are normalized as full paths relative to the URL of the first "real" page that was loaded. The hash is always maintained as a valid URL, so any "page" in jQuery mobile can be bookmarked or referenced in a link. To retrieve a non-hash-based URL, simply remove the # from the address and refresh the page.
In general, hash changes are created whenever a link is clicked in jQuery mobile. When a link is clicked, jQuery mobile will make sure that the link is referencing a local URL, and if so, it'll prevent the link's default click behavior from occurring and request the referenced url via Ajax instead. When the page returns successfully, it will set the location.hash to the new page's relative url.
Hash changes that occur independently of a click, such as when a user clicks the back button, are handled through the hashchangeevent, which is bound to the window object using Ben Alman's hashchange special event plugin (included in jQuery Mobile). When a hash change occurs (and also when the first page loads), the hashchange event handler will send the location.hash to the$.mobile.changePage() function, which in turn either loads or reveals the referenced page.
Once the referenced page is present in the DOM, the $.mobile.changePage() function applies a transition between the current active page and the new page. Page transitions happen through adding and removing classes that apply CSS animations. For example, in a slide-left transition, the exiting page is given the classes "slideleft" and "out", and the entering page is given the classes"slideleft" and "in", as well as a class of "ui-page-active" to mark it as the new "active" page being viewed. When the animation is complete, the "in" and "out" classes are removed, and the exited page loses its "ui-page-active" class.

pushState plugin

There is an optional feature that converts the longer, hash-based URLs mentioned in the previous section into the full document path which is cleaner and makes the Ajax tracking transparent in the URL structure. This is built as an enhancement on top of the hash-based URL system for Ajax links. Note that despite the name, this feature technically converts hash-based urls by using history.replaceState(not history.pushState) in the current release because this works more reliably across our target platforms. For browsers that do not support history.replaceState, or if this feature is disabled, hash-based URLs will be used instead.
Since the plugin initializes when the DOM is fully loaded you can enable and disable it manually by setting$.mobile.pushStateEnabled global configuration option to false anytime before document ready.

Important: rel="external" and $.mobile.ajaxEnabled=false

Slightly different implementations of the replaceState API in various browsers can cause odd behavior in specific scenarios. For example, some browser implementations (including desktop browsers) implement the popstate event differently when linking externally and moving back to a page onto which state has already been pushed/replaced. When building a jQuery Mobile application where the ajax navigation is being explicitly disabled, either through the frequent use of rel="external" on links or by disabling Ajax navigation completely via the $.mobile.ajaxEnabled=false, we recommend disabling the pushState feature to fall back to the hash based navigation for more consistent behavior.

changePage

Within the framework, page changes - both for pages already in the DOM and for pages that need to be loaded via Ajax - use the$.mobile.changePage() function. $.mobile.changePage() contains all of the logic for finding pages to transition to and from, and how to handle various response conditions such as a page not found. $.mobile.changePage() can be called externally and accepts the following arguments (to, transition, back, changeHash). The to argument can accept either a string (such as a file url or local element's ID), an array (in which the first array item is any local page you'd like to transition from, and the second array item is the topage), or an object (with expected properties: url, type ("get" or "post"), and data (for serialized parameters)), the latter of which is useful for loading pages that expect form data. The transition argument accepts a string representing a named transition, such as "slide". The back argument accepts a boolean representing whether the transition should go forward or in reverse. Lastly, the changeHashargument accepts a boolean for whether you'd like the url to be updated upon a successful page change.
The $.mobile.changePage() function is used in a number of places in jQuery Mobile. For example, when a link is clicked, its hrefattribute is normalized and then $.mobile.changePage() handles the rest. When forms are submitted, jQuery Mobile simply gathers a few of the form's attributes, serializes its data, and once again, $.mobile.changePage() is used to handle the submission and response. Also, links that create dialogs use $.mobile.changePage()to open a referenced page without updating the hash, which is useful for keeping dialogs out of history tracking.

Base element

Another key ingredient to jQuery Mobile's page navigation model is the base element, which is injected into the head and modified on every page change to ensure that any assets (images, CSS, JS, etc.) referenced on that page will be requested from a proper path. In browsers that don't support dynamic updates to the base element (such as Firefox 3.6), jQuery Mobile loops through all of the referenced assets on the page and prefixes their href and src attributes with the base path.

Developer explanation of base url management:

jQuery Mobile manages http requests using a combination of generated absolute URL paths and manipulating a generated <base>element's href attribute. The combination of these two approaches allows us to create URLs that contain full path information for loading pages, and a base element to properly direct asset requests made by those loaded pages (such as images and stylesheets).
TODO: update description of internal base and urlHistory objects

Data-url storage

The navigation model maintains a data-url attribute on all data-role="page" elements. This data-url attribute is used to track the origin of the page element. Pages embedded within the main application document all have their data-url parameter set to the ID of their element with data-role="page". The only exception to this is the first-page in the document. The first-page is special because it can be addressed by its id if it has one, or by the document or base URL (with no hash fragment).
Pages that are external to the application document get pulled in dynamically via ajax, and their data-url is set to the site relative path to the external page. If you are running in an environment where loading an external page from a different domain is allowed, then the data-url is set to the absolute URL.

Auto-generated pages and sub-hash urls

Some plugins may choose to dynamically break a page's content into separate navigable pages, which can then be reached via deep links. One example of this would be the Listview plugin, which will break a nested UL (or OL) into separate pages, which are each given adata-url attribute so they can be linked to like any normal "page" in jQuery Mobile. However, in order to link to these pages, the page that generates them must first be requested from the server. To make this work, pages that are auto-generated by plugins use the following special data-url structure: <div data-url="page.html&subpageidentifier">
So, for example, a page generated by the listview plugin may have a data-url attribute like this: data-url="artists.html&ui-page=listview-1"
When a page is requested, jQuery Mobile knows to split the URL at "&ui-page" and make an HTTP request to the portion of the URL before that key. In the case of the listview example mentioned above, the URL would look like this: http://example.com/artists.html&ui-page=listview-1 ...and jQuery Mobile would request artists.html, which would then generate its sub-pages, creating the div with data-url="artists.html&ui-page=listview-1", which it will then display as the active page.
Note that the data-url attribute of the element contains the full URL path, not just the portion after &ui-page=. This allows jQuery Mobile to use a single consistent mechanism that matches URLs to page data-url attributes.

Cases when Ajax navigation will not be used

Under certain conditions, normal http requests will be used instead of Ajax requests. One case where this is true is when linking to pages on external websites. You can also specify that a normal http request be made through the following link attributes:
  • rel=external
  • target (with any value, such as "_blank")

Form submissions

Form submissions are handled automatically through the navigation model as well. Visit the forms section for more information.

Using the Application Cache

When using the application cache with jQuery Mobile there is at least one important issue to consider. Some browsers, when making requests to the cache will report an http status of 0 on success. This causes jQuery Core's $.ajax to trigger error handlers. The suggested workaround for users leveraging the application cache is to use a jQuery ajax pre-filter. Something like the following (credit tojammus for the snippet):


$.ajaxPrefilter( function(options, originalOptions, jqXHR) {
 if ( applicationCache &&
   applicationCache.status != applicationCache.UNCACHED &&
   applicationCache.status != applicationCache.OBSOLETE ) {
   // the important bit
   options.isLocal = true;
 }
});

   
Setting isLocal to true for your ajax requests will alert jQuery Core that it should handle the 0 return values differently. Local requests exhibit similar behavior (ie 0 statuses), and Core will then fall back to determining success based on the presence of content in the xhrresponseText attribute.
One important issue to note with the above is that it will set isLocal to true for all requests made via ajax regardless of whether they are in the manifest or not so long as the cache is valid. This works for now because Core only consults the isLocal value when the status is in fact 0 which doesn't affect uncached results. There is no long term guarantee that isLocal will remain isolated in its purpose for handling 0 status values. If that changes it may break your application.

Known limitations

The non-standard environment created by jQuery Mobile's page navigation model introduces some conditions of which you should be aware when building pages:
  • When linking to directories, without a filename url, (such as href="typesofcats/" instead ofhref="typesofcats/index.html"), you must provide a trailing slash. This is because jQuery Mobile assumes the section after the last "/" character in a url is a filename, and it will remove that section when creating base urls from which future pages will be referenced.
  • Documents loaded via Ajax will select the first page in the DOM of that document to be loaded as a JQM page element. As a result the developer must make sure to manage the ID attributes of the loaded page and child elements to prevent confusion when manipulating the DOM.
  • If you link to multipage document, you must use a data-ajax="false" attribute on the link to cause a full page refresh due to the limitation above where we only load the first page node in an Ajax request due to potential hash collisions. There is currently asubpage plugin that makes it possible to load in multi-page documents.
  • Any unique assets referenced by pages in a jQuery Mobile-driven site should be placed inside the "page" element (the element with a data-role attribute of "page"). For example, links to styles and scripts that are specific to a particular page can be referenced inside that div. However, a better approach is to use jQuery Mobile's page events to trigger specific scripting when certain pages load. Note: you can return a page from the server with a data-url already specified in the markup, and jQuery Mobile will use that for the hash update. This allows you to ensure directory paths resolve with a trailing slash and will therefore be used in the base url path for future requests.
  • Conversely, any non-unique assets (those used site-wide) should be referenced in the <head> section of an HTML document, or at the very least, outside of the "page" element, to prevent running scripts more than once.
  • The "ui-page" key name used in sub-hash url references can be set to any value you'd like, so as to blend into your URL structure. This value is stored in jQuery.mobile.subPageUrlKey.
  • When traveling back to a previously loaded jQuery Mobile document from an external or internal document with the push state plugin enabled, some browsers load and trigger the popstate event on the wrong document or for the wrong reasons (two edge cases recorded so far). If you are regularly linking to external documents and find the application behaving erratically try disabling pushstate support.
  • jQuery Mobile does not support query parameter passing to internal/embedded pages but there are two plugins that you can add to your project to support this feature. There is a lightweight page params plugin and a more fully featured jQuery Mobile router plugin for use with backbone.js or spine.js.
  • Since we use the URL hash to preserve Back button behavior, using page anchors to jump down to a position on the page isn't supported by using the traditional anchor link (#foo). Use the silentScroll method to scroll to a particular Y position without triggering scroll event listeners. You can pass in a yPos arguments to scroll to that Y location.