Comment utiliser JQuery-Mobile / Phonegap ensemble?


107

Quelle est la manière correcte (à ce jour) d'utiliser JQuery Mobile et Phonegap ensemble?

Les deux frameworks doivent se charger avant de pouvoir être utilisés. Comment puis-je être sûr que les deux sont chargés avant de pouvoir les utiliser?


11
S'il vous plaît ! choisissez une réponse !!!
realtebo

même si cela le mérite, je ne vais pas attribuer +1 jusqu'à ce qu'une réponse soit choisie <3
Don Vaughn

1
Quel est le problème réel résolu ici - que se passe-t-il si je viens de fournir des références aux fichiers js requis pour jQuery et Cordova dans mon index.html, puis que je redirige vers la page de connexion à partir d'un troisième fichier js en utilisant $ .mobile.changePage de jQuery? Je veux dire ce qui empêche cette conception de fonctionner et pourquoi ai-je besoin des solutions décrites ci-dessous? Est-ce parce qu'il y a des charges asynchrones dans jQuery et / ou Cordova et que mon 3ème fichier js pourrait être chargé avant même que les 2 frameworks ne soient chargés? Veuillez suggérer. Merci
Mustafa

@Mustafa par exemple, vous pouvez essayer d'accéder à la base de données AVANT que l' ondeviceReadyévénement ne soit déclenché à partir de votre code JQM ...
Mirko

Réponses:


174

Vous pouvez utiliser la fonctionnalité différée de JQuery.

var deviceReadyDeferred = $.Deferred();
var jqmReadyDeferred = $.Deferred();

document.addEventListener("deviceReady", deviceReady, false);

function deviceReady() {
  deviceReadyDeferred.resolve();
}

$(document).one("mobileinit", function () {
  jqmReadyDeferred.resolve();
});

$.when(deviceReadyDeferred, jqmReadyDeferred).then(doWhenBothFrameworksLoaded);

function doWhenBothFrameworksLoaded() {
  // TBD
}

3
cette réponse devrait obtenir plus de votes et être marquée comme la bonne.
memical

4
Pourriez-vous élaborer un peu plus s'il vous plaît? À quoi ressemble la hiérarchie des références de fichiers? Merci
farjam

2
S'il vous plaît, pourriez-vous ajouter l'ordre de chargement du script, en utilisant la dernière version ??
realtebo

7
Pour tous ceux qui disent que cela ne fonctionne pas, l'ordre de déclaration du script compte. Incluez d'abord jquery, PUIS CE CODE dans un élément de script, puis jquery mobile js.
Manish

1
Et quoi cordova.js? Doit-il être chargé avant ou après JQM?
Ferdinand.kraft

17

Voici comment cela a fonctionné pour moi, basé sur l'exemple ci-dessus

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <meta name="format-detection" content="telephone=no" />
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
        <link rel="stylesheet" type="text/css" href="css/bootstrap.css" />
        <title>InforMEA</title>
    </head>
    <body>
        <script type="text/javascript" src="js/jquery-1.8.3.js"></script>
        <script type="text/javascript">
            var dd = $.Deferred();
            var jqd = $.Deferred();
            $.when(dd, jqd).done(doInit);

            $(document).bind('mobileinit', function () {
                jqd.resolve();
            });
        </script>
        <script type="text/javascript" src="js/jquery.mobile-1.2.0.js"></script>
        <script type="text/javascript" src="cordova-2.2.0.js"></script>
        <script type="text/javascript">
            document.addEventListener('deviceready', deviceReady, false);
            function deviceReady() {
                dd.resolve();
            }

            function doInit() {
                alert('Ready');
            }
        </script>
    </body>
</html>

Cela a fonctionné pour moi aussi, mais si j'ajoute <div id = "test-index-page" data-role = "page"> </div> à la même page avant la fermeture de la balise html, la page ne se charge pas et j'obtiens des erreurs . Je veux commencer à utiliser les deux frameworks en utilisant un troisième fichier js à partir du moment où les deux sont chargés. Comment je fais ça?
Mustafa

Bien sûr, j'ai essayé de charger le 3ème fichier js qui a une logique métier pour mon application dans doInit () mais cela n'a pas fonctionné. Ce fichier a une logique de liaison d'événement et des déclarations de fonction, par exemple $ (document) .delegate ('# fakhera-index-page', 'pageinit', function (event) {...}. Comment puis-je faire cela?
Mustafa

7

Pour utiliser phonegap avec jquery mobile, vous devez l'utiliser comme ceci

<head>
<title>Index Page</title>

<!-- Adding viewport -->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no">

<!-- Adding jQuery scripts -->
<script type="text/javascript" src="jquery/jquery-1.7.1.min.js"></script>

<!-- Since jQuery Mobile relies on jQuery core's $.ajax() functionality,
 $.support.cors & $.mobile.allowCrossDomainPages must be set to true to tell
 $.ajax to load cross-domain pages. -->
<script type="text/javascript">
    $(document).bind("mobileinit", function() {
        $.support.cors = true;
        $.mobile.allowCrossDomainPages = true;
    });
</script>

<!-- Adding Phonegap scripts -->
<script type="text/javascript" charset="utf-8"
    src="cordova/cordova-1.8.0.js"></script>

<!-- Adding jQuery mobile scripts & CSS -->
<link rel="stylesheet" href="jquerymobile/jquery.mobile-1.1.0.min.css" />
<script type="text/javascript"
    src="jquerymobile/jquery.mobile-1.1.0.min.js"></script>

</head>
<script type="text/javascript">
    // Listener that will invoke the onDeviceReady() function as soon as phonegap has loaded properly
    document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
        navigator.splashscreen.hide();

        document.addEventListener("backbutton", onBackClickEvent, false); // Adding the back button listener    

    }
    </script>
<body>
<div data-role="page" id="something" data-ajax="false">
        <script type="text/javascript">
            $("#something").on("pageinit", function(e) {

            });

            $("#something").on("pageshow", function(e) {

            });

            $("#something").on("pagebeforeshow", function(e) {

            });
        </script>

        <div data-role="header">            
        </div>

        <div data-role="content">           
        </div>      
    </div>
</body>  

6

Comme beaucoup de gens l'ont suggéré, utiliser un différé est une option acceptable tant que vous ne vous souciez pas de l'ordre devicereadyet du mobileinitdéroulement. Mais dans mon cas, j'avais besoin de quelques pageshowévénements lors du premier chargement de l'application et mobileinit, par extension, ces événements pageshow/ pagebeforeshow/ etc étaient tous tir avant la devicereadyfin, donc je ne pouvais pas me lier à eux correctement en utilisant un différé sur eux. Cette condition de course n'était pas une bonne chose.

Ce que je devais faire, c'était m'assurer que «mobileinit» n'avait lieu qu'après que « deviceready» ait déjà été viré. Parce que se mobileinitdéclenche immédiatement lorsque vous chargez JQM, j'ai choisi de l'utiliser jQuery.getScriptpour le charger APRÈS avoir devicereadydéjà terminé.

<script src="cordova-2.2.0.js"></script>
<script src="js/jquery-1.8.2.min.js"></script>
<script src="js/async.min.js"></script>
<script src="js/app.js"></script>
<script>
  document.addEventListener(
    'deviceready',
    function () {
      $('body').css('visibility', 'hidden');
      $(document).one("mobileinit", function () {
        app.init();
        $('body').css('visibility', '');
      });
      $.getScript('js/jquery.mobile-1.2.0.min.js');
    },
    false
  );
</script>

La raison pour laquelle je cache le corps est qu'un effet secondaire de cette méthode est une demi-seconde de visibilité du document HTML d'origine avant le chargement de jquery.mobile. Dans ce cas, il est préférable de le masquer une demi-seconde supplémentaire d'espace vide plutôt que de voir le document sans style.


1
+1 sur votre réponse car cela m'a inspiré à résoudre mon problème avec un léger changement. Commencez par déplacer le code body.hide () sur la toute première ligne de onBodyLoad (); Deuxièmement, déplacez le code body.show () après getScript (jQM_PATH); Parce que mobileInit () est appelé à chaque transition de page JQM. Pas idéal. J'espère que cela aide les autres.
GeorgeW

Pouvez-vous simplement inclure le reste de votreindex.html
JGallardo

Cela n'a pas fonctionné pour moi car cordova supprimait tous les fichiers qui n'étaient pas inclus à l'aide de la <script>balise.
Chris Snow

2

Je pense qu'il n'est pas nécessaire d'utiliser la fonction différée. (Peut-être que ce n'est pas nécessaire avec les nouvelles versions de phonegap?) J'ai ceci dans la tête de mon fichier index.html et tout fonctionne bien. Je pense que l'ordre d'inclusion de jquery, phonegap et jquery mobile est important.

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta name="format-detection" content="telephone=no" />
    <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />

    <!-- Adding jQuery -->
    <script type="text/javascript" src="js/jquery-1.9.1.min.js"></script>

    <!-- Add Phonegap scripts -->
    <script type="text/javascript" src="phonegap.js"></script>

    <!-- Add jQuery mobile -->
    <link rel="stylesheet" href="css/jquery.mobile-1.3.2.css" />
    <script type="text/javascript" src="js/jquery.mobile-1.3.2.min.js"></script>

    <title>MY TITLE</title>
</head>

1

c'est du travail pour moi. base sur dhaval, cet exemple lorsque j'apprends à utiliser sqlite

<!DOCTYPE html>
<html>
 <head>
<title>Cordova Sqlite+Jquery</title>
<script type="text/javascript" charset="utf-8" src="js/jquery-1.8.3.min.js"></script>   
<script type="text/javascript" charset="utf-8" src="cordova-2.2.0.js"></script>
<script type="text/javascript" charset="utf-8">`

// Call onDeviceReady when Cordova is loaded.
//
// At this point, the document has loaded but cordova-1.8.0.js has not.
// When Cordova is loaded and talking with the native device,
// it will call the event `deviceready`.
//
function onLoad() {
    document.addEventListener("deviceready", onDeviceReady, false);
}

// Populate the database 
//
function populateDB(tx) {
    tx.executeSql('DROP TABLE IF EXISTS DEMO');
    tx.executeSql('CREATE TABLE IF NOT EXISTS DEMO (id unique, data)');
    tx.executeSql('INSERT INTO DEMO (id, data) VALUES (1, "First row")');
    tx.executeSql('INSERT INTO DEMO (id, data) VALUES (2, "Second row")');
}

// Query the database
//
function queryDB(tx) {
    tx.executeSql('SELECT * FROM DEMO', [], querySuccess, errorCB);
}

// Query the success callback
//
function querySuccess(tx, results) {
    var len = results.rows.length;
    //console.log("DEMO table: " + len + " rows found.");
    $('#result').html("DEMO table: " + len + " rows found.");
    var listval = '';
    for (var i=0; i<len; i++){
        //console.log("Row = " + i + " ID = " + results.rows.item(i).id + " Data =  " + results.rows.item(i).data);
         listval += '<li>'+ results.rows.item(i).data + '[' + results.rows.item(i).id + '] </li>';
    }

    $('#listItem').html(listval);

}

// Transaction error callback
//
function errorCB(err) {
    console.log("Error processing SQL: "+err.code);
}

// Transaction success callback
//
function successCB() {
    var db = window.openDatabase("Database", "1.0", "PhoneGap Demo", 200000);
    db.transaction(queryDB, errorCB);
}

// Cordova is loaded and it is now safe to make calls Cordova methods
//
function onDeviceReady() {
    // Now safe to use the Cordova API
    //alert('ready');
    var db = window.openDatabase("Database", "1.0", "PhoneGap Demo", 200000);
    db.transaction(populateDB, errorCB, successCB);
    //$('#result').html('hello');
}

</script>
  </head>
 <body onload="onLoad()">
  <div>result:</div><div id="result"></div>
  <ul id="listItem">
  </ul>
 </body>
 </html>

0

Pour construire sur la réponse de @ Jeffrey, j'ai trouvé un moyen beaucoup plus propre qui cache le balisage HTML jusqu'à ce que JQM ait fini de traiter la page et rende le premier élément Page, car j'ai remarqué que 1/2 seconde de scintillement de balisage nu avant le rendu de JQM.

Il vous suffit de masquer tout le balisage avec css ... PageShow () by JQM basculera la visibilité pour vous.

//snip
<style type="text/css">
.hide {
  display:none;
}
</style>

//snip - now the markup notice the hide class
<div id="page1" data-role="page" class="hide">
     //all your regular JQM / html form markup
</div>

//snip -- down to the end of /body
<script src="cordova-2.2.0.js"></script>
<script src="js/jquery-1.8.2.min.js"></script>
<script>
   document.addEventListener(
     'deviceready',
      function () {
         $(document).one("mobileinit", function () {
         //any JQM init methods

       });
      $.getScript('js/jquery.mobile-1.2.0.min.js');
   },
   false);
</script>


essayé votre suggestion et cela n'a pas fonctionné pour moi. Le diaporama JQM n'affichera pas la première page masquée. De plus, le HTML standard apparaît toujours avant d'être masqué. Je l'ai finalement fait fonctionner sur la base de la solution de Jeffrey avec un léger changement de timing. voir mon commentaire ci-dessous sa réponse.
GeorgeW

0

Ce qui suit a fonctionné pour moi sur PG 2.3 et JQM 1.2, incl. Plugin Facebook Connect:

<head>
<script src="./js/jquery-1.8.2.min.js"></script>
<script>
    $.ajaxSetup({
        dataType : 'html'
    });

    var dd = $.Deferred();
    var jqd = $.Deferred();
    $.when(dd, jqd).done(function() {                

        FB.init({ appId: auth.fbId, nativeInterface: CDV.FB, useCachedDialogs: false });
    });

    $(document).bind('mobileinit', function () {
        jqd.resolve();
    });                        
</script>
<script src="./js/jquery.mobile-1.2.0.min.js"></script>
<script>
    $.mobile.loader.prototype.options.text = "loading";
    $.mobile.loader.prototype.options.textVisible = true;
    $.mobile.loader.prototype.options.theme = "a";
    $.mobile.loader.prototype.options.html = "";

    $.mobile.ajaxEnabled = false;
    $.mobile.allowCrossDomainPages = true;
    $.support.cors = true;       

    $('[data-role=page]').live('pagecreate', function(event) {                      
        tpl.renderReplace('login', {}, '#content-inner', function() {                   
            auth.init();
        });
    });
</script>
<script src="./js/cordova-2.3.0.js"></script>
<script src="./js/cdv-plugin-fb-connect.js"></script>
<script src="./js/facebook_js_sdk.js"></script>                     
<!--some more scripts -->
<script>        
    document.addEventListener('deviceready', function() {
        dd.resolve();
    }, false);                        
</script>  
<head>

-1

Le chargement de PhoneGap est légèrement différent du chargement de jQuery. jQuery fonctionne davantage comme une bibliothèque d'utilitaires, vous incluez donc cela et il est immédiatement disponible. D'autre part, PhoneGap nécessite la prise en charge du code natif pour une initialisation correcte, de sorte qu'il n'est pas prêt à être utilisé peu de temps après son inclusion dans la page.

Phonegap suggère de s'inscrire et d'attendre l' devicereadyévénement exécutant un code spécifique natif.

<!DOCTYPE html>
<html>
  <head>
    <title>PhoneGap Example</title>

    <script type="text/javascript" charset="utf-8" src="lib/jquery.min.js"></script>
    <script type="text/javascript">
        // jquery code here
    </script>
    <script type="text/javascript" charset="utf-8" src="lib/android/cordova-1.7.0.js"></script>
    <script type="text/javascript" charset="utf-8">

    function onLoad(){
        document.addEventListener("deviceready", onDeviceReady, false);
    }

    // Cordova is ready
    function onDeviceReady() {
        // write code related to phonegap here
    }
    </script>
  </head>
  <body onload="onLoad()">
    <h1>Phonegap Example</h1>
  </body>
</html>

Pour plus d'informations, consultez la doc


1
Mais le problème est que je veux utiliser des éléments de phonegap dans mon code jquery. Dans votre exemple, tout le code jquery serait exécuté avant même que phonegap ne soit chargé. Peut-être que si je mets tout le code dans la fonction onDeviceReady ()? Comme ceci: $ ("# form"). Live ("pageinit", function (event) {// phonegapp stuff here});
Juw

si vous #formêtes la première page, vous ne recevrez pas de pageinitrappel car il est trop tard
dhaval
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.