动态加载phonegap.js的问题

Issue with dynamically loaded phonegap.js

本文关键字:问题 js phonegap 加载 动态      更新时间:2023-09-26

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

我使用普通的script标签加载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对象存在。但是,尝试调用设备。uuid(或其他简单的phonegap API调用)失败。就好像PhoneGap没有完全初始化。但情况似乎不应该是这样。我错过什么了吗?谢谢!

最后我让它工作不使用任何外部库。


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

  • 封装项目
  • javascript 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脚本在动态加载时执行的唯一有效方法是@Sean Kinsey在这个惊人的答案中所显示的(向他致敬)。

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

我面临着类似的问题,我需要根据平台类型加载PhoneGap和依赖的插件文件。我浏览了PhoneGap源代码,发现它使用windows/浏览器事件来加载和准备对象。如果我手动调用浏览器事件,那么它会初始化运行应用程序所需的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延迟负载测试

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

2)此外,您是否为您的设备使用正确的phonegap.js ?(当在android上使用iPhone phonegap.js时,我有相同的"沉默"行为)

deviceready事件是由phonegap.js中的代码通过duck punching document处理的特殊事件。addEventListener,所以在你可以将事件附加到deviceready之前,必须先加载phonegap.js。

试试这个:

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 .js脚本后,通过运行以下javascript代码,我能够在动态注入后模拟正确的PhoneGap初始化工作流。

if (document.readyState == "complete") {
    PhoneGap.onDOMContentLoaded.fire();
}