Modo corretto di utilizzare JQuery-Mobile / Phonegap insieme?


107

Qual è il modo corretto (fino ad oggi) di utilizzare JQuery Mobile e Phonegap insieme?

Entrambi i framework devono essere caricati prima di poter essere utilizzati. Come posso essere sicuro che entrambi siano caricati prima di poterli utilizzare?


11
per favore ! scegli una risposta !!!
realtebo

anche se lo merita, non farò +1 su questo fino a quando non verrà scelta una risposta <3
Don Vaughn

1
Qual è il vero problema che viene risolto qui - e se fornissi solo riferimenti ai file js richiesti per jQuery e Cordova nel mio index.html e poi reindirizzassi per dire pagina di accesso da un terzo file js usando $ .mobile.changePage di jQuery? Voglio dire, cosa impedisce a questo progetto di funzionare e perché ho bisogno delle soluzioni descritte di seguito? È perché ci sono carichi asincroni all'interno di jQuery e / o Cordova e il mio terzo file js potrebbe essere caricato anche prima che i 2 framework vengano caricati? Per favore suggerisci. Grazie
Mustafa

@Mustafa per esempio potresti provare ad accedere al database PRIMA che l' ondeviceReadyevento si attivi dal tuo codice JQM ...
Mirko

Risposte:


174

Puoi utilizzare la funzione differita di 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
questa risposta dovrebbe ottenere più voti ed essere contrassegnata come quella corretta.
memical

4
Potresti approfondire un po 'di più per favore? Qual è la gerarchia dei riferimenti ai file? Grazie
farjam

2
Per favore, potresti aggiungere l'ordine di caricamento dello script, utilizzando l'ultima versione ??
realtebo

7
Per tutti coloro che dicono che non funziona, l'ordine di dichiarazione del copione è importante. Prima includi jquery, POI QUESTO CODICE all'interno di un elemento script, quindi jquery mobile js.
Manish

1
Di cosa cordova.js? Dovrebbe essere caricato prima o dopo JQM?
Ferdinand.kraft

17

Ecco come ha funzionato per me, sulla base dell'esempio sopra

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

Questo ha funzionato anche per me, ma se aggiungo <div id = "test-index-page" data-role = "page"> </div> alla stessa pagina prima che il tag html si chiuda, la pagina non si carica e ricevo errori . Voglio iniziare a utilizzare entrambi i framework utilizzando un terzo file js dal punto in cui vengono caricati entrambi. Come lo faccio?
Mustafa

Ovviamente ho provato a caricare il terzo file js che ha una logica di business per la mia app in doInit () ma non ha funzionato. Quel file ha una logica di associazione di eventi e dichiarazioni di funzioni, ad esempio $ (document) .delegate ('# fakhera-index-page', 'pageinit', function (event) {...}. Come posso farlo?
Mustafa

7

Per poter utilizzare phonegap insieme a jquery mobile, devi usarlo in questo modo

<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

Poiché molte persone hanno suggerito di utilizzare un differito è un'opzione accettabile fintanto che non ti interessa quale ordine devicereadye cosa è mobileinitsuccesso. Ma nel mio caso, avevo bisogno di alcuni pageshoweventi quando l'applicazione è stata caricata per la prima volta mobileinite per estensione quegli eventi pageshow/ pagebeforeshow/ etc erano sparavano tutti prima che devicereadyfinissero, quindi non potevo legarmi correttamente usando un differito su di loro. Questa condizione di gara non era una buona cosa.

Quello che dovevo fare era assicurarmi che 'mobileinit' non avesse luogo fino a dopo che ' deviceready' era già stato licenziato. Poiché mobileinitsi attiva immediatamente quando carichi JQM, ho scelto di utilizzarlo jQuery.getScriptper caricarlo DOPO che devicereadyfosse già finito.

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

Il motivo per cui nascondo il corpo è che un effetto collaterale di questo metodo è mezzo secondo di visibilità del documento HTML originale prima del caricamento di jquery.mobile. In questo caso è preferibile nascondere un mezzo secondo in più di spazio vuoto piuttosto che vedere il documento senza stile.


1
+1 sulla tua risposta perché mi ha ispirato a risolvere il mio problema con qualche leggera modifica. Per prima cosa, sposta il codice body.hide () sulla prima riga di onBodyLoad (); Secondo, sposta il codice body.show () in modo che sia dopo getScript (jQM_PATH); Perché mobileInit () viene chiamato su ogni transizione di pagina JQM. Non è l'ideale. Spero che questo aiuti gli altri.
GeorgeW

Puoi semplicemente includere il resto del tuoindex.html
JGallardo

Questo non ha funzionato per me perché cordova stava rimuovendo tutti i file non inclusi utilizzando il <script>tag.
Chris Snow

2

Credo che non sia necessario utilizzare la funzione differita. (Forse questo non è necessario con le versioni più recenti di phonegap?) Ce l'ho nella testa del mio file index.html e tutto funziona bene. Penso che l'ordine di includere jquery, phonegap e jquery mobile sia importante.

<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

questo è lavoro per me. base su dhaval, questo esempio quando imparo a usare 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

Per basarmi sulla risposta di @ Jeffrey, ho trovato un modo molto più pulito che nasconde il markup HTML fino a quando JQM non ha terminato l'elaborazione della pagina e rende il primo elemento Page, poiché ho notato che uno sfarfallio di 1/2 secondo di markup nudo prima del rendering di JQM.

Hai solo bisogno di nascondere tutto il markup con css ... PageShow () di JQM cambierà la visibilità per te.

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


ho provato il tuo suggerimento e non ha funzionato per me. Pageshow di JQM non mostrerà la prima pagina nascosta. Inoltre, l'html standard viene visualizzato ancora prima di essere nascosto. Alla fine l'ho fatto funzionare sulla base della soluzione di Jeffrey con un leggero cambiamento di tempistica. vedere il mio commento sotto la sua risposta.
GeorgeW

0

Quanto segue ha funzionato per me su PG 2.3 e 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

Il caricamento di PhoneGap è leggermente diverso dal caricamento di jQuery. jQuery funziona più come una libreria di utilità in modo da includerla ed è disponibile per l'uso immediatamente. D'altra parte PhoneGap richiede il supporto del codice nativo per una corretta inizializzazione, quindi non è pronto per l'uso subito dopo l'inclusione nella pagina.

Phonegap suggerisce di registrarsi e attendere l' devicereadyevento che esegue qualsiasi codice specifico nativo.

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

Per maggiori informazioni consultare il doc


1
Ma il problema è che voglio usare roba phonegap nel mio codice jquery. Nel tuo esempio tutto il codice jquery verrebbe eseguito prima ancora che phonegap venga caricato. Forse se inserisco tutto il codice all'interno della funzione onDeviceReady ()? In questo modo: $ ("# form"). Live ("pageinit", function (event) {// phonegapp stuff here});
Giovedì

se la tua #formè la prima pagina, non riceverai la pageinitrichiamata perché è troppo tardi
dhaval
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.