How to fire deviceready event in Chrome browser (trying to debug phonegap project)

JavascriptGoogle ChromeCordova

Javascript Problem Overview


I'm developing a PhoneGap application and I'd like to be able to debug it in Chrome rather than on the phone. However, I do the initialization of my code in an onDeviceReady() function that is triggered when PhoneGap fires the "deviceready" event. Since Chrome doesn't fire this event, my code isn't ever initialized.

Here's a stripped down version of my code:

var dashboard = {};

$(document).ready(function() {
    document.addEventListener("deviceready", dashboard.onDeviceReady, false);
}); 

dashboard.onDeviceReady = function() {
    alert("hello!"); //this is never fired in Chrome
};

I've tried using the [StopGap][1] code, which basically just does the following:

var e = document.createEvent('Events'); 
e.initEvent("deviceready");
document.dispatchEvent(e);

But when I run that code in the Chrome javascript console, the "hello" alert still doesn't trigger. What am I doing wrong? Or does chrome just not support firing "custom" events like deviceready?

[1]: https://github.com/alunny/stopgap "StopGap"

Javascript Solutions


Solution 1 - Javascript

Add this code to your onLoad handler function:

    if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/)) {
        document.addEventListener("deviceready", onDeviceReady, false);
    } else {
        onDeviceReady();
    }

Event "deviceready" is fired in cordova.js so I don't know a way to detect existence of this event in application code.

Solution 2 - Javascript

Ended up pulling out the StopGap code and having to introduce a tiny delay (have this code running in a separate script than page-specific code):

window.setTimeout(function() {
    var e = document.createEvent('Events'); 
    e.initEvent("deviceready", true, false); 
    document.dispatchEvent(e);
}, 50);

Solution 3 - Javascript

For my mobile site and mobile App I'm using the following code with jQuery:

function init() { ... };
if ("cordova" in window) {
	$(document).on("deviceready", init);
} else {
	$(init);
}

Solution 4 - Javascript

Use the Ripple Mobile Emulator. It is free on the Chrome Web Store. When it is installed, navigate to the page you want to test it on, right click the page and choose Ripple Mobile Emulator > Enable. When prompted, choose PhoneGap.

The emulator is good, but it is still in beta so not everything has been implemented yet.

Ad@m

Solution 5 - Javascript

I use Safari for debugging and do this:

//my standard PG device ready
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
//debug("onDeviceReady")
getDefaultPageSetup();

}

//then add this (for safari
window.onload = function () {
if(! window.device)
    onDeviceReady()
}

Solution 6 - Javascript

user318696 had the magic I was looking for. "device" is defined in cordova and does not get defined when in a browser (non-phoneGap app wrapper).

EDITED:

I ran into a scenario where Cordova took quite a while to initialize on a device and the "original" answer here was no longer valid. I have moved on to requiring a parameter on the URL when running tests in the browser. (in the example I'm looking for "testing=" in the url of the original page)

$(document).ready(function () {

	// ALWAYS LISTEN
	document.addEventListener("deviceready", main, false);

	// WEB BROWSER
	var url = window.location.href;
	if ( url.indexOf("testing=") > -1 ) {
		setTimeout(main, 500);
	}

});

ORIGINAL:

I haven't dug deeply enough to know how long to trust this [could they start defining "device" in the browser in a future release?] But at least up to 2.6.0 this is safe:

$(document).ready(function () {
	// call main from Cordova
	if ( window.device ) {
		document.addEventListener("deviceready", main, false);
	}

	// from browser
	else {
		main();
	}
});

Solution 7 - Javascript

user318696's window.device detection works well. If using Kendo UI Mobile and PhoneGap, the following script will enable functionality in both PhoneGap builds and web browsers. This is based on Burke Holland's PhoneGap Build Bootstrap Project for Kendo UI Mobile and is intended to be placed at the bottom of the page before the closing body tag.

    <script type="text/javascript">
    var tkj = tkj || {};

    tkj.run = (function () {
        // create the Kendo UI Mobile application
        tkj.app = new kendo.mobile.Application(document.body);
    });

    // this is called when the intial view shows. it prevents the flash of unstyled content (FOUC)
    tkj.show = (function () {
        $(document.body).show();
    });
    
    (function () {
        if (!window.device) {
            //initialize immediately for web browsers
            tkj.run();
        }
        else if (navigator.userAgent.indexOf('Browzr') > -1) {
            // blackberry
            setTimeout(tkj.run, 250)
        } else {
            // attach to deviceready event, which is fired when phonegap is all good to go.
            document.addEventListener('deviceready', tkj.run, false);
        }
    })();
    </script>

Solution 8 - Javascript

Enhancing Chemik suggestion. The following code uses navigator.userAgent string to generically determine if the client browser is on a mobile platform.

The purpose of the separation from desktop browsers is to allow code verifying prior to compiling/installing android apk, etc. It is much faster to make a quick code change, refresh desktop browser vs. compiling in eclipse and loading on android. Another added bonus is the ability to use weinre in one tab & the index.html from android assets in another tab (and use firebug).

PS: weinre code is excluded since it has my private VPS info & UUID.

thx!

<!-- Framework:jQuery -->
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.2, minimum-scale=1.0, maximum-scale=3.0, user-scalable=yes" >
<link  href="./framework/jquery/mobile/1.2.0/jquery.mobile-1.2.0.min.css" type="text/css" media="screen" rel="stylesheet" title="JQuery Mobile">
<script src="./framework/jquery/jquery-1.8.2.min.js"></script>
<script src="./framework/jquery/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>

<!-- Framework:Weinre -->

<!-- Framework:PhoneGap -->
<script src="./framework/phonegap/cordova-2.0.0.js" type="text/javascript" charset="utf-8"></script>

<script type="text/javascript" charset="utf-8">
	var mobile = false;
	if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/)) {
		document.addEventListener("deviceready", function(){mobile = true; onDeviceReady();}, false);
	} else {
		$(document).ready(onDeviceReady); 	
	}
	function onDeviceReady() {
		setEvents();
		test();
		if (mobile) {
			navigator.notification.alert("Debugging-ready for\n" + navigator.userAgent);
		} else {
			alert("Debugging-ready for\n" + navigator.userAgent);
		}
	};
</script>

Solution 9 - Javascript

You simulate events like this:

const simulateEvent = (eventName, attrs = {customData:"data"}, time = 1000, target = document) => {
    let event = new CustomEvent(eventName, { detail:  attrs });    
    setTimeout(() => {
        target.dispatchEvent(event);
    }, time);
};

var divReady = document.querySelector('div#ready');

document.addEventListener('deviceready', (e) => {
 console.log("triggered with:", e.detail);
 divReady.innerHTML = `Ready! ${JSON.stringify(e.detail)}`;
});

simulateEvent('deviceready', {customData:"My custom data goes in event.detail"});

<div id="ready"> Wait for ready... </div>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMaxView Question on Stackoverflow
Solution 1 - JavascriptChemikView Answer on Stackoverflow
Solution 2 - JavascriptMaxView Answer on Stackoverflow
Solution 3 - JavascriptjeroneView Answer on Stackoverflow
Solution 4 - JavascriptkirbView Answer on Stackoverflow
Solution 5 - JavascriptKatrinaView Answer on Stackoverflow
Solution 6 - JavascriptbladnmanView Answer on Stackoverflow
Solution 7 - JavascriptTaeKwonJoeView Answer on Stackoverflow
Solution 8 - JavascriptPage2PageProView Answer on Stackoverflow
Solution 9 - JavascriptPasquale MangialavoriView Answer on Stackoverflow