我正在尝试动态加载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没有完全初始化。看起来不应该是这种情况。我错过了什么吗?谢谢!
答案 0 :(得分:8)
最后,我在不使用任何外部库的情况下使用它。
问题
对于多平台Phonegap项目,有两个是不同平台的不同部分:
这些封装项目在整个项目过程中通常不会发生太大变化。希望有一个HTML5代码库可以直接粘贴(或使用构建脚本)到依赖于平台的项目上。由于javascript phonegap库位于Web文件集中,因此每次更换正确的文件真的很痛苦。
我的解决方案
在我的项目中,我有几个cordova文件,每个目标平台一个:
(注意这些文件中的每一个文件是如何包含在应用程序中的,即使它没有被使用。对我来说这不是问题,因为脚本捆绑在应用程序中,只有正确平台的脚本被加载到内存中)。
在我的页面中,我没有使用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();
}