Richtige Verwendung von JQuery-Mobile / Phonegap zusammen?


107

Was ist der richtige Weg (bis zu diesem Datum), um JQuery Mobile und Phonegap zusammen zu verwenden?

Beide Frameworks müssen geladen werden, bevor sie verwendet werden können. Wie kann ich sicher sein, dass beide geladen sind, bevor ich sie verwenden kann?


11
Bitte ! wähle eine Antwort !!!
Realtebo

Obwohl es es verdient, werde ich dies nicht +1 tun, bis eine Antwort gewählt wird <3
Don Vaughn

1
Was ist das eigentliche Problem, das hier gelöst wird? Was wäre, wenn ich nur Verweise auf die erforderlichen js-Dateien für jQuery und Cordova in meiner index.html angegeben und dann mit jQuerys $ .mobile.changePage zur Anmeldeseite einer dritten js-Datei umgeleitet hätte? Ich meine, was verhindert, dass dieses Design funktioniert, und warum brauche ich die unten beschriebenen Lösungen? Liegt es daran, dass in jQuery und / oder Cordova asynchrone Ladevorgänge vorhanden sind und meine 3. js-Datei geladen werden könnte, noch bevor die beiden Frameworks geladen werden? Bitte vorschlagen. Danke
Mustafa

@ Mustafa zum Beispiel könnten Sie versuchen, auf die Datenbank zuzugreifen, ondeviceReadybevor das Ereignis von Ihrem JQM-Code ausgelöst wird ...
Mirko

Antworten:


174

Sie können die verzögerte Funktion von JQuery verwenden.

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
Diese Antwort sollte mehr Stimmen erhalten und als die richtige markiert werden.
Memical

4
Könnten Sie bitte etwas näher darauf eingehen? Wie sieht die Hierarchie der Dateiverweise aus? Vielen Dank
Farjam

2
Könnten Sie bitte die Reihenfolge des Ladens des Skripts mit der neuesten Version hinzufügen?
Realtebo

7
Für alle, die sagen, dass es nicht funktioniert - die Reihenfolge der Deklaration des Skripts ist wichtig. Fügen Sie zuerst jquery, dann DIESEN CODE in ein Skriptelement und dann jquery mobile js ein.
Manish

1
Was ist mit cordova.js? Sollte es vor oder nach JQM geladen werden?
Ferdinand.kraft

17

Hier ist, wie es für mich funktioniert hat, basierend auf dem obigen Beispiel

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

Dies hat auch bei mir funktioniert, aber wenn ich <div id = "test-index-page" data-role = "page"> </ div> zur selben Seite hinzufüge, bevor das HTML-Tag geschlossen wird, wird die Seite nicht geladen und es werden Fehler angezeigt . Ich möchte beide Frameworks mit einer dritten js-Datei ab dem Zeitpunkt verwenden, an dem beide geladen sind. Wie mache ich das?
Mustafa

Natürlich habe ich versucht, die 3. js-Datei mit Geschäftslogik für meine App in doInit () zu laden, aber es hat nicht funktioniert. Diese Datei enthält Ereignisbindungslogik und Funktionsdeklarationen, z. B. $ (document) .delegate ('# fakhera-index-page', 'pageinit', function (event) {...}. Wie kann ich das tun?
Mustafa

7

Um phonegap zusammen mit jquery mobile zu verwenden, müssen Sie es so verwenden

<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

Wie viele Leute vorgeschlagen haben, ist die Verwendung einer verzögerten Option in Ordnung, solange es Ihnen egal ist, in welcher Reihenfolge devicereadyund mobileinitin welcher Reihenfolge . Aber in meinem Fall brauchte ich einige pageshowEreignisse, als die Anwendung zum ersten Mal geladen wurde, mobileinitund im weiteren Sinne waren diese pageshow/ pagebeforeshow/ etc-Ereignisse Alle feuerten, bevor sie devicereadyfertig waren, so dass ich mich nicht richtig an sie binden konnte, indem ich sie aufschob. Diese Rennbedingung war keine gute Sache.

Was ich tun musste, war sicherzustellen, dass 'mobileinit' erst stattfand, nachdem ' deviceready' bereits gefeuert wurde. Da es mobileinitbeim Laden von JQM sofort ausgelöst wird, habe ich mich für das Laden entschieden, nachdem jQuery.getScriptes devicereadybereits fertig war.

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

Der Grund, warum ich den Körper verstecke, ist, dass ein Nebeneffekt dieser Methode eine halbe Sekunde der Sichtbarkeit des ursprünglichen HTML-Dokuments ist, bevor jquery.mobile geladen wird. In diesem Fall wird das Ausblenden einer zusätzlichen halben Sekunde des leeren Speicherplatzes dem Anzeigen des nicht gestalteten Dokuments vorgezogen.


1
+1 auf Ihre Antwort hat mich dazu inspiriert, mein Problem mit einer kleinen Änderung zu lösen. Verschieben Sie zuerst den Code body.hide () in die erste Zeile von onBodyLoad (). Verschieben Sie zweitens den Code body.show () nach getScript (jQM_PATH). Weil mobileInit () bei jedem JQM-Seitenübergang aufgerufen wird. Nicht ideal. Hoffe das hilft anderen.
GeorgeW

Können Sie nur den Rest Ihrerindex.html
JGallardo

Dies funktionierte bei mir nicht, da Cordova alle Dateien entfernte, die nicht mit dem <script>Tag enthalten waren.
Chris Snow

2

Ich glaube, dass es nicht notwendig ist, die verzögerte Funktion zu verwenden. (Vielleicht ist dies bei neueren Versionen von phonegap nicht erforderlich?) Ich habe dies im Kopf meiner index.html-Datei und alles funktioniert einwandfrei. Ich denke, dass die Reihenfolge der Aufnahme von jquery, phonegap und jquery mobile wichtig ist.

<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

Das ist Arbeit für mich. Basis auf Dhaval, dieses Beispiel, wenn ich mit SQLite lerne

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

Um auf der Antwort von @ Jeffrey aufzubauen, habe ich einen viel saubereren Weg gefunden, der das HTML-Markup verbirgt, bis JQM die Verarbeitung der Seite abgeschlossen und das erste Seitenelement gerendert hat, da ich bemerkt habe, dass 1/2 Sekunde bloßes Markup flackert, bevor JQM rendert.

Sie müssen nur das gesamte Markup mit CSS ausblenden ... PageShow () von JQM schaltet die Sichtbarkeit für Sie um.

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


habe deinen Vorschlag ausprobiert und es hat bei mir nicht funktioniert. JQM pageshow zeigt die versteckte erste Seite nicht an. Darüber hinaus wird das Standard-HTML weiterhin angezeigt, bevor es ausgeblendet wird. Ich habe es schließlich auf der Grundlage von Jeffreys Lösung zum Laufen gebracht, wobei sich das Timing geringfügig geändert hat. siehe meinen Kommentar unter seiner Antwort.
GeorgeW

0

Das Folgende funktionierte für mich auf PG 2.3 und JQM 1.2, inkl. Facebook Connect Plugin:

<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

Das Laden von PhoneGap unterscheidet sich geringfügig vom Laden von jQuery. jQuery funktioniert eher als Dienstprogrammbibliothek, daher schließen Sie diese ein und es steht sofort zur Verfügung. Auf der anderen Seite benötigt PhoneGap die Unterstützung von nativem Code für eine ordnungsgemäße Initialisierung, sodass es nicht bald nach der Aufnahme in die Seite einsatzbereit ist.

Phonegap schlägt vor, sich zu registrieren und auf ein devicereadyEreignis zu warten , das einen nativen spezifischen Code ausführt.

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

Weitere Informationen finden Sie im Dokument


1
Aber das Problem ist, dass ich Phonegap-Zeug in meinem JQuery-Code verwenden möchte. In Ihrem Beispiel würde der gesamte JQuery-Code ausgeführt, bevor Phonegap überhaupt geladen wird. Vielleicht, wenn ich den ganzen Code in die Funktion onDeviceReady () stecke? So: $ ("# form"). Live ("pageinit", function (event) {// phonegapp stuff here});
Juw

Wenn Sie #formdie erste Seite sind, erhalten Sie keinen pageinitRückruf, da es zu spät ist
dhaval
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.