Reputation: 1218
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 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?
Upvotes: 58
Views: 37411
Reputation: 81
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>
Upvotes: 1
Reputation: 1218
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);
Upvotes: 14
Reputation: 2651
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();
}
});
Upvotes: 6
Reputation: 1177
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>
Upvotes: 3
Reputation: 16881
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);
}
Upvotes: 9
Reputation: 168
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>
Upvotes: 1
Reputation: 1479
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.
Upvotes: 73
Reputation: 79
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()
}
Upvotes: 7
Reputation: 2049
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
Upvotes: 8