动态加载的phonegap.js问题

时间:2011-07-21 21:38:43

标签: javascript jquery mobile jquery-mobile cordova

我正在尝试动态加载phonegap javascript文件(这样我可以选择在我使用Ripple时不在调试模式下加载它)但我正在遇到一些问题。

我使用普通脚本标记加载jquery和jquerymobile javascript库。在另一个脚本块中,我这样做:

function onDeviceReady() { 
    alert("Device Ready!"); 
} 
$(document).ready(function() { 
    alert("doc ready!"); 
    $.getScript("js/phonegap.0.9.5.1.js", function() {alert("Got Phonegap!");}); 
    document.addEventListener("deviceready", onDeviceReady, false); 
}); 

此代码警告它“获得了Phonegap!”但从不警告“设备就绪”。使用jsconsole.com,我可以看到PhoneGap javascript对象存在。但是,尝试调用device.uuid(或其他简单的phonegap API调用)失败。这几乎就像PhoneGap没有完全初始化。看起来不应该是这种情况。我错过了什么吗?谢谢!

5 个答案:

答案 0 :(得分:8)

最后,我在不使用任何外部库的情况下使用它。

问题
对于多平台Phonegap项目,有两个是不同平台的不同部分:

  • 封装项目
  • Javacript Phonegap文件。

这些封装项目在整个项目过程中通常不会发生太大变化。希望有一个HTML5代码库可以直接粘贴(或使用构建脚本)到依赖于平台的项目上。由于javascript phonegap库位于Web文件集中,因此每次更换正确的文件真的很痛苦。

我的解决方案
在我的项目中,我有几个cordova文件,每个目标平台一个:

  • cordova.android.js
  • cordova.ios.js
  • cordoba.bb.js ...

(注意这些文件中的每一个文件是如何包含在应用程序中的,即使它没有被使用。对我来说这不是问题,因为脚本捆绑在应用程序中,只有正确平台的脚本被加载到内存中)。

在我的页面中,我没有使用phonegap的脚本标签,而是放置了加载器模块:

<script src="phonegap-loader.js"></script>

这就是phonegap-loader.js脚本。我利用用户代理检测来动态地同步加载脚本:

    (function(){
        var useragent = navigator.userAgent;


        if(/Android/i.test(useragent)){
            loadScript('cordova.android.js');
        } else if((/iPhone/i.test(useragent)) || (/iPad/i.test(useragent))){
            loadScript('cordova.ios.js');
        }
        ...
        // Else desktop browser is assumed and no phonegap js is loaded


        function loadScript(url){
            // synchronous load by @Sean Kinsey 
            // https://stackoverflow.com/a/2880147/813951
            var xhrObj =  new XMLHttpRequest();
            xhrObj.open('GET', url, false);
            xhrObj.send('');
            var se = document.createElement('script');
            se.text = xhrObj.responseText;
            document.getElementsByTagName('head')[0].appendChild(se);
        }
    })();

同步加载脚本非常重要。这给了我无数令人头疼的问题。在实现这一点之前,我尝试在头部底部添加脚本标记,并使用$ .getScript,但没有工作,因为ondeviceReady未被触发。看起来确保动态加载后执行Phonegap脚本的唯一有效方法是amazing answer by @Sean Kinsey中所示的(对他来说都是赞誉)。

唯一的缺点是脚本是内联的,但对我来说,最好从容器中分离出核心HTML5应用程序,这是一个便宜的代价。

答案 1 :(得分:3)

我遇到了类似的问题,我需要根据平台类型加载PhoneGap和相关插件文件。我浏览了PhoneGap源代码,发现它使用windows / browser事件来加载和准备对象。如果我手动调用浏览器事件,那么它会初始化运行我的应用程序所需的PhoneGap对象(API和插件)。

以下使用Yabble的代码现在对我有用:

<html>
<head>
<script
    src="https://raw.github.com/jbrantly/yabble/master/lib/yabble.js"></script>

<script>
    require.setModuleRoot("js");
    require.useScriptTags();

    require.ensure([ "jquery", "phonegap" ], function(require) {

        // Trigger PhoneGap Initialization
        PhoneGap.onPhoneGapInit.fire();

        // Load PhoneGap Plugins
        require.ensure([ "plugin1" ], function() {
            $("#console").append("Plugin1 loaded<br>");
        });

        // Both following functions will work only if PhoneGap is loaded/initialized and Plugin is successfully registered

        // Check PhoneGap device object
        $("#checkDevice").click(function() {
            console.log(JSON.stringify(device));
        });

        // Call Native Plugin
        $("#callPlugin").click(function() {
            window.plugins.plugin1.call();
        });
    });
</script>
</head>
<body>
    <div id="console"></div>

    <input type="button" id="checkDevice" value="Check Device">
    <input type="button" id="callPlugin" value="Call Plugin">
</body>
</html>

设备信息和插件调用在Android上运行良好。虽然我还没有检查过所有的PhoneGap API,但截至目前我只需要这两个就可以工作,而且它们正在工作。

修改

在Phonegap 1.5 / Cordova中,由于API更改,PhoneGap.onPhoneGapInit.fire();不可用。在我当前的测试中,大多数必需的对象在动态加载JS后没有任何变化。此要点提供了更新的测试 - Cordova Lazy Load Test

答案 2 :(得分:0)

1)您是否尝试在getScript之前调用addEventListener?

2)另外,您是否为您的设备使用了正确的phonegap.js? (当在android上使用iphone phonegap.js时,我有同样的“沉默”行为)

答案 3 :(得分:0)

deviceready事件是一个特殊事件,由phonegap.js中的代码通过duck punching document.addEventListener处理,因此必须先加载phonegap.js,然后才能将事件附加到deviceready。

试试这个:

function onDeviceReady() { 
    alert("Device Ready!"); 
} 
$(document).ready(function() { 
    alert("doc ready!"); 
    $.getScript("js/phonegap.0.9.5.1.js", function() {
        alert("Got Phonegap!");
        document.addEventListener("deviceready", onDeviceReady, false);
    });
});

答案 4 :(得分:0)

通过在注入phonegap.js脚本后立即运行以下javascript代码,动态注入后,我能够模拟正确的PhoneGap初始化工作流程。

if (document.readyState == "complete") {

    PhoneGap.onDOMContentLoaded.fire();
}