web-dev-qa-db-fra.com

Comment déclencher un événement deviceready dans Chrome (essayant de déboguer le projet phonegap)

Je développe une application PhoneGap et j'aimerais pouvoir la déboguer dans Chrome plutôt que sur le téléphone. Cependant, je fais l'initialisation de mon code dans une fonction onDeviceReady () qui est déclenché lorsque PhoneGap déclenche l'événement "deviceready". Puisque Chrome ne déclenche pas cet événement, mon code n'est jamais initialisé.

Voici une version allégée de mon code:

var dashboard = {};

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

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

J'ai essayé d'utiliser le code StopGap , qui fait essentiellement ce qui suit:

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

Mais lorsque j'exécute ce code dans la console Chrome javascript, l'alerte "bonjour" ne se déclenche toujours pas. Que fais-je de mal? Ou chrome ne prend tout simplement pas en charge le déclenchement d'événements "personnalisés" comme deviceready?

58
Max

Ajoutez ce code à votre fonction de gestionnaire onLoad:

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

L'événement "deviceready" est déclenché dans cordova.js, donc je ne connais pas de moyen de détecter l'existence de cet événement dans le code d'application.

70
Chemik

J'ai fini par extraire le code StopGap et avoir à introduire un petit retard (avoir ce code en cours d'exécution dans un script distinct du code spécifique à la page):

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

Utilisez l'émulateur mobile Ripple. Il est gratuit sur le Chrome Web Store. Lorsqu'il est installé, accédez à la page sur laquelle vous souhaitez le tester, cliquez avec le bouton droit sur la page et choisissez Ripple Mobile Emulator> Activer. Lorsque vous y êtes invité, choisissez PhoneGap.

L'émulateur est bon, mais il est toujours en version bêta donc tout n'est pas encore implémenté.

Ad @ m

8
kirb

Pour mon site mobile et mon application mobile, j'utilise le code suivant avec jQuery:

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

J'utilise Safari pour le débogage et je fais ceci:

//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()
}
7
Katrina

user318696 avait la magie que je cherchais. "périphérique" est défini dans cordova et n'est pas défini dans un navigateur (wrapper d'application non-phoneGap).

ÉDITÉ:

Je suis tombé sur un scénario où Cordova a mis un certain temps à s'initialiser sur un appareil et la réponse "originale" ici n'était plus valide. Je suis passé à exiger un paramètre sur l'URL lors de l'exécution des tests dans le navigateur. (dans l'exemple je cherche "testing =" dans l'url de la page d'origine)

$(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:

Je n'ai pas creusé assez profondément pour savoir combien de temps faire confiance à cela [pourraient-ils commencer à définir "périphérique" dans le navigateur dans une future version?] Mais au moins jusqu'à 2.6.0, c'est sûr:

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

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

la détection window.device de user318696 fonctionne bien. Si vous utilisez Kendo UI Mobile et PhoneGap, le script suivant activera la fonctionnalité dans les versions de PhoneGap et les navigateurs Web. Ceci est basé sur Burke Holland PhoneGap Build Bootstrap Project for Kendo UI Mobile et est destiné à être placé en bas de la page avant la balise de fermeture du corps.

    <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>
3
TaeKwonJoe

Amélioration de la suggestion Chemik. Le code suivant utilise la chaîne navigator.userAgent pour déterminer de manière générique si le navigateur client se trouve sur une plate-forme mobile.

Le but de la séparation des navigateurs de bureau est de permettre la vérification du code avant de compiler/installer Android apk, etc. Il est beaucoup plus rapide d'effectuer un changement de code rapide, d'actualiser le navigateur de bureau par rapport à la compilation dans Eclipse et chargement sur Android. Un autre bonus supplémentaire est la possibilité d'utiliser weinre dans un onglet et l'index.html de Android dans un autre onglet (et d'utiliser Firebug).

PS: le code weinre est exclu car il contient mes informations VPS et UUID privés.

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>
1
Page2PagePro

Vous simulez des événements comme celui-ci:

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>
1