jQuery Mobile is a great framework for getting a polished mobile site up and running relatively quickly and easily.
Due to the way that it injects pages into the DOM using Hijax, our usual techniques for running code against the current page using selectors that traverse the body no longer make sense.
Basically, there isn’t a $(document).ready().
It’s for this very reason that we can’t rely on IDs either, since multiple copies of the same page are likely to exist in the DOM at the same time.
So how do we run page-level code against the current page when it’s finished loading without the risk of changes to the other pages?
If you keep an eye on the DOM in your developer tools while pages are loaded, you’ll notice that any new pages are appended in a DIV with an HTML5 data-role attribute value of ‘page’. Any code in the page, either in a script block or in an external file, will be executed immediately.
So selecting the most recent page added to the DOM is pretty straightforward:
Note that you should always use the ‘:jqmData’ pseudo-selector to ensure your code will still work if jQuery Mobile’s data attributes are namespaced.
Having to repeat that constantly in all page-level code is a bit fragile, and more than a little ugly, so let’s break this logic out into a standard function which we’ll place into our site-wide script file.
1 2 3 4
Now that we have a page-level script handler, we wrap all our scripts in an anonymous function with a ‘$context’ parameter which is a reference to the jQuery object for the current page:
1 2 3
The equivalent of $(document).ready() is achieved via the ‘pagecreate’ event:
1 2 3 4 5
The other five jQuery Mobile events available for this DIV can now be bound within this anonymous function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
This anonymous function will only run once per page load, so by binding to the event handlers you’ll ensure any event-driven logic will continue to run as users navigate your mobile site.