【问题标题】:Correct way of using JQuery-Mobile/Phonegap together?一起使用 JQuery-Mobile/Phonegap 的正确方法?
【发布时间】:2012-06-12 07:46:27
【问题描述】:

结合使用 JQuery Mobile 和 Phonegap 的正确方法是什么(迄今为止)?

两个框架都需要加载才能使用。在我可以使用它们之前,如何确定它们都已加载?

【问题讨论】:

  • 请!选择一个答案!!!
  • 尽管值得,但在选择答案之前我不会为此 +1
  • 这里要解决的实际问题是什么 - 如果我只是在我的 index.html 中提供了对 jQuery 和 Cordova 所需 js 文件的引用,然后从第三个 js 文件重定向到登录页面使用jQuery 的 $.mobile.changePage?我的意思是什么阻止了这个设计,为什么我需要下面列出的解决方案?是不是因为 jQuery 和/或 Cordova 内部有异步加载,而我的第 3 个 js 文件甚至可以在加载 2 个框架之前加载?请建议。谢谢
  • @Mustafa 例如,您可能会在 JQM 代码触发 ondeviceReady 事件之前尝试访问数据库...

标签: jquery jquery-mobile cordova


【解决方案1】:

您可以使用 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
}

【讨论】:

  • 这个答案应该会得到更多的投票并被标记为正确的。
  • 您能详细说明一下吗?文件引用的层次结构是什么样的?谢谢
  • 拜托,你能添加脚本加载的顺序,使用最新版本吗??
  • 对于那些说它不起作用的人——声明脚本的顺序很重要。首先包含 jquery,然后在脚本元素中包含 THIS CODE,然后是 jquery mobile js。
  • cordova.js 怎么样?应该在 JQM 之前还是之后加载?
【解决方案2】:

根据上面的示例,这对我来说是这样的

<!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 标签关闭页面之前将
    添加到同一页面不加载,我得到错误。我想从加载两个框架开始使用第三个 js 文件。我该怎么做?
  • 当然,我尝试在 doInit() 中加载包含我的应用程序业务逻辑的第三个 js 文件,但没有成功。该文件具有事件绑定逻辑和函数声明,例如$( document ).delegate( '#fakhera-index-page' , 'pageinit',function(event){ ... }。我该怎么做?
【解决方案3】:

为了将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>  

【讨论】:

    【解决方案4】:

    正如许多人建议的那样,只要您不关心 devicereadymobileinit 发生的顺序,使用延迟是一个不错的选择。但在我的情况下,我需要一些 pageshow 事件来应用程序首先加载和mobileinit 和扩展这些pageshow/pagebeforeshow/etc 事件都在deviceready 完成之前触发,所以我无法使用延迟正确绑定到它们。这种竞争条件不是一件好事。

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

    <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 在您的回答中,因为它启发了我通过一些细微的改变来解决我的问题。首先,将 body.hide() 代码移动到 onBodyLoad() 的第一行;其次,将 body.show() 代码移到 getScript(jQM_PATH) 之后;因为,在每个 JQM 页面转换时都会调用 mobileInit()。不理想。希望这对其他人有所帮助。
    • 你能把你index.html的其余部分包括进来吗
    • 这对我不起作用,因为 cordova 使用 &lt;script&gt; 标记删除了所有未包含的文件。
    【解决方案5】:

    我认为没有必要使用延迟功能。 (也许新版本的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>
    

    【讨论】:

      【解决方案6】:

      这对我有用。基于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>
      

      【讨论】:

        【解决方案7】:

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

        您只需要使用 css 隐藏所有标记...JQM 的 PageShow() 将为您切换可见性。

        
        
        
        //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 在被隐藏之前仍然会显示出来。我最终根据 Jeffrey 的解决方案使其工作,但时间略有变化。在他的回答下方查看我的评论。
        【解决方案8】:

        以下内容在 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>
        

        【讨论】:

          【解决方案9】:

          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

          【讨论】:

          • 但问题是我想在我的 jquery 代码中使用 phonegap 的东西。在您的示例中,所有 jquery 代码都将在 phonegap 加载之前运行。也许如果我将所有代码都放在 onDeviceReady() 函数中?像这样: $("#form").live("pageinit",function(event) { //phonegapp stuff here });
          • 如果您的#form 是第一页,那么您将不会收到pageinit 回调,因为为时已晚
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多