Правильний спосіб спільного використання JQuery-Mobile / Phonegap?


107

Який правильний спосіб (до цієї дати) використовувати JQuery Mobile і Phonegap разом?

Обидві рамки потрібно завантажити перед тим, як їх можна буде використовувати. Як я можу бути впевненим, що обидва завантажені, перш ніж я можу їх використовувати?


11
будь ласка! оберіть відповідь !!!
realtebo

незважаючи на те, що це заслуговує, я не збираюся оцінювати +1, поки не буде обрана відповідь <3
Дон Вон

1
Яка реальна проблема тут вирішується - що робити, якщо я просто надав посилання на потрібні js-файли для jQuery та Cordova у своєму index.html, а потім перенаправляю, щоб сказати сторінку входу з 3-го файлу js, використовуючи $ .mobile.changePage jQuery? Я маю на увазі, що заважає цій конструкції працювати і навіщо мені потрібні рішення, викладені нижче? Це тому, що всередині jQuery та / або Кордова є асинхронні навантаження, і мій файл 3-го js може бути завантажений ще до завантаження 2-х фреймів? Будь ласка, підкажіть. Спасибі
Мустафа

@Mustafa, наприклад, ви можете спробувати отримати доступ до бази даних перед тим, як 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.
Маніш

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-файл з точки, яку завантажують. Як це зробити?
Мустафа

Звичайно, я спробував завантажити файл 3-й js, який має ділову логіку для мого додатка в doInit (), але це не спрацювало. Цей файл містить логіку прив'язки подій та функції, наприклад, $ (document) .delegate ('# fakhera-index-page', 'pageinit', функція (подія) {...}. Як це зробити?
Mustafa

7

Для того, щоб використовувати фонегап разом із 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Події були всі стріляли раніше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
JGallardo

Це не спрацювало для мене, оскільки cordova видаляла всі файли, які не були включені за допомогою <script>тегу.
Кріс Сноу

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

На основі відповіді @ Джеффрі я знайшов набагато більш чіткий спосіб, який приховує розмітку 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 не відображатиме приховану першу сторінку. Більше того, стандартний html все ще з’являється, перш ніж його заховати. Зрештою, я змусив це працювати на основі рішення Джеффрі з незначними змінами в часі. дивіться мій коментар нижче його відповіді.
GeorgeW

0

Наступне працювало для мене на PG 2.3 та JQM 1.2, в т.ч. Плагін 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

Завантаження 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
Але проблема полягає в тому, що я хочу використовувати в моєму коді jquery речі phonegap. У вашому прикладі весь код jquery буде запущений до завантаження фонегапу. Можливо, якщо я покладу весь код на функцію onDeviceReady ()? Ось так: $ ("# форма"). Live ("pageinit", функція (подія) {// phonegapp речі тут});
липня

якщо ваша #formперша сторінка, то ви не будете отримувати pageinitзворотній дзвінок, оскільки вже пізно
dhaval
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.