在“PhoneGap + jQuery Mobile”应用中正确注册事件

15

我试图定义在Android应用程序中为 PhoneGapjQuery Mobile 注册初始化事件的正确方法(类似于jQuery风格)。

在研究文档后,我得出了以下结论:

$('#index-page').live('pageinit', function () { // <-- fires
    $(document).bind('deviceready', function () { // <-- !fires
        // ...
    });
});

“外层”事件(pageinit)触发,而“内层”事件(deviceready)没有触发......

尽管这种类型的事件注册完美无缺:

window.addEventListener('load', function () {
    document.addEventListener('deviceready', function () {
        // ...
    }, false);
}, false);

有人能解释一下第一种事件注册方式有什么问题吗?哪种方式更好?


先决条件:

  • PhoneGap v1.2
  • jQuery Mobile v1.0rc2
  • Eclipse v3.7.1
3个回答

14

在这种情况下,我认为使用延迟对象更加清晰和安全。这也是我通常会采用的做法:

var jqmReady = $.Deferred();
var pgReady = $.Deferred();

// jqm ready
$(document).bind("mobileinit", jqmReady.resolve);

// phonegap ready
document.addEventListener("deviceready", pgReady.resolve, false);

// all ready :)
$.when(jqmReady, pgReady).then(function () {
  // do your thing
});

这比 Cordova/PhoneGap 使用的“标准”回调混乱要好得多。 - ocodo
理想情况下,我应该在index.html内完成这个任务,对吧?另外,我想要用一个JS文件来调用所有我的应用程序中的实时或延迟事件,而不是使用“/* do your thing */”,这样我就可以有一个集中的地方来注册所有事件。这种设计可行吗?如果是,我该如何实现呢?我尝试使用$.getScript,但它会为我的应用程序呈现一个空白页面。请给予建议。 - Asif
@Mustafa,你可以使用闭包,并创建一个初始化所有内容的模块。然后在代替 /* do your thing */ 的地方调用 yourModule.yourInitMethod(); - Paranoid Android
我对index.html中的所有JS进行了一些更改(清理),现在getScript可以工作了。感谢您的回答。 - Asif
@所有人 在哪个部分我必须包含“返回按钮”事件的代码? - Paul Vargas

7

我想要进一步借鉴Michael的例子,并触发一个自定义的“PG_pageinit”JavaScript事件。这将在两个事件(“pageinit”,“deviceready”)都被触发后触发。这样,您只需要更改已编写的外部JavaScript文件中注册事件的名称。

因此,使用Michael的代码(将“mobileinit”事件稍微更改为“pageinit”):

var jqmReady = $.Deferred(),
pgReady = $.Deferred();

// jqm page is ready
$(document).bind("pageinit", jqmReady.resolve);

// phonegap ready
document.addEventListener("deviceready", pgReady.resolve, false);

// all ready, throw a custom 'PG_pageinit' event
$.when(jqmReady, pgReady).then(function () {
  $(document).trigger("PG_pageinit"); 
});

在您的其他JavaScript文件中,每当您想要注册此新事件时,请使用以下内容:

$(document).bind("PG_pageinit", function(){
  alert('PG_pageinit was just fired!');    
  // do your thing...
});

在 Android 2.3 上进行测试,使用 cordova 1.9.0。


如果我将$(document).on('event')放在//do your thing中,为什么JQM事件永远不会被触发? - Paranoid Android

6
请坚持使用最后一个方案,因为这是PhoneGap推荐的。你的第一个方法可能不起作用,因为你绑定了deviceready太晚(即:在绑定之前它已经被触发)。这是因为pageinit比较晚才被触发。
你可以采用jQuery的方式:
$(window).load(function() {
    $(document).bind('deviceready', function () { 
        // ...
    });
});

1
坚持遵循W3C事件注册模型非常好...至于建议的jQuery样式,对我不起作用:'deviceready'事件没有触发...谢谢建议! - John Doe

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