A "page" in jQuery Mobile consists of an element (usually a
div) with a
data-role attribute set to
"page", which generally contains
div elements with roles of
"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
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.
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 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 hashchange event, 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
"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
"out" classes are removed, and the exited page loses its
There is an optional feature is 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.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.
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 though 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.
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() 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
to page), 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
changeHash argument accepts a boolean for whether you'd like the url to be updated upon a successful page change.
$.mobile.changePage() function is used in a number of places in jQuery Mobile. For example, when a link is clicked, its href attribute 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.
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.
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
The nav 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 the @data-role="page" element. 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, 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.
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 a data-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:
So, for example, a page generated by the listview plugin may have an data-url attribute like this:
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.
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:
target (with any value, such as "_blank")
Form submissions are handled automatically through the navigation model as well. Visit the forms section for more information.
The non-standard environment created by jQuery Mobile's page navigation model introduces some conditions for which you should be aware when building pages:
When linking to directories, without a filename url, (such as href="typesofcats/" instead of href="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.
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
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 eratically try disabling pushstate support.