一起使用JQuery-Mobile / Phonegap的正确方法?


107

到目前为止,正确使用JQuery Mobile和Phonegap的正确方法是什么?

这两个框架都需要先加载,然后才能使用。在使用它们之前,如何确定两者都已加载?


11
请 !选择一个答案!
realtebo 2013年

即使它值得,我也不会对此+1,直到选择答案为止<3
Don Vaughn

1
这里要解决的实际问题是什么-如果我只是在index.html中提供了jQuery和Cordova所需js文件的引用,然后使用jQuery的$ .mobile.changePage从第三个js文件重定向到登录页面,该怎么办?我的意思是阻止该设计工作的原因,为什么我需要以下概述的解决方案?是因为jQuery和/或Cordova内部存在异步加载,并且即使在加载两个框架之前也可以加载我的第3个js文件?请提出建议。谢谢
Mustafa

例如,@ Mustafa您可能会在ondeviceReady事件从您的JQM代码触发之前尝试访问数据库...
Mirko 2013年

Answers:


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
此答案应获得更多选票,并标记为正确选票。
记忆式的,2012年

4
您能再详细一点吗?文件引用的层次结构是什么样的?谢谢
farjam 2012年

2
请使用最新版本添加脚本加载的顺序吗?
realtebo

7
对于所有那些说不起作用的人来说,声明脚本的顺序很重要。首先在脚本元素中包含jquery,THEN THIS CODE,然后是jquery移动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>

这也对我有用,但是如果我在<html id>标签关闭页面之前将<div id =“ test-index-page” data-role =“ page”> </ div>添加到同一页面,则该页面无法加载,并且出现错误。我想从两个加载点开始使用第三个js文件来使用两个框架。我怎么做?
穆斯塔法

当然,我尝试在doInit()中加载第3个js文件,该文件具有我的应用程序的业务逻辑,但没有用。该文件具有事件绑定逻辑和函数声明,例如$(document).delegate('#fakhera-index-page','pageinit',function(event){...}。我该怎么做?
Mustafa

7

为了与jquery mobile一起使用phonegap,您需要像这样使用它

<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

正如许多人建议的那样,只要您不在乎顺序devicereadymobileinit幸福就可以使用延迟选项。但是就我而言,我需要pageshow在应用程序首次加载时添加一些事件,mobileinit并通过扩展将这些pageshow/ pagebeforeshow/ etc事件所有的射击都在deviceready完成之前进行,所以我无法使用延迟对它们的绑定。这种比赛条件不是一件好事。

我需要做的是确保直到' deviceready'被解雇后才发生'mobileinit' 。因为mobileinit加载JQM时会立即触发,所以我选择使用jQuery.getScriptdeviceready在完成后加载它。

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

我隐藏正文的原因是,此方法的副作用是jquery.mobile加载之前原始HTML文档的可见性的一半。在这种情况下,与查看未样式化的文档相比,最好将其隐藏半秒钟的空白空间。


1
您的答案+1,这激发了我一些细微的变化来解决我的问题。首先,将body.hide()代码移到onBodyLoad()的第一行;其次,将body.show()代码移到getScript(jQM_PATH);之后;因为,在每个JQM页面转换上都会调用mobileInit()。不理想。希望这对其他人有帮助。
GeorgeW

您能否只包括其余部分index.html
JGallardo 2013年

这对我不起作用,因为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

为了以@Jeffrey的答案为基础,我发现了一种更简洁的方法,即在JQM完成处理页面并呈现第一个Page元素之前,隐藏HTML标记,因为我注意到JQM呈现之前有1/2秒的裸标记闪烁。

您只需要用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在隐藏之前仍会显示。我最终根据Jeffrey的解决方案使其工作,但时间稍有变化。请参阅他的回答下方的我的评论。
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>

有关更多信息,请检查doc


1
但是问题是我想在我的jquery代码中使用phonegap东西。在您的示例中,所有jquery代码都将在甚至加载phonegap之前运行。也许如果我将所有代码放在onDeviceReady()函数中?像这样:$(“#form”)。live(“ pageinit”,function(event){//这里是phonegapp的东西});
2012年

如果您#form是第一页,那么您将不会收到pageinit回调,因为为时已晚
dhaval 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.