Cara yang benar untuk menggunakan JQuery-Mobile / Phonegap secara bersamaan?

107

Apa cara yang benar (sampai saat ini) untuk menggunakan JQuery Mobile dan Phonegap bersama?

Kedua kerangka kerja perlu dimuat sebelum dapat digunakan. Bagaimana saya bisa yakin bahwa keduanya dimuat sebelum saya dapat menggunakannya?

Juw
sumber
11
silahkan ! pilih jawaban !!!
realtebo
meskipun layak, saya tidak akan memberi ini +1 sampai jawaban dipilih <3
Don Vaughn
1
Apa masalah sebenarnya yang sedang diselesaikan di sini - bagaimana jika saya hanya memberikan referensi ke file js yang diperlukan untuk jQuery dan Cordova di index.html saya dan kemudian mengarahkan ulang untuk mengatakan halaman login dari file js ke-3 menggunakan $ .mobile.changePage jQuery? Maksud saya, apa yang menghentikan desain ini berfungsi dan mengapa saya memerlukan solusi yang diuraikan di bawah ini? Apakah karena ada beban asinkron di dalam jQuery dan / atau Cordova dan file js ke-3 saya dapat dimuat bahkan sebelum 2 kerangka kerja dimuat? Mohon saran. Terima kasih
Mustafa
@Mustafa misalnya Anda mungkin mencoba mengakses database SEBELUM ondeviceReadyacara dipicu dari kode JQM Anda ...
Mirko

Jawaban:

174

Anda dapat menggunakan fitur ditangguhkan dari 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
}
Oktavianus
sumber
3
jawaban ini akan mendapatkan lebih banyak suara dan ditandai sebagai jawaban yang benar.
memical
4
Bisakah Anda menjelaskan lebih lanjut? Seperti apa hierarki referensi file itu? Terima kasih
farjam
2
Tolong, bisakah Anda menambahkan urutan pemuatan skrip, menggunakan versi terbaru ??
realtebo
7
Untuk semua orang yang mengatakan itu tidak berhasil - urutan mendeklarasikan skrip itu penting. Pertama masukkan jquery, LALU KODE INI di dalam elemen script, lalu jquery mobile js.
Manish
1
Tentang apa cordova.js? Apakah harus dimuat sebelum atau sesudah JQM?
Ferdinand.kraft
17

Begini cara kerjanya untuk saya, berdasarkan contoh di atas

<!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>
Cristian Romanescu
sumber
Ini juga berfungsi untuk saya, tetapi jika saya menambahkan <div id = "test-index-page" data-role = "page"> </div> ke halaman yang sama sebelum tag html menutup halaman tidak memuat dan saya mendapatkan kesalahan . Saya ingin mulai menggunakan kedua kerangka kerja menggunakan file js ketiga dari titik keduanya dimuat. Bagaimana aku melakukan itu?
Mustafa
Tentu saja saya mencoba memuat file js ke-3 yang memiliki logika bisnis untuk aplikasi saya di doInit () tetapi tidak berhasil. File itu memiliki logika pengikatan peristiwa dan deklarasi fungsi, misalnya $ (document) .delegate ('# fakhera-index-page', 'pageinit', function (event) {...}. Bagaimana cara melakukannya?
Mustafa
7

Untuk menggunakan phonegap bersama dengan jquery mobile, Anda perlu menggunakannya seperti ini

<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>  
Coder_sLaY
sumber
6

Seperti yang disarankan banyak orang, menggunakan deferred adalah pilihan yang baik selama Anda tidak peduli dengan urutan apa devicereadydan apa yang mobileinitterjadi. Namun dalam kasus saya, saya memerlukan beberapa pageshowperistiwa ketika aplikasi pertama kali dimuat dan mobileinitdan dengan ekstensi peristiwa pageshow/ pagebeforeshow/ dll. semua menembak sebelumnyadeviceready selesai, jadi saya tidak bisa mengikat mereka dengan benar menggunakan penangguhan pada mereka. Kondisi balapan ini bukanlah hal yang baik.

Yang perlu saya lakukan adalah memastikan 'mobileinit' tidak berlangsung sampai ' deviceready' sudah dipecat. Karena mobileinitlangsung menyala saat Anda memuat JQM yang saya pilih untuk digunakan jQuery.getScriptuntuk memuatnya SETELAH devicereadysudah selesai.

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

Alasan saya menyembunyikan badan adalah karena efek samping dari metode ini adalah setengah detik visibilitas dokumen HTML asli sebelum jquery.mobile dimuat. Dalam hal ini menyembunyikan setengah detik tambahan dari ruang kosong lebih disukai daripada melihat dokumen tanpa gaya.

Jeffrey Van Alstine
sumber
1
+1 pada jawaban Anda untuk itu mengilhami saya untuk memecahkan masalah saya dengan sedikit perubahan. Pertama, pindahkan kode body.hide () ke baris pertama onBodyLoad (); Kedua, pindahkan kode body.show () menjadi setelah getScript (jQM_PATH); Karena, mobileInit () dipanggil pada setiap transisi halaman JQM. Tidak ideal. Semoga ini bisa membantu orang lain.
GeorgeW
Bisakah Anda memasukkan sisanyaindex.html
JGallardo
Ini tidak berhasil untuk saya karena cordova menghapus semua file yang tidak disertakan menggunakan <script>tag.
Chris Snow
2

Saya percaya bahwa tidak perlu menggunakan fitur deferred. (Mungkin ini tidak diperlukan dengan versi phonegap yang lebih baru?) Saya memiliki ini di kepala file index.html saya dan semuanya berfungsi dengan baik. Menurut saya urutan termasuk jquery, phonegap dan jquery mobile itu penting.

<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>
Allie Hoch Janoch
sumber
1

ini pekerjaan untukku. berdasarkan dhaval, ini contoh ketika saya belajar menggunakan 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>
Ztuons Ch
sumber
0

Untuk membangun jawaban @ Jeffrey, saya menemukan cara yang jauh lebih bersih yang menyembunyikan markup HTML sampai JQM selesai memproses halaman dan merender elemen Halaman pertama, karena saya telah memperhatikan bahwa 1/2 detik flicker dari markup kosong sebelum JQM merender.

Anda hanya perlu menyembunyikan semua markup dengan css ... PageShow () oleh JQM akan mengalihkan visibilitas untuk Anda.

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

Erik
sumber
mencoba saran Anda dan tidak berhasil untuk saya. Pageshow JQM tidak akan menampilkan halaman pertama yang tersembunyi. Selain itu, html standar masih muncul sebelum disembunyikan. Saya akhirnya membuatnya bekerja berdasarkan solusi Jeffrey dengan sedikit perubahan waktu. lihat komentar saya di bawah jawabannya.
GeorgeW
0

Berikut ini bekerja untuk saya di PG 2.3 dan JQM 1.2, termasuk. 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>
Jens Peters
sumber
-1

Memuat PhoneGap sedikit berbeda dengan memuat jQuery. jQuery bekerja lebih sebagai pustaka utilitas sehingga Anda memasukkannya dan tersedia untuk digunakan segera. Di sisi lain, PhoneGap memerlukan dukungan dari kode asli untuk inisialisasi yang tepat sehingga tidak siap digunakan segera setelah disertakan dalam halaman.

Phonegap menyarankan untuk mendaftar dan menunggu devicereadyacara mengeksekusi kode khusus asli apa pun.

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

Untuk info lebih lanjut, periksa dok

dhaval
sumber
1
Tapi masalahnya adalah saya ingin menggunakan phonegap di kode jquery saya. Dalam contoh Anda, semua kode jquery akan dijalankan bahkan sebelum phonegap dimuat. Mungkin jika saya memasukkan semua kode di dalam fungsi onDeviceReady ()? Seperti ini: $ ("# form"). Live ("pageinit", function (event) {// phonegapp stuff here});
Juw
jika Anda #formadalah halaman pertama maka Anda tidak akan menerima pageinitpanggilan balik karena sudah terlambat
dhaval