我试图动态加载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();
}