Tag Archives: jquery mobile

jQuery Mobile Fixes

29 Jul 2013

Hmmm… jQuery Mobile… if only you delivered on mobile the way you promised…. the world’s most popular JS framework sadly misses the mobile mark and by a wide margin. If you do have to use jQM then you’re probably looking for tips on how to get some level of performance out it.

Scroll Performance

This is a widely discussed topic – list view performance in jQM is pretty poor and is most noticibly lacking in Android especially in older devices. Throw in form elements like sliders, buttons – and things are downright unacceptable. Per the aforementioned online discussions and some of my own trial and error remove the following to get a modicum of performance gains:

  • Remove all radiused corners
  • Remove all gradients – I replace them with tiled backgrounds to achieve the same effect
  • Remove all shadows
  • “Disable” all hover states – a big performance hog on mobile
  • Don’t inset the list view – doing so adds more overhead for the mobile browser / webview

An example that has worked for me – you’ll want to tailor this for your specific needs. This works on the premise that if all of the up, down and hover states’ CSS is the same the browser doesn’t have to redraw anything. The result is that nothing happens and you negate the performance hit that you would have otherwise had to endure.

...
*.ui-listview li.ui-btn-up-c,
*.ui-listview li.ui-btn-down-c,
*.ui-listview li.ui-btn-hover-c,
*.ui-listview li div.ui-btn-hover-c
  {
	background: #fff !important;
	font-weight: bold !important;
	color: #222 !important;
	
	background-color: none !important;
	background-image: none !important;
	background-image: -webkit-gradient(linear, left top, left bottom, from( #fff ), to( #f1f1f1 )) !important;
	background-image: -webkit-linear-gradient( #fff , #f1f1f1 ) !important;
	background-image: -moz-linear-gradient( #fff , #f1f1f1 ) !important;
	background-image: -ms-linear-gradient( #fff , #f1f1f1 ) !important;
	background-image: -o-linear-gradient( #fff , #f1f1f1 ) !important;
	background-image: linear-gradient( #fff , #f1f1f1 ) !important;

	border-top-style: solid !important;
	border-top-width: 0px !important;
	border-top-color: rgb(204, 204, 204) !important;
	
	border-bottom-style: solid;
	border-bottom-width: 1px;
	border-bottom-color: rgb(204, 204, 204) !important;
	box-shadow: none !important;
	
  }
...

In addition, if you’re using iScroll or iScrollView you’ll want to do the following:

  • Set vScrollbar to false – the presence of the scroll bar adds some overhead so remove it from view

And here’s an example of setting some defaults in iScrollView – notice that I reference getDeviceInfo() – see my previous article titled Mobile Device Detection using the UserAgent as the code there is assumed to be in use here. Of course you can use your own platform detection scripts. Anyway, you can see that I only use this setting in Android.

...
var _d = myapp.util.getDeviceInfo(); // my own device-detection library
if (_d.android){
    $.mobile.iscrollview.prototype.options.vScrollbar = false;
}
...

Shifty Fixed Headers

Symptoms:

  • When clicking the page the headers disappear
  • When clicking the page elements within the header or footer shift up or down.

Add the following to your application:

...
$("[data-role=header]").fixedtoolbar({ tapToggle: false });
...

I put the above in the “deviceready” event.

Alternatively you could add the following attribute to your header divs:

...
data-tap-toggle="false"
...

Flashing or Slow Page transitions

iOS does a good job with jQM’s page transition animations. Android is another matter. You will want to turn off page transitions entirely for Android.

...
$.extend( $.mobile,{
    var _d = myapp.util.getDeviceInfo(); // my own device-detection library
    defaultDialogTransition: (_d.android ? 'none' : 'pop'),
    defaultPageTransition:   (_d.android ? 'none' : 'fade'),
});
...

Manage DOM Bloat

If you have a multi-page app jQM will add each page into the app’s DOM as you navigate the app. The purpose is to “speed up” the app as jQM will no longer have to do any DOM insertion when future page requests happen. That’s all fine and good for desktop computers but it kind of stinks on mobile. The more that is added to the DOM the slower your app gets. Memory use for most apps is a major concern so you definitely want to disabling this, like so:

...
$.extend( $.mobile,{
    domCache: false
});
...

Another reason to disable is that events like pageload will only fire the very first time the page is inserted into the DOM. Thereafter, it doesn’t fire because the page has already been loaded (cached).

Preventing jQuery Mobile Page Flicker

11 Jun 2013

One irritating artifact of using jQuery Mobile is the page flickering that happens when changing pages – most noticeable on Android but sometimes on iOS as well. Here’s how to get rid of it…

First, make sure you have the proper viewport meta in your document:

...

...

This prevents the user from scaling the view as if it were a normal web page – every web app must have this in it.

Next, turn backfaces off via css like so:

...
.ui-page {
  -webkit-backface-visibility: hidden;
}
...

This last one assumes that you are not using native webview scrolling to scroll your content- I don’t know why you would want to – performance of native scrolling is spotty at best. So, assuming that you are not using native scrolling but are using iScroll instead then add this last item to your css:

...
body{
  overflow:hidden;
}
...

You’re done – no more flickering.

If you aren’t using iScroll but instead are relying on native webview scrolling then you will need to enable/disable the native scrolling programmatically during page transitions/loads. You can bind to the pagebeforechange event to do the toggling for your entire project. This event fires twice, once before and once after the page change, so you can do something similar to the following:

...

...
$('.selector').on('pagebeforechange', function(e){
  var isScrollable = !$('body').hasClass('preventNativeScroll');
  if (isScrollable){
    $('body').removeClass('preventNativeScroll');
  } else {
    $('body').addClass('preventNativeScroll');
  }
});
...

I’ve not tested the above – its only meant for illustration.

JQuery Mobile Checkboxes

31 Oct 2012

JQuery Mobile has some nice form element replacements that are more mobile device/touch-friendly than the way browsers currently present form elements. One of them is the visual replacement for a checkbox. To be clear the ugly checkbox is still there, its now layered underneath the JQM checkbox art.

The end results looks like this:

Click here to see a working example.

The docs IMO don’t quite tell you one critical thing – that certain tag attributes need to be identical in order for the framework to enhance the checkbox. If one of these is out of place you won’t get what you’re looking for.

Here’s how I implemented a checkbox today after trial and error:

...
  
...
  
...

According to the docs the only thing to pay attention to is to ensure that the LABEL tag’s for attribute value is the same as the INPUT tag’s name value so that they are semantically linked together and displayed appropriately by the framework. There is one critical piece of information and that’s the INPUT tag’s id – it too must be the same value as the previous two attribute values. Omit that last bit and you don’t get any visual enhancement of the CHECKBOX element.

As far as getting the label removed all that is needed (as can be seen in the code sample above) is to add data-iconpos=”notext” to the input tag.

Lastly, I wanted to set the width so I added a class to the FIELDSET element and that was it, my check box was created and ready to go.

A handy tip is the use of the jQuery trigger method when inserting checkboxes into your document after it has loaded. Doing so ensures that you get the visual enhancement.

For example:

...
var newcbox = '';
    newcbox = '';

// add html to DOM and "trigger" jQuery visual enhancement
$(newcbox).appendTo('#contentWrapper').trigger('create');
...