วิธีใช้ JQuery-Mobile / Phonegap ร่วมกันอย่างถูกต้องหรือไม่?


107

วิธีที่ถูกต้อง (จนถึงปัจจุบัน) ในการใช้ JQuery Mobile และ Phonegap ร่วมกันคืออะไร?

ต้องโหลดเฟรมเวิร์กทั้งสองก่อนจึงจะใช้งานได้ ฉันจะแน่ใจได้อย่างไรว่าทั้งสองโหลดก่อนที่จะใช้งานได้


11
ได้โปรด! เลือกคำตอบ !!!
realtebo

แม้ว่าจะสมควรได้รับ แต่ฉันจะไม่ +1 สิ่งนี้จนกว่าจะมีการเลือกคำตอบ <3
Don Vaughn

1
อะไรคือปัญหาที่แท้จริงที่ได้รับการแก้ไขที่นี่ - จะเกิดอะไรขึ้นถ้าฉันเพียงแค่ให้การอ้างอิงถึงไฟล์ js ที่จำเป็นสำหรับ jQuery และ Cordova ใน index.html ของฉันจากนั้นเปลี่ยนเส้นทางเพื่อพูดหน้าเข้าสู่ระบบจากไฟล์ js ที่ 3 โดยใช้ $ .mobile.changePage ของ jQuery ฉันหมายถึงสิ่งที่ทำให้การออกแบบนี้หยุดทำงานและเหตุใดฉันจึงต้องการแนวทางแก้ไขที่ระบุไว้ด้านล่าง เป็นเพราะมีโหลดแบบอะซิงโครนัสภายใน jQuery และ / หรือ Cordova และไฟล์ js ที่ 3 ของฉันสามารถโหลดได้ก่อนที่จะโหลด 2 เฟรมเวิร์ก ช่วยแนะนำหน่อยครับ. ขอบคุณ
มุสตาฟา

ตัวอย่างเช่น @ มุสตาฟาคุณอาจพยายามเข้าถึงฐานข้อมูลก่อนที่ondeviceReadyเหตุการณ์จะถูกทริกเกอร์จากรหัส JQM ของคุณ ...
Mirko

คำตอบ:


174

คุณสามารถใช้คุณสมบัติรอการตัดบัญชีของ 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
คำตอบนี้ควรได้รับการโหวตมากกว่าและถูกทำเครื่องหมายว่าถูกต้อง

4
ช่วยอธิบายเพิ่มเติมอีกหน่อยได้ไหม ลำดับชั้นของการอ้างอิงไฟล์มีลักษณะอย่างไร ขอบคุณ
farjam

2
ได้โปรดเพิ่มลำดับการโหลดสคริปต์โดยใช้เวอร์ชันล่าสุดได้ไหม?
realtebo

7
สำหรับทุกคนที่บอกว่ามันใช้ไม่ได้ - ลำดับการประกาศสคริปต์มีความสำคัญ ขั้นแรกให้รวม jquery จากนั้นรหัสนี้ภายในองค์ประกอบของสคริปต์จากนั้น jquery mobile js
Manish

1
เกี่ยวกับอะไรcordova.js? ควรโหลดก่อนหรือหลัง JQM?
Ferdinand.kraft

17

นี่คือวิธีการทำงานสำหรับฉันตามตัวอย่างด้านบน

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

สิ่งนี้ใช้ได้ผลสำหรับฉันเช่นกัน แต่ถ้าฉันเพิ่ม <div id = "test-index-page" data-role = "page"> </div> ในหน้าเดียวกันก่อนที่แท็ก html จะปิดหน้าจะไม่โหลดและฉันได้รับข้อผิดพลาด . ฉันต้องการเริ่มใช้ทั้งสองเฟรมเวิร์กโดยใช้ไฟล์ js ที่สามจากจุดที่ทั้งสองถูกโหลด ฉันจะทำอย่างไร?
มุสตาฟา

แน่นอนฉันลองโหลดไฟล์ js ที่ 3 ที่มีตรรกะทางธุรกิจสำหรับแอพของฉันใน doInit () แต่มันไม่ได้ผล ไฟล์นั้นมีตรรกะการผูกเหตุการณ์และการประกาศฟังก์ชันเช่น $ (document) .delegate ('# fakhera-index-page', 'pageinit', function (event) {... } ฉันจะทำสิ่งนี้ได้อย่างไร
Mustafa

7

ในการใช้ phonegap ร่วมกับ jquery mobile คุณต้องใช้แบบนี้

<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

ตามที่หลายคนแนะนำให้ใช้การเลื่อนเวลาเป็นตัวเลือกที่โอเคตราบเท่าที่คุณไม่สนใจว่าจะเรียงลำดับdevicereadyและเกิดmobileinitอะไรขึ้น แต่ในกรณีของฉันฉันต้องการpageshowเหตุการณ์บางอย่างเมื่อแอปพลิเคชันโหลดครั้งแรกและmobileinitและโดยการขยายเหตุการณ์pageshow/ pagebeforeshow/ etc เหล่านั้น ยิงทั้งหมดก่อนdevicereadyเสร็จสิ้นดังนั้นฉันจึงไม่สามารถผูกติดกับพวกเขาได้อย่างถูกต้องโดยใช้การรอการตัดบัญชี สภาพการแข่งขันนี้ไม่ใช่สิ่งที่ดี

สิ่งที่ฉันต้องทำคือตรวจสอบให้แน่ใจว่า 'mobileinit' ไม่เกิดขึ้นจนกระทั่งหลังจากนั้น ' deviceready' ถูกไล่ออกแล้ว เพราะจะmobileinitยิงทันทีเมื่อคุณโหลด JQM ฉันเลือกใช้jQuery.getScriptเพื่อโหลดหลังจากdevicereadyเสร็จสิ้นแล้ว

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

เหตุผลที่ฉันซ่อนเนื้อหาก็คือผลข้างเคียงของวิธีนี้คือครึ่งวินาทีของการมองเห็นเอกสาร HTML ดั้งเดิมก่อนที่จะโหลด jquery.mobile ในกรณีนี้ควรซ่อนพื้นที่ว่างเพิ่มอีกครึ่งวินาทีเพื่อดูเอกสารที่ไม่มีการจัดเรียง


1
+1 ในคำตอบของคุณเป็นแรงบันดาลใจให้ฉันแก้ปัญหาด้วยการเปลี่ยนแปลงเล็กน้อย ขั้นแรกให้ย้ายโค้ด body.hide () ไปยังบรรทัดแรกของ onBodyLoad (); ประการที่สองย้าย body.show () โค้ดไปอยู่หลัง getScript (jQM_PATH); เนื่องจาก mobileInit () ถูกเรียกใช้ในการเปลี่ยนหน้า JQM แต่ละหน้า ไม่เหมาะ หวังว่านี่จะช่วยคนอื่น ๆ
GeorgeW

คุณช่วยรวมส่วนที่เหลือของคุณได้index.html
ไหม

สิ่งนี้ไม่ได้ผลสำหรับฉันเพราะ Cordova กำลังลบไฟล์ทั้งหมดที่มีไม่ได้รวมไว้โดยใช้<script>แท็ก
Chris Snow

2

ฉันเชื่อว่าไม่จำเป็นต้องใช้คุณสมบัติรอการตัดบัญชี (อาจไม่จำเป็นสำหรับ phonegap เวอร์ชันใหม่กว่า) ฉันมีสิ่งนี้อยู่ในส่วนหัวของไฟล์ index.html และทุกอย่างทำงานได้ดี ฉันคิดว่าลำดับของการรวม jquery, phonegap และ jquery mobile มีความสำคัญ

<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

นี่คืองานสำหรับฉัน บนพื้นฐานของ dhaval ตัวอย่างนี้เมื่อฉันเรียนรู้โดยใช้ 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

เพื่อสร้างคำตอบของ @ Jeffrey ฉันพบวิธีที่สะอาดกว่ามากซึ่งจะซ่อนมาร์กอัป HTML จนกว่า JQM จะประมวลผลหน้าเสร็จและแสดงผลองค์ประกอบของหน้าแรกเนื่องจากฉันสังเกตเห็นว่าการกะพริบของมาร์กอัปเปล่า 1/2 วินาทีก่อนที่ JQM จะแสดงผล

คุณต้องซ่อนมาร์กอัปทั้งหมดด้วย css เท่านั้น ... PageShow () โดย JQM จะสลับการเปิดเผยให้คุณ

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


ลองทำตามคำแนะนำของคุณแล้วก็ไม่ได้ผลสำหรับฉัน JQM pageshow จะไม่แสดงหน้าแรกที่ซ่อนอยู่ ยิ่งไปกว่านั้น html มาตรฐานยังคงแสดงก่อนที่จะถูกซ่อน ในที่สุดฉันก็ทำให้มันใช้งานได้ตามวิธีแก้ปัญหาของเจฟฟรีย์โดยมีการเปลี่ยนแปลงเวลาเล็กน้อย ดูความคิดเห็นของฉันด้านล่างคำตอบของเขา
GeorgeW

0

สิ่งต่อไปนี้ใช้ได้ผลกับฉันใน PG 2.3 และ JQM 1.2 รวมถึง ปลั๊กอินเชื่อมต่อ Facebook:

<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

การโหลด PhoneGap แตกต่างจากการโหลด jQuery เล็กน้อย jQuery ทำงานเป็นไลบรารียูทิลิตี้ได้มากขึ้นดังนั้นคุณจึงรวมไว้และพร้อมใช้งานทันที ในทางกลับกัน PhoneGap ต้องการการสนับสนุนจากโค้ดเนทีฟเพื่อการเริ่มต้นที่เหมาะสมดังนั้นจึงไม่พร้อมใช้งานในไม่ช้าหลังจากรวมอยู่ในเพจ

Phonegap แนะนำให้ลงทะเบียนและรอให้devicereadyเหตุการณ์เรียกใช้โค้ดเนทีฟเฉพาะ

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

สำหรับข้อมูลเพิ่มเติมโปรดตรวจสอบเอกสาร


1
แต่ปัญหาคือฉันต้องการใช้ของ phonegap ในรหัส jquery ของฉัน ในตัวอย่างของคุณโค้ด jquery ทั้งหมดจะถูกเรียกใช้ก่อนที่จะโหลด phonegap บางทีถ้าฉันใส่รหัสทั้งหมดไว้ในฟังก์ชัน onDeviceReady ()? ดังนี้ $ ("# form"). live ("pageinit", function (event) {// phonegapp stuff here});
Juw

หากคุณ#formเป็นหน้าแรกคุณจะไม่ได้รับการpageinitติดต่อกลับเนื่องจากสายเกินไป
dhaval
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.