Cách đúng để sử dụng JQuery-Mobile / Phonegap cùng nhau?


107

Cách chính xác (cho đến nay) để sử dụng JQuery Mobile và Phonegap cùng nhau là gì?

Cả hai khuôn khổ cần tải trước khi chúng có thể được sử dụng. Làm cách nào tôi có thể chắc chắn rằng cả hai đều được tải trước khi tôi có thể sử dụng chúng?


11
xin vui lòng ! chọn một câu trả lời !!!
realtebo

mặc dù nó xứng đáng với nó, tôi sẽ không để +1 mục này cho đến khi một câu trả lời được chọn <3
Don Vaughn

1
Vấn đề thực tế đang được giải quyết ở đây là gì - điều gì sẽ xảy ra nếu tôi chỉ cung cấp tham chiếu đến các tệp js cần thiết cho jQuery và Cordova trong index.html của tôi và sau đó chuyển hướng đến trang đăng nhập từ tệp js thứ 3 bằng cách sử dụng $ .mobile.changePage của jQuery? Ý tôi là điều gì ngăn thiết kế này hoạt động và tại sao tôi cần các giải pháp được nêu dưới đây? Có phải vì có tải không đồng bộ bên trong jQuery và / hoặc Cordova và tệp js thứ 3 của tôi có thể được tải ngay cả trước khi 2 khung được tải không? Hãy đề nghị. Cảm ơn
Mustafa

@Mustafa ví dụ bạn có thể thử truy cập vào cơ sở dữ liệu TRƯỚC ondeviceReadysự kiện được kích hoạt từ mã JQM của bạn ...
Mirko

Câu trả lời:


174

Bạn có thể sử dụng tính năng hoãn lại của 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
câu trả lời này sẽ nhận được nhiều phiếu bầu hơn và được đánh dấu là câu đúng.
memical

4
Bạn có thể giải thích thêm một chút được không? Hệ thống phân cấp của các tham chiếu tệp trông như thế nào? Cảm ơn
farjam

2
Làm ơn, bạn có thể thêm thứ tự tải tập lệnh, sử dụng phiên bản mới nhất không ??
realtebo vào

7
Đối với tất cả những người nói rằng nó không hoạt động - thứ tự khai báo script quan trọng. Đầu tiên hãy bao gồm jquery, SAU ĐÓ MÃ NÀY bên trong một phần tử script, sau đó là jquery mobile js.
Manish

1
Về cordova.jsthì sao? Nó nên được tải trước hay sau JQM?
Ferdinand.kraft,

17

Đây là cách nó hoạt động cho tôi, dựa trên ví dụ trên

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

Điều này cũng hiệu quả với tôi nhưng nếu tôi thêm <div id = "test-index-page" data-role = "page"> </div> vào cùng một trang trước khi thẻ html đóng thì trang sẽ không tải và tôi gặp lỗi . Tôi muốn bắt đầu sử dụng cả hai khuôn khổ bằng cách sử dụng tệp js thứ ba từ thời điểm cả hai đều được tải. Làm thế nào để làm điều đó?
Mustafa

Tất nhiên tôi đã thử tải tệp js thứ 3 có logic nghiệp vụ cho ứng dụng của tôi trong doInit () nhưng nó không hoạt động. Tệp đó có logic ràng buộc sự kiện và khai báo hàm, ví dụ: $ (document) .delegate ('# fakhera-index-page', 'pageinit', function (event) {...}. Làm cách nào để thực hiện việc này?
Mustafa

7

Để sử dụng phonegap cùng với jquery mobile, bạn cần sử dụng nó như thế này

<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

Như nhiều người đã đề xuất sử dụng hoãn lại là một lựa chọn ổn, miễn là bạn không quan tâm đến thứ tự devicereadyvà diễn ra như mobileinitthế nào. Nhưng trong trường hợp của tôi, tôi cần một vài pageshowsự kiện khi ứng dụng được tải lần đầu tiên mobileinitvà bằng cách mở rộng các sự kiện pageshow/ pagebeforeshow/ etc đó. tất cả đều bắn trước khi devicereadykết thúc, vì vậy tôi không thể liên kết với chúng đúng cách bằng cách sử dụng hoãn lại. Điều kiện cuộc đua này không phải là một điều tốt.

Những gì tôi cần làm là đảm bảo 'mobileinit' không diễn ra cho đến khi ' deviceready' đã bị sa thải. Vì mobileinitcháy ngay lập tức khi bạn tải JQM, tôi đã chọn sử dụng jQuery.getScriptđể tải nó SAU KHI devicereadyđã hoàn thành.

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

Lý do tôi ẩn phần nội dung là một tác dụng phụ của phương pháp này là một nửa giây khả năng hiển thị của tài liệu HTML gốc trước khi tải jquery.mobile. Trong trường hợp này, ẩn nó thêm nửa giây không gian trống sẽ được ưu tiên hơn để xem tài liệu chưa được định kiểu.


1
+1 cho câu trả lời của bạn vì nó đã truyền cảm hứng cho tôi để giải quyết vấn đề của mình với một số thay đổi nhỏ. Đầu tiên, di chuyển mã body.hide () đến dòng đầu tiên của onBodyLoad (); Thứ hai, di chuyển mã body.show () thành sau getScript (jQM_PATH); Bởi vì, mobileInit () được gọi trên mỗi chuyển đổi trang JQM. Không lý tưởng. Hy vọng điều này sẽ giúp những người khác.
GeorgeW

Bạn có thể chỉ bao gồm phần còn lại của bạnindex.html
JGallardo

Điều này không hiệu quả với tôi vì cordova đang xóa tất cả các tệp không được bao gồm bằng <script>thẻ.
Chris Snow

2

Tôi tin rằng không cần thiết phải sử dụng tính năng hoãn lại. (Có thể điều này không cần thiết với các phiên bản phonegap mới hơn?) Tôi có điều này trong phần đầu của tệp index.html và mọi thứ hoạt động tốt. Tôi nghĩ rằng thứ tự bao gồm jquery, phonegap và jquery mobile là quan trọng.

<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

đây là công việc đối với tôi. dựa trên dhaval, mẫu này khi tôi học cách sử dụng 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

Để xây dựng câu trả lời của @ Jeffrey, tôi đã tìm thấy một cách rõ ràng hơn nhiều là ẩn đánh dấu HTML cho đến khi JQM xử lý xong trang và hiển thị phần tử Trang đầu tiên, vì tôi nhận thấy rằng nhấp nháy 1/2 giây của đánh dấu trần trước khi JQM hiển thị.

Bạn chỉ cần ẩn tất cả các đánh dấu bằng css ... PageShow () của JQM sẽ chuyển đổi chế độ hiển thị cho bạn.

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


đã thử gợi ý của bạn và nó không hiệu quả với tôi. Trình chiếu trang JQM sẽ không hiển thị trang đầu tiên bị ẩn. Hơn nữa, html chuẩn vẫn hiển thị trước khi bị ẩn. Cuối cùng tôi đã làm cho nó hoạt động dựa trên giải pháp của Jeffrey với một chút thay đổi về thời gian. xem bình luận của tôi bên dưới câu trả lời của anh ấy.
GeorgeW

0

Phần sau phù hợp với tôi trên PG 2.3 và JQM 1.2, bao gồm. Plugin kết nối 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

Tải PhoneGap hơi khác so với tải jQuery. jQuery hoạt động nhiều hơn như một thư viện tiện ích, vì vậy bạn bao gồm nó và nó có sẵn để sử dụng ngay lập tức. Mặt khác, PhoneGap yêu cầu hỗ trợ từ mã gốc để khởi tạo thích hợp nên nó chưa sẵn sàng để sử dụng ngay sau khi được đưa vào trang.

Phonegap đề nghị đăng ký và đợi devicereadysự kiện thực thi bất kỳ mã gốc cụ thể nào.

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

Để biết thêm thông tin, hãy kiểm tra tài liệu


1
Nhưng vấn đề là tôi muốn sử dụng nội dung phonegap trong mã jquery của mình. Trong ví dụ của bạn, tất cả mã jquery sẽ được chạy trước khi phonegap được tải. Có thể nếu tôi đặt tất cả mã bên trong hàm onDeviceReady ()? Như thế này: $ ("# form"). Live ("pageinit", function (event) {// phonegapp nội dung tại đây});
Juw

nếu bạn #formlà trang đầu tiên sau đó bạn wont nhận pageinitcallback vì nó là quá muộn
dhaval
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.