15

I am trying to define the correct way to register both initialization events (jQuery-style) for PhoneGap and jQuery Mobile in an Android application.

After studying the documentation, I came up with the following:

$('#index-page').live('pageinit', function () { // <-- fires
    $(document).bind('deviceready', function () { // <-- !fires
        // ...
    });
});

The "outer" event (pageinit) fires and the "inner" (deviceready) does not...

Although, this type of event registration works perfectly:

window.addEventListener('load', function () {
    document.addEventListener('deviceready', function () {
        // ...
    }, false);
}, false);

Can anybody explain what's wrong with the first type of event registration? What type is better?


Prerequisites:

  • PhoneGap v1.2
  • jQuery Mobile v1.0rc2
  • Eclipse v3.7.1
John Doe
  • 4,574
  • 2
  • 26
  • 30

3 Answers3

14

I find the use of deferred objects cleaner/safer in this case. This is what I usually do:

var jqmReady = $.Deferred();
var pgReady = $.Deferred();

// jqm ready
$(document).bind("mobileinit", jqmReady.resolve);

// phonegap ready
document.addEventListener("deviceready", pgReady.resolve, false);

// all ready :)
$.when(jqmReady, pgReady).then(function () {
  // do your thing
});
Michal Kuklis
  • 871
  • 11
  • 14
  • This is so much better than the "standard" callback mess that Cordova/PhoneGap uses. – ocodo Feb 25 '13 at 21:36
  • Ideally I would do this inside index.html. Right? Also instead of /* do your thing */ I want to give a call to a JS file that has all the live or deferred events for my app so that I can have a central place where all the events are registered by me. Is it possible? Is it a good design? If yes, how do I achieve that? I tried using $.getScript but that renders a blank page for my app. Please suggest. – Asif Aug 15 '13 at 16:19
  • @Mustafa you can use a closure, and create a module that initialises everything. Then instead of /* do your thing */ you call `yourModule.yourInitMethod();` – Paranoid Android Sep 11 '13 at 09:22
  • I made some changes (read clean up) to all the JS in index.html and now getScript works. Thanks for your answer. – Asif Sep 11 '13 at 20:18
  • @All And, in which part I must include the code for the "backbutton" event? – Paul Vargas Feb 14 '14 at 21:29
7

I would go farther with Michael's example, and trigger a custom 'PG_pageinit' JavaScript event. This will trigger after both events ('pageinit', 'deviceready') have been fired. This way, you only need to change the name of the registered event at your (already written) external JavaScript files.

So, using Michael's code (with a minor change from the 'mobileinit' event to 'pageinit'):

var jqmReady = $.Deferred(),
pgReady = $.Deferred();

// jqm page is ready
$(document).bind("pageinit", jqmReady.resolve);

// phonegap ready
document.addEventListener("deviceready", pgReady.resolve, false);

// all ready, throw a custom 'PG_pageinit' event
$.when(jqmReady, pgReady).then(function () {
  $(document).trigger("PG_pageinit"); 
});

And on your other JavaScript files, whenever you want to register this new event, use this:

$(document).bind("PG_pageinit", function(){
  alert('PG_pageinit was just fired!');    
  // do your thing...
});

Tested on Android 2.3, cordova 1.9.0

Roei Bahumi
  • 3,433
  • 2
  • 20
  • 19
6

Please stick with the last one because this is recommended by PhoneGap, your first approach probably isn't working because you are binding deviceready too late (ie: it is already fired before your bind). Thats because pageinit is fired relatively late.

What you can do is the jQuery way:

$(window).load(function() {
    $(document).bind('deviceready', function () { 
        // ...
    });
});
GerjanOnline
  • 1,871
  • 16
  • 17
  • 1
    Sticking to the W3C event registration model works great... As for the suggested jQuery-style it does not work for me: the `deviceready` event does not fire... Thanks for advice! – John Doe Nov 28 '11 at 09:28