The jQuery Mobile team is happy to announce the release of Beta 2. This brings a bunch of big improvements to the library including: decoupled widgets so you can include only the components you need, DOM cache management for less memory use, a page pre-cache option, more flexible page structure, improved checkbox and radiobutton designs, advanced features for developers building dynamic JS-driven sites, and even broader device support. It’s been a busy 5 weeks since Beta 1 and we’re really happy with the direction and velocity of the project as we head towards 1.0.
Beta 3 coming – We have a few key improvements we want to land before we switch gears to focus on bug fixes and performance for the first RC for 1.0. Look for Beta 3 within the next month that will include pushState support, improved transitions with support for Firefox and Opera, and even more developer extensibility hooks.
Note that jQuery Mobile 1.0 will require jQuery core 1.6.2 as a baseline. Going forward, we’ll be supporting the two latest major versions of core but we’re starting with a cleaner baseline for launch. Here is a summary of what’s new and improved in Beta 2.
In Beta 2, we’ve added broader support of CSS gradient rules for Opera and Firefox, brought support and testing for Android 2.3 phones and Honeycomb tablets, HP Palm WebOS 3.0 tablets, and added B grade support for newer Nokia S60 devices.
We’re happy to announce that jQuery Mobile Beta 2 now supports Nokia Series 60 smartphones. We’ve had to bump this platform down to B grade support because this platform doesn’t properly support hashchange events in the history stack. This means that Nokia devices will get the enhanced experience except without the Ajax-based animated page transitions.
At this stage, jQuery Mobile works on the vast majority of all modern desktop, smartphone, tablet, and e-reader platforms. In addition, feature phones and older browsers are also supported because of our progressive enhancement approach. We’re very proud of our commitment to universal accessibility through our broad support for all popular platforms.
Our graded support matrix was created over a year ago based on our goals as a project and since that time, we’ve been refining our grading system based on real-world device testing and the quickly evolving mobile landscape. To provide a quick summary of our browser support in Beta 1, we’ve created a simple A (full), B (full minus Ajax), C (basic) grade system with notes of the actual devices and versions we’ve been testing on in our lab.
The visual fidelity of the experience is highly dependent on CSS rendering capabilities of the device and platform so not all A grade experience will be pixel-perfect but that’s the nature of the web. We’ll be adding additional vendor-prefixed CSS rules to bring transitions, gradients and other visual improvements to non-WebKit browsers in future releases so look for even more added visual polish as we move towards 1.0.
A-grade – Full enhanced experience with Ajax-based animated page transitions.
- Apple iOS 3.2-5.0 beta: Tested on the original iPad (3.2 / 4.3), iPad 2 (4.3), original iPhone (3.1), iPhone 3 (3.2), 3GS (4.3), and 4 (4.3 / 5.0 beta)
- Android 2.1-2.3: Tested on the HTC Incredible (2.2), original Droid (2.2), Nook Color (2.2), HTC Aria (2.1), Google Nexus S (2.3) NEW. Functional on 1.5 & 1.6 but performance may be sluggish, tested on Google G1 (1.5)
- Android Honeycomb NEW – Tested on the Samsung Galaxy Tab 10.1
- Windows Phone 7: Tested on the HTC 7 Surround
- Blackberry 6.0: Tested on the Torch 9800 and Style 9670
- Blackberry Playbook: Tested on PlayBook version 1.0.1 / 1.0.5
- Palm WebOS (1.4-2.0): Tested on the Palm Pixi (1.4), Pre (1.4), Pre 2 (2.0)
- Palm WebOS 3.0 NEW – Tested on HP TouchPad
- Firebox Mobile (Beta): Tested on Android 2.2
- Opera Mobile 11.0: Tested on the iPhone 3GS and 4 (5.0/6.0), Android 2.2 (5.0/6.0), Windows Mobile 6.5 (5.0)
- Kindle 3: Tested on the built-in WebKit browser included in the Kindle 3 device
- Chrome Desktop 11-13 – Tested on OS X 10.6.7 and Windows 7
- Firefox Desktop 3.6-4.0 – Tested on OS X 10.6.7 and Windows 7
- Internet Explorer 7-9 – Tested on Windows XP, Vista and 7 (minor CSS issues)
- Opera Desktop 10-11 – Tested on OS X 10.6.7 and Windows 7
B-grade – Enhanced experience except without Ajax navigation features.
- Blackberry 5.0: Tested on the Storm 2 9550, Bold 9770
- Opera Mini (5.0-6.0) – Tested on iOS 3.2/4.3
- Windows Phone 6.5 – Tested on the HTC
- Nokia Symbian^3 NEW – Tested on Nokia N8 (Symbian^3), C7 (Symbian^3), also works on N97 (Symbian^1)
C-grade – Basic, non-enhanced HTML experience that is still functional
- Blackberry4.x: Tested on the Curve 8330
- All older smartphone platforms and featurephones – Any device that doesn’t support media queries will receive the basic, C grade experience
Not Officially Supported – May work, but haven’t been thoroughly tested or debugged
- Meego – Originally a target platform, but Nokia decision to relegate this platform to “experimental”, we are considering dropping support.
- Samsung Bada – The project doesn’t currently have test devices or emulators, but current support is known to be fairly good. Support level undecided for 1.0.
KEY CHANGES
Widgets: Now decoupled for flexible builds
We’ve wanted to decouple all our widgets from the page plugin for a long time now and we’re happy to announce that we finally landed this change. So what exactly does decoupled mean anyway? Well, the individual widgets and utilities have always been broken out into separate script files. However, the page plugin was responsible for handling the auto-initialization all of the official plugins found in the markup at page creation. This situation made it impossible to remove plugins you don’t need without causing errors, and generally set a bad precedent for future widget additions.
Now, pretty much all the UI widgets in the jQuery Mobile library are completely decoupled so they can simply be deleted if not needed for a particular project. This change allows you to dramatically reduce the size of the library by only including the specific set of widgets or features you need, in addition to the handful of required, core files. While we still plan to do more decoupling and cleanup, the following files are now decoupled and can safely be removed from the make file before you do a custom build:
- page header/content/footer
- collapsible
- controlgroup
- fieldcontain
- fixheaderfooter
- button
- checkboxradio
- select
- slider
- textinput
- links theming
- listview
- navbar
- grid
We will work on a dependency map because a few widgets rely on others to work. For example, the button markup plugin is called by many of the widgets above, so it can only be excluded but if you’re not using any of the widgets that depend on buttons.
We’re still working out our recommendations for mapping plugin dependencies and decoupling things even further. Ultimately, this will be surfaced in a download builder tool, so stay tuned!
New “create” event: Easily enhance all widgets at once
While the page plugin no longer calls each plugin specifically, it does dispatch a “pagecreate” event, which most widgets use to auto-initialize themselves. As long as a widget plugin script is referenced, it will automatically enhance any instances of the widgets it finds on the page, just like before. For example, if the selectmenu plugin is loaded, it will enhance any selects it finds within a newly created page.
This structure now allows us to add a new create
event that can be triggered on any element, saving you the task of manually initializing each plugin contained in that element. Until now, if a developer loaded in content via Ajax or dynamically generated markup, they needed to manually initialize all contained plugins (listview button, select, etc.) to enhance the widgets in the markup.
Now, our handy create
event will initialize all the necessary plugins within that markup, just like how the page creation enhancement process works. If you were to use Ajax to load in a block of HTML markup (say a login form), you can trigger create
to automatically transform all the widgets it contains (inputs and buttons in this case) into the enhanced versions. The code for this scenario would be:
$( ...new markup that contains widgets... ).appendTo( ".ui-page" ).trigger( "create" );
Create vs. refresh: An important distinction
Note that there is an important difference between the create
event and refresh
method that some widgets have. The create
event is suited for enhancing raw markup that contains one or more widgets. The refresh
method that some widgets have should be used on existing (already enhanced) widgets that have been manipulated programmatically and need the UI be updated to match.
For example, if you had a page where you dynamically appended a new unordered list with data-role=listview
attribute after page creation, triggering create
on a parent element of that list would transform it into a listview styled widget. If more list items were then programmatically added, calling the listview’s refresh
method would update just those new list items to the enhanced state and leave the existing list items untouched.
New DOM cache management feature: On by default
Since animated page transitions require that the page you’re on and the one you’re transitioning to are both in the DOM, we add pages to the DOM as you navigate around. Until now, those pages would continue to stay in the DOM until you did a full page refresh so there was always a concern that we could hit a memory ceiling on some devices and cause the browser to slow down or even crash.
For Beta 2, we added a simple mechanism to keep the DOM tidy. It works like this: whenever a page is loaded in via Ajax, it is flagged for removal from the DOM once you navigate away to another page (technically, on pagehide). If you return to a deleted page, the browser may be able to retrieve the file from it’s cache, or it will re-request it fro the sever if needed. In the case of nested lists, we remove all the pages that make up the nested list once you navigate to a page that’s not part of the list. Pages that are included in a multi-page setup won’t be affected by this feature at all – only pages brought in by Ajax are managed this way by jQuery Mobile.
A new page option called domCache
controls whether to leave pages in the DOM as a way to cache them (the way things used to work) or keep the DOM clean and remove hidden pages (the new way). By default, domCache
is set to false
to keep the DOM size actively managed. If you set this to true
, you need to take care to manage the DOM yourself and test thoroughly on a range of devices.
To set the domCache
option on an individual pages in order to selectively cache a page, you can either add the data-dom-cache="true"
attribute to the page container or set it programmatically like this:
elem.page({ domCache: true });
The domCache option can also be set globally. This is how to turn DOM caching back on so it works like it did originally:
$.mobile.page.prototype.options.domCache = true;
Page pre-fetch page option added
Another cool feature we recently added is the ability to flag pages that should be pre-fetched by Ajax. For example, if you’re building a photo gallery with each photo on a separate HTML page, you can pre-fetch the previous and next pages in the slideshow sequence so they will display immediately without the Ajax loader. It’s simple to use: just add a data-prefetch
attribute to any link in the page and the framework will lazy load the pages into the DOM in the background. We recommend building your apps as a series of individual, linked HTML documents for each page for performance yet we see a lot of people using multi-page templates and even nested lists (yikes) as a way to essentially pre-load content. We hope this feature will encourage developers to use standalone, external pages with selective pre-caching instead of relying as much on multi-page setups.
<a href="foo/bar/baz" data-prefetch>link text</a>
Pages can also be pre-fetched programmatically by calling $.mobile.loadpage( url )
. Pre-fetching links will naturally cause additional HTTP requests that may never be used, so it’s important to use this feature only in situations where it’s highly likely that a page will be visited.
New global config option: autoInitializePage
For advanced developers who want more control over the initialization sequence of a page, we’ve just added a new autoInitializePage
global config option. Setting this to false
disables auto-initialization of plugins on page creation to allow developers to manipulate or pre-process markup before manually initializing the page later on. By default, this option is set to true
so things work just like they always did.
Loading message: Now configurable at runtime
Previously, you could customize the loading text message on initialization as an option, but you couldn’t modify it on the fly from within a page if you wanted a different message for the particular situation. We just landed an improvement so you can set the contents of the loading message programmatically at runtime. The syntax is the same as it’s always been, you can just use it more flexibly:
$.mobile.loadingMessage = "My custom message!";
Configurable swipe event thresholds added
There were a number of hard-coded constants in the jquery.mobile.event.js swipe code. For developers who need to tweak those constants to allow a greater vertical displacement and still register a swipe, this new feature allows them to be adjusted. Thanks to mlitwin for contributing this.
- scrollSupressionThreshold (default: 10px) – More than this horizontal displacement, and we will suppress scrolling
- durationThreshold (default: 1000ms) – More time than this, and it isn’t a swipe
- horizontalDistanceThreshold (default: 30px) – Swipe horizontal displacement must be more than this.
- verticalDistanceThreshold (default: 75px) – Swipe vertical displacement must be less than this.
Backtrack: We’ve switched back from vclick to click for links
In Beta 1, we decided to use our custom vclick event for handling Ajax links to improve responsiveness and to hide the URL bar on the iPhone and Android phones. Even though we did quite a bit of testing before landing this for Beta 1, we began to hear feedback that this change was causing some significant issues out in the wild including:
- Multiple click events causing navigation and form element issue – In certain situations, when tapping an element, tap/click events seem to fire twice on links and is due to edge cases where the target of the touch event and mouse event don’t match due to how the browsers calculate tolerances for these events. This is most pronounced on Android 2.1, but affected most WebKit-based browsers to varying degrees when a tap events occured near the edge of an element.
- Click handlers in custom scripts didn’t “work” anymore – if a script bound only to click events on the document, the global vclick feature could interfere because the touch events may supercede click events so it events wouldn’t appear to trigger.
Based on a lot of detailed testing and analysis, we’ve decided to roll back to using standard click events on links instead of using the custom vclick event because it’s the only reliable way to support all our target browsers. There are two important things to note in this change:
- URL bar hiding isn’t quite as slick as in Beta 1, but link handling is obviously much more important. The good news is that there is still a significant improvement from Alpha 4.1: although URL bar may appear briefly it overlays the page in iOS instead of pushing down content and causing a re-draw blink. We methodically tried every technique we could to keep the URL bar hidden but there is unfortunately a Safari bug (even in the latest Beta 2 of iOS 5) that makes it impossible to hide the bar reliably.
- The
useFastClick
global option introduced in Beta 1 is now removed because we’re not using vclick globally anymore on links and don’t recommend doing this going forward. We hardly knew ye…
Page wrapper: Now optional
The framework is now more flexible with document structure so now the data-role=page
wrapper element is optional. This will ease integration with existing sites, as well as mashups with external content. Previously, if you didn’t wrap your page in a container with this role, the framework wouldn’t enhance the page widgets but now it doesn’t need a page wrapper in the markup to trigger initialization.
The page, header, content, and footer data-role
elements have always been optional, but now with this page wrapper change, there is no required markup at all – just start building you page content. Here is an example of a page with none of these structural elements in the markup and everything works great.
Behind the scenes, the framework will inject the page wrapper if you don’t include it 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.
Checkboxes and Radio buttons: New, Simpler design
Now onto fun fun stuff: the previous design for checkboxes or radio buttons highlighted the entire button background to the active state. We’ve wanted to tweak this for some time because having the full button switch tothe active state could be a bit overwhelming visually, especially on a check list with multiple items selected.
To make these controls a bit simpler visually and also fall in-line with standard UI conventions, now just the check or radio form element flips to the active state instead of the whole button. Note that the horizontal, grouped check and radio groups still flip the while label to the active state color because we hide the form element in these cases.
Gradients: Expanded platform support
We just added additional vendor-prefixed rules for CSS3 background gradients to increase browser support of this feature. There are now Opera (-o) and Internet Explorer (-ms) prefixed gradient rules in addition to the standard, non-prefixed version. Thanks to Paul Irish CCS3 Please for the slick formatting ideas for these rules:
background-image: -webkit-linear-gradient(top, #3c3c3c, #111); /* Chrome 10+, Saf5.1+ */
background-image: -moz-linear-gradient(top, #3c3c3c, #111); /* FF3.6 */
background-image: -ms-linear-gradient(top, #3c3c3c, #111); /* IE10 */
background-image: -o-linear-gradient(top, #3c3c3c, #111); /* Opera 11.10+ */
background-image: linear-gradient(top, #3c3c3c, #111); /* Standard, non-prefixed */
This now means that our background gradients work in WebKit, Firefox, Opera, Internet Explorer 10 and any other browser that supports the standard, non-prefixed rule. As we mentioned in an earlier blog post, we had to remove the -ms filter gradient rules due to a rendering issue in IE9 that conflicts with border radius and won’t be fixed by Microsoft. This means that older versions of IE will just see a flat background color, including WP7 and the forthcoming Mango release. More info on this bug and decision can be found at issue #2046. This change has been rolled into both the Default and Valencia themes.
All code formatting: Cleaned up & JSlint-ready
Thanks to an intense 24 hour sprint by Rick Waldron of Bocoup, all our code formatting now conforms with with the jQuery core styleguide for whitespace and organization. This also makes the library work with JSLint and other validation tools.
API documentation: Now underway
We’ve been trying a number of different ideas internally on how to add in more traditional API-style docs to the demos & docs site and have a proposed solution that essentially adds a simple tab strip to all the plugin detail pages where we can document the options, methods and events that a more technical developer might need. We’ve tried to strike a balance between presenting the simpler, markup-based approach that a designer may need and the more advanced script-driven details that a developer requires.
We’re looking for volunteers to help us apply this style of docs throughout the rest of the system. To participate, learn more about on how to help us write API docs. Thanks to ovargas27 for already jumping in and lending a hand.
Beta 1 upgrade notes
The useFastClick
global option introduced in Beta 1 is now removed because we’re not using vclick globally anymore on links.
Change log
Fix for cached page removal breaking dialog sized select menus (issue 2181)
Added a configurable timeout to $.mobile.loadPage to give pages that are being fetched from cache a little time to load before a loading message appears. Note: if the delay ends up needing to be longer than 300ms or so to suit some devices,we may not keep this feature.
Exposed automatic initialization selectors on most widgets – The new option, initSelector
is accessed through each of the widget plugins (select, slider, etc.) that expose options through the widget factory. This is used to define the selectors (element types, data roles, etc.) that should be used as the trigger to automatic initialization of each widget plugin. This allows developers to apply auto-initialization in more flexible ways.
Restored degradeInputs page option (issue 2123) – We originally had a degradeInputs
option as part of the page plugin that would allows you to find a certain type of form element (say input type=”range”) and degrade it into another type (input type=”number”) either because the browser support is so uneven or if you built a custom enhancement for the primary type (like a custom slider) and you don’t want the native implementation to interfere. Now added back in a decoupled plugin, but the API is the same.
Prevent ‘Unspecified error’ when we use an IFrame on IE9 (issue 2064) – Add try/catch block to prevent the error. Thanks SamuelKC
Updated Valencia theme to match new CSS syntax (issue 2087) – After our request for help on this, and Mayank Varia came through with an update for this theme so thanks!
Error in new page.sections js when data-add-back-btn=”true” on page (issue 2119) -Fixed a problem when pages have the data-add-back-btn set to true causing an error. Thanks jgable!
Email input type doesn’t receive input field styles (issue 2117) – When using email as the input type for an input field, jQuery Mobile does not correctly enhance them post-decoupling. Thanks commadelimited! Also fixed URL and tel input types for the same regression.
Hide loading message for loadPage should be to not show the loading message – It’s default use case is to fetch a page that is not yet active so this is distracting. However, changePage should cause it to show because loadPage is being called during a page change. This was causing the loader to show when using the new page precache option.
Fix for URL handing in navigation with relative URLs – Now you can call $.mobile.loadPage with a relative path and it will load the page correctly, regardless of whatever page you are linking from.
Removed the nonHistorySelectors option, which was no longer in use after the nav refactor.
Fix for rounded corners in collapsible Set (issue #1931) – The first section in a collapsible set has rounded bottom corners when not expanded (shouldn’t have .ui-corner-bottom class), and the last section does not have rounded corners when collapsed (should have .ui-corner-bottom class). Thanks ryanneufeld !
Checkbox list with same name do not allow multiple selection (issue #1851) – The checkboxradio plugin treats a check box list with same value for the name attribute for the check boxes as radio buttons. Thanks Tigbro!
Rounded corner login for inset lists with two items (issue 1996) – The top corner style doesn’t get applied in an inset list with two items (other number of items work fine). Thanks eugenb1!
Close button behavior fixes (Issues #1618, #1692,#1750)- Abstracted out some of the page hide behavior to fix issues with the close button not returning focus to the button after closing. Also fixes an issue where a full page custom menu would open as a misplaced small custom menu the second time it opens (if the menu was closed via the custom close button).
Changed padding-box to padding for -moz-background-clip per this spec
Slider onChange event is launched on page load (issue #1526) – the onChange event was triggered when the page loads instead of only when the slider’s value is changed.
Disappearing text in IE7 (issue #2058) – Text would only appear on mouseover in certain circumstances due to a rendering bug in IE (shocker!). Fixed by adding the zoom: hack.
XSS risk with XHR level2 cross domain request (issue #1990) – jQuery mobile can load other domain’s html so there is a security risk, as it can XSS or display fake contents. Created new option for $.mobile.ajaxCrossDomainEnabled and set the defaultto false
Switch back to processing link clicks on the “click” event because it really is the only reliable way across all the devices we support. Fixes any of the double click events, missed clicks or click event not being processed. Also, removed the useFastClick option and documentation references since using vclick isn’t a workable solution for links.
mobile.changePage not working on BB5 (issue #1907)- multi-page docs don’t work, and clicking a link cause a “page is too large” error. The fix for this was to tweak the regex related.
Fix for the mysterious “page is too large” error on Blackberry 5 prior to beta 1. Turns out this little code was enough to invoke the error: “/dir1/dir2”.replace(/\/?/, “”); Rewrote the regexp in path.makePathAbsolute() that was stripping leading slash, and trailing filename/slash. This gets around the problem. Special thanks to @adambiggs for helping us test 33 iterations when trying to narrow down the cause!
Fixed form buttons no longer submitting forms in Internet Explorer 8
Corrected corner styling issue with listview refresh on growing lists (issue #1470) – If list items were appended and the refresh() method called, the correct corners were not being assigned.
Fixed incorrectly calculated path of forms (issue #1923)- Added code to calculate whether to choose the documentUrl or the page Url in the case where an action is not specified on a form element. Fixed bug in the navigation “submit” handler where an error was being thrown if “type” was not specified.
Hitting enter in search filter now doesn’t not submit the form – Since this is a client-side filter, we want to prevent submitting the form. Thanks adamvaughan
Remove unnecessary ajax call and duplicate DOM nodes when refreshing a page with a dialog visible (issue #1913) – This was causing duplicate dialog elements inthe DOM. Thanks Sunpig!
Controlgroup now filters on visible buttons when adding first and last classes for rounded corners. If you hide the first or last button in a controlgroup and then call refresh on it, it won’t add the right classes to the newly promoted first/last button.
Removed param “refresh” sent to .controlgroup since it’s not a $.widget
Tweaked styles for select menu text running off side of list – Seen when using the custom select menus only
Updated Valencia theme for the updated check and radio styles
Fixed swatch letter typo for E button in theme CSS (Issue #1894)- it said ui-bar-d instead of ui-bar-e. . Thanks app42!
Moved collapsible sets (accordions) in docs into a standalone page for better visibility, updated section nav on other pages and index page to link to it.
Moved our form binding into the _registerInternalEvents callback, to ensure it’s not bound until after mobilinit.
Download
We provide CDN-hosted versions of jQuery Mobile for you to include into your site. These are already minified and compressed – and host the image files as well. It’ll likely be the fastest way to include jQuery Mobile in your site.
CDN-Hosted JavaScript:
CDN-Hosted CSS:
Copy-and-Paste Snippet for CDN-hosted files (recommended):
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b2.min.css" />
<script src="http://code.jquery.com/jquery-1.6.2.min.js"></script>
<script src="http://code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b2.min.js"></script>
If you want to host the files yourself you can download a zip of all the files:
ZIP File: