jQuery Mobile and backbone.js, the ugly

jQuery Mobile is a great technology, no doubt it can be an integral part of the future like jQuery is today. However even if the 1.0 version is out after more than a year after the alpha has been launched, it still feels like a very young product. There is enough posts and beginner tutorials around the web about the greatness of jQuery mobile. But not so much about the hurdles of jQuery mobile integrated in other systems. Let’s dive right into that.

Animations are a problem

Unless you are developing solely for the iPhone, you’ve got a problem. Animations are slow on Android and nobody else except iOs has 3d animations (it defaults to some weird stuff on other platforms). On my Sony Xperia the interface also becomes jaggy (missing anti-aliasing) and is looking weird when animating. For that reason if you’re going multiple platforms with your app you better disable them completely, or only use them on iPhone.

Example :

if((!navigator.userAgent.match(/iPhone/i)) || (!navigator.userAgent.match(/iPod/i))) {
  $.extend(  $.mobile , {
    defaultPageTransition:"none",
    defaultDialogTransition:"none"
  });
}

However if you still use the transitions in your code you overwrite the defaults. You will have to create a way to also check if you are on iPhone and go from there. In fact the required code would look like this:

var iosDevice = ((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i))) ? true : false;
 
  $.extend(  $.mobile , {
    slideText :  (iosDevice) ? "slide" : "none",
    slideUpText :  (iosDevice) ? "slideup" : "none",
    defaultPageTransition:(iosDevice) ? "slide" : "none",
    defaultDialogTransition:(iosDevice) ? "slide" : "none"
  });

Routing jQmobile can be hard if you overwrite it’s router

If you use backbone.js you don’t want jQuery mobile messing up with your routing. Unfortunately it’s not that easy. You will have to use changePage() and other plugins to render views on the fly.

It’s also going to be a problem to handle transitions’ direction. Personally while I do not have a complete solution, here an example of what I do.

wedapp.router.TasksMobile = Backbone.Router.extend({
 
	routes: {
		"/tasks":  	"list"
	 },
	list: function(){
		if(this.listContainerView){
			$.mobile.changePage($(this.listContainerView.el), "slide", false, false);
			return false;
		}
		this.listContainerView = new wedapp.view.TasksContainerMobile({
			model:wedapp.model.tasks,
			collection:wedapp.collection.tasks
		}).render().el;
		$("body").append(this.listContainerView);	
                $.mobile.changePage($(this.listContainerView),{ transition: "slide"})
		wedapp.collection.tasks.fetch();	
	 }
});

I check if my page already exists and if it does, I reload it instead of creating a new one and move to it. Of course I still only have one transition option, but that’s something we can arrange later using a status variable.

You will have to use a lot of listview(‘refresh’) when you add or modify stuff in your models and collections.

Data can be a bitch with dialogs, specially with backbone.js

jQMobile dialogs are more than just dialogs, they are entirely pages themselves. This mean you can’t go about deleting your views when you change a page, you need to keep them when you use dialogs with their contents or always update the model.

This comes has a problem with datepickers for example, they are pages, and they think they got routing control to replace content in your form view. Well since they don’t, nothing is going to set by itself.

And last

If you use backbone.js you can forget that beautiful compatibility table, your javascript pretty much messes all the browsers outside the A grade.

Still I think it is worth it for all the goodies and support you will get in the future. But it would not be “that” much work to create a layout for webkit mobile, specially if you are not going to use the transitions.

Cedric Dugas is a front-end veteran with more than 9 years under the belt, between his open source projects & entrepreneurial ambitions he is a product architect at CakeMail. Why don't you follow him on twitter.

9 Comments on "jQuery Mobile and backbone.js, the ugly"

  1. What about sniffing css transition instead of mobile browser using Modernizr?
    New device with newer version of Android will surely have better support for css transition and animation and will benefit from this feature sniffing.

    • Cedric Dugas says:

      Transitions are currently available in android, and test of jQuery mobile on android 4.0 show poor performances, for now. You would also be stuck with transitions on phone that support it but got poor hardware.

      If you are talking about 3d stuff than yes, it’s definitely a pretty good idea.

  2. azicchetti says:

    Hi,
    I usually replace backbone.js router with a custom jquery mobile plugin built around its event system. I think this is both a simpler an more powerful solution. If you want to check it out, its name on github is jquerymobile-router.

  3. Alan Huffman says:

    Are you turning off any of the routing? Do you have a solution that works? Over-riding the routing is super not fun.

    $(document).bind(“mobileinit”, function(){
    /////////////////////////////
    // cut off all the routing //
    $.mobile.autoInitializePage = false;
    $.mobile.ajaxEnabled = false;
    $.mobile.linkBindingEnabled = false;
    $.mobile.hashListeningEnabled = false;
    $.mobile.pushStateEnabled = false;
    ////////////////////////////
    });

  4. Cedric Dugas says:

    I decided to let go jquery mobile in the end, it was more problems than it was worth for me. It try to do to much without giving me enough control,

    Since I only target android and ios I did not had a need for all the overhead of the support grid. I use position fixed (that default absolute in ios4 and andr 2.2) and a nice and clean mobile layout. Only thing I am missing is animations (and I don’t find I miss it much)

    • Tyrone says:

      When you open up the demo solution and find !important everywhere, you know it’s going to be a nightmare to try overwrite and customize styles. Also the overhead is quite huge. 440kb unminified. Combine that with Backbone, Handlebars and all other dependancies, you have quite a hefty frontend stack especially for mobile.

  5. Charlie says:

    If you let go of jquery mobile, what did you move towards using?

  6. Josh Schneider says:

    (Still) using jQM with Knockout and Sammy, and using all the usual jQM config settings to allow Sammy to control routing (including $.mobile.linkBindingEnabled=false), but now older Android, particularly, has issues with link event handling. Not only are jQM link event styles disabled, but the entire event goes unhandled. Works in other phones. Anyone have a workaround they’ve used to fix this issue?

Got something to say? Go for it!