如果deviceready事件已经触发,我该如何检查cordova是否准备好?

12
在cordova提供的示例应用程序中,通过cordova create ...命令创建的应用程序会监听deviceready事件的以下代码:
bindEvents: function() {
    document.addEventListener('deviceready', this.onDeviceReady, false);
},

这很好,但如果事件在我监听之前被触发会发生什么?举个例子,将上面示例应用程序的代码替换为以下内容:

bindEvents: function() {
    setTimeout(function () {
        document.addEventListener('deviceready', this.onDeviceReady, false);
    }, 2000)
},

在这个例子中,this.onDeviceReady从未被调用。难道没有更好、更可靠的方法来检查cordova是否已准备就绪吗?例如:

bindEvents: function() {
    setTimeout(function () {
        if (window.cordovaIsReady) {
            this.onDeviceReady()
        } else {
            document.addEventListener('deviceready', this.onDeviceReady, false);
        }
    }, 2000)
},
2个回答

27

根据cordova文档,
deviceready事件的行为与其他事件有些不同。在deviceready事件触发后注册的任何事件处理程序都会立即调用其回调函数。
如您所见,如果在deviceready触发后附加了任何事件处理程序,则会立即调用它。
setTimeout函数中,this指向的对象已经不再是原来的对象,上下文是不同的。因此,您的处理程序永远不会被调用。
您可以尝试将以下代码放置在<head>标签中,其中我使用全局函数/变量(出于简单起见,避免this上下文问题)。这应该会显示一个警报。

<script>
    function onDeviceReady () {
     alert("Calling onDeviceReady()");
    }

    setTimeout(function () {
            document.addEventListener('deviceready', onDeviceReady, false);
    }, 9000);
</script>

没错,我完全误解了这个问题。 - Shawn

-1

frank 的答案确实可行。但是处理这个问题的正确方法不是通过添加超时。

deviceready 事件处理程序将在 DOM 加载时创建。因此,为了使用该事件,我们应该等待直到 DOMContentLoaded,然后可以向 deviceready 事件添加监听器。

document.addEventListener("DOMContentLoaded", function() {
    //alert("Calling DOMContentLoaded");
    document.addEventListener('deviceready', function(){
        //alert("Calling onDeviceReady()");
        callFirebase();
    }, false);
});

2
我认为您错过了被接受的答案的要点:@frank演示了一个事件侦听器可以在页面加载后9秒钟的任何时间创建deviceready。因此,无需等待任何事件(包括DOMContentLoaded)。 - Mike

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接