Javascript 如何在 Chrome 浏览器中触发 deviceready 事件(尝试调试 phonegap 项目)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6687099/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to fire deviceready event in Chrome browser (trying to debug phonegap project)
提问by Max
I'm developing a PhoneGap application and I'd like to be able to debug it in Chrome rather than on the phone. However, I do the initialization of my code in an onDeviceReady() function that is triggered when PhoneGap fires the "deviceready" event. Since Chrome doesn't fire this event, my code isn't ever initialized.
我正在开发一个 PhoneGap 应用程序,我希望能够在 Chrome 中而不是在手机上调试它。但是,我在一个 onDeviceReady() 函数中初始化我的代码,该函数在 PhoneGap 触发“deviceready”事件时触发。由于 Chrome 不会触发此事件,因此我的代码从未被初始化。
Here's a stripped down version of my code:
这是我的代码的精简版本:
var dashboard = {};
$(document).ready(function() {
document.addEventListener("deviceready", dashboard.onDeviceReady, false);
});
dashboard.onDeviceReady = function() {
alert("hello!"); //this is never fired in Chrome
};
I've tried using the StopGapcode, which basically just does the following:
我试过使用StopGap代码,它基本上只执行以下操作:
var e = document.createEvent('Events');
e.initEvent("deviceready");
document.dispatchEvent(e);
But when I run that code in the Chrome javascript console, the "hello" alert still doesn't trigger. What am I doing wrong? Or does chrome just not support firing "custom" events like deviceready?
但是当我在 Chrome javascript 控制台中运行该代码时,“你好”警报仍然没有触发。我究竟做错了什么?还是 chrome 不支持触发“自定义”事件,例如 deviceready?
回答by Chemik
Add this code to your onLoad handler function:
将此代码添加到您的 onLoad 处理程序函数中:
if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/)) {
document.addEventListener("deviceready", onDeviceReady, false);
} else {
onDeviceReady();
}
Event "deviceready" is fired in cordova.js so I don't know a way to detect existence of this event in application code.
在cordova.js 中触发事件“deviceready”,所以我不知道在应用程序代码中检测此事件是否存在的方法。
回答by Max
Ended up pulling out the StopGap code and having to introduce a tiny delay (have this code running in a separate script than page-specific code):
最终拉出 StopGap 代码并不得不引入一个微小的延迟(让此代码在单独的脚本中运行,而不是特定于页面的代码):
window.setTimeout(function() {
var e = document.createEvent('Events');
e.initEvent("deviceready", true, false);
document.dispatchEvent(e);
}, 50);
回答by kirb
Use the Ripple Mobile Emulator. It is free on the Chrome Web Store. When it is installed, navigate to the page you want to test it on, right click the page and choose Ripple Mobile Emulator > Enable. When prompted, choose PhoneGap.
使用 Ripple 移动模拟器。它在 Chrome 网上应用店是免费的。安装后,导航到要测试的页面,右键单击该页面并选择 Ripple Mobile Emulator > Enable。出现提示时,选择 PhoneGap。
The emulator is good, but it is still in beta so not everything has been implemented yet.
模拟器很好,但它仍处于测试阶段,所以还没有实现一切。
Ad@m
广告@m
回答by jerone
For my mobile site and mobile App I'm using the following code with jQuery:
对于我的移动站点和移动应用程序,我将以下代码与 jQuery 一起使用:
function init() { ... };
if ("cordova" in window) {
$(document).on("deviceready", init);
} else {
$(init);
}
回答by Katrina
I use Safari for debugging and do this:
我使用 Safari 进行调试并执行以下操作:
//my standard PG device ready
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
//debug("onDeviceReady")
getDefaultPageSetup();
}
//then add this (for safari
window.onload = function () {
if(! window.device)
onDeviceReady()
}
回答by bladnman
user318696 had the magic I was looking for. "device" is defined in cordova and does not get defined when in a browser (non-phoneGap app wrapper).
user318696 拥有我正在寻找的魔法。“设备”在cordova 中定义,在浏览器(非phoneGap 应用程序包装器)中未定义。
EDITED:
编辑:
I ran into a scenario where Cordova took quite a while to initialize on a device and the "original" answer here was no longer valid. I have moved on to requiring a parameter on the URL when running tests in the browser. (in the example I'm looking for "testing=" in the url of the original page)
我遇到了一个场景,Cordova 花了很长时间在设备上初始化,这里的“原始”答案不再有效。在浏览器中运行测试时,我已经开始要求 URL 上有一个参数。(在示例中,我在原始页面的 url 中查找“testing=”)
$(document).ready(function () {
// ALWAYS LISTEN
document.addEventListener("deviceready", main, false);
// WEB BROWSER
var url = window.location.href;
if ( url.indexOf("testing=") > -1 ) {
setTimeout(main, 500);
}
});
ORIGINAL:
原来的:
I haven't dug deeply enough to know how long to trust this [could they start defining "device" in the browser in a future release?] But at least up to 2.6.0 this is safe:
我还没有深入挖掘,不知道要相信多久 [他们可以在未来的版本中开始在浏览器中定义“设备”吗?] 但至少在 2.6.0 之前这是安全的:
$(document).ready(function () {
// call main from Cordova
if ( window.device ) {
document.addEventListener("deviceready", main, false);
}
// from browser
else {
main();
}
});
回答by TaeKwonJoe
user318696's window.device detection works well. If using Kendo UI Mobile and PhoneGap, the following script will enable functionality in both PhoneGap builds and web browsers. This is based on Burke Holland's PhoneGap Build Bootstrap Project for Kendo UI Mobileand is intended to be placed at the bottom of the page before the closing body tag.
user318696 的 window.device 检测效果很好。如果使用 Kendo UI Mobile 和 PhoneGap,以下脚本将在 PhoneGap 构建和 Web 浏览器中启用功能。这是基于 Burke Holland 的PhoneGap Build Bootstrap Project for Kendo UI Mobile并且旨在放置在页面底部的结束正文标记之前。
<script type="text/javascript">
var tkj = tkj || {};
tkj.run = (function () {
// create the Kendo UI Mobile application
tkj.app = new kendo.mobile.Application(document.body);
});
// this is called when the intial view shows. it prevents the flash of unstyled content (FOUC)
tkj.show = (function () {
$(document.body).show();
});
(function () {
if (!window.device) {
//initialize immediately for web browsers
tkj.run();
}
else if (navigator.userAgent.indexOf('Browzr') > -1) {
// blackberry
setTimeout(tkj.run, 250)
} else {
// attach to deviceready event, which is fired when phonegap is all good to go.
document.addEventListener('deviceready', tkj.run, false);
}
})();
</script>
回答by Page2PagePro
Enhancing Chemik suggestion. The following code uses navigator.userAgent string to generically determine if the client browser is on a mobile platform.
加强Chemik 建议。以下代码使用 navigator.userAgent 字符串一般确定客户端浏览器是否在移动平台上。
The purpose of the separation from desktop browsers is to allow code verifying prior to compiling/installing android apk, etc. It is much faster to make a quick code change, refresh desktop browser vs. compiling in eclipse and loading on android. Another added bonus is the ability to use weinre in one tab & the index.html from android assets in another tab (and use firebug).
与桌面浏览器分离的目的是允许在编译/安装android apk等之前进行代码验证。进行快速代码更改,刷新桌面浏览器与在eclipse中编译并在android上加载相比要快得多。另一个额外的好处是能够在一个选项卡中使用 weinre 以及在另一个选项卡中使用来自 android 资产的 index.html(并使用 firebug)。
PS: weinre code is excluded since it has my private VPS info & UUID.
PS:weinre 代码被排除在外,因为它有我的私人 VPS 信息和 UUID。
thx!
谢谢!
<!-- Framework:jQuery -->
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.2, minimum-scale=1.0, maximum-scale=3.0, user-scalable=yes" >
<link href="./framework/jquery/mobile/1.2.0/jquery.mobile-1.2.0.min.css" type="text/css" media="screen" rel="stylesheet" title="JQuery Mobile">
<script src="./framework/jquery/jquery-1.8.2.min.js"></script>
<script src="./framework/jquery/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>
<!-- Framework:Weinre -->
<!-- Framework:PhoneGap -->
<script src="./framework/phonegap/cordova-2.0.0.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
var mobile = false;
if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/)) {
document.addEventListener("deviceready", function(){mobile = true; onDeviceReady();}, false);
} else {
$(document).ready(onDeviceReady);
}
function onDeviceReady() {
setEvents();
test();
if (mobile) {
navigator.notification.alert("Debugging-ready for\n" + navigator.userAgent);
} else {
alert("Debugging-ready for\n" + navigator.userAgent);
}
};
</script>
回答by Pasquale Mangialavori
You simulate events like this:
您可以模拟这样的事件:
const simulateEvent = (eventName, attrs = {customData:"data"}, time = 1000, target = document) => {
let event = new CustomEvent(eventName, { detail: attrs });
setTimeout(() => {
target.dispatchEvent(event);
}, time);
};
var divReady = document.querySelector('div#ready');
document.addEventListener('deviceready', (e) => {
console.log("triggered with:", e.detail);
divReady.innerHTML = `Ready! ${JSON.stringify(e.detail)}`;
});
simulateEvent('deviceready', {customData:"My custom data goes in event.detail"});
<div id="ready"> Wait for ready... </div>