PhoneGap 如何在更改 window.location/document.location 后保持 Javascript 执行

Posted

技术标签:

【中文标题】PhoneGap 如何在更改 window.location/document.location 后保持 Javascript 执行【英文标题】:How PhoneGap keep Javascript executing after changing window.location/document.location 【发布时间】:2012-09-03 13:32:48 【问题描述】:

根据this question,当我们设置window.location时,javascript会“停止”执行或者变成竞态条件。

有时我们需要在 WebView 中多次触发 window.location = SOMESCH://xxx 以将“通知”发送回我们的应用。例如设置window.location = myapp://loginButtonEnabled?e=1 告诉应用程序用户已经填写了一些必要的信息并且可以开始登录。这样做似乎是不可能的:

function()
window.location = myapp://loginButtonEnable?e=1;
window.location = myapp://hideHintView;
.....
window.location = myapp://theLastThing;

只有最后一个 window.location = myapp://theLastThing 会被触发,然后 Javascript 将停止执行(尽管我们通过在 webView:shouldStartLoadWithRequest:navigationType: 中返回 NO 来停止应用程序中的重定向)。

我觉得有趣的是,PhoneGap 通过使用调度队列使这成为可能,但我仍然没有弄清楚它为什么会起作用,有人知道诀窍吗??

顺便说一句,有没有一种简单的方法可以在设置位置后“恢复”执行?会比使用操作队列好很多。

【问题讨论】:

【参考方案1】:

您需要让事件循环每次都有机会响应位置变化。执行此操作的典型方法是使用具有小/零延迟的setTimeout,这具有将执行移至下一个事件循环滴答的效果。试试这样的:

var q=[];

function dequeue() 
  window.location='myapp://'+q.shift();
  if (q.length>0) setTimeout(dequeue,0);


function notifyApp(cmd) 
  q.push(cmd);
  if (q.length==1) setTimeout(dequeue,0);


notifyApp('loginButtonEnable?e=1');
notifyApp('hideHintView');
notifyApp('theLastThing');

至于 javascript 执行停止,设置 window.location 不应该有这种效果,除非它实际上导致页面更改 - 也许尝试使用上面的技术,看看你的 javascript 在最后一次 notifyApp() 调用之后是否继续。

编辑:解决此问题的另一种方法是创建临时 iframe,而不是更改当前页面的位置 - 例如,请参阅 Triggering shouldStartLoadWithRequest with multiple window.location.href calls

【讨论】:

以上是关于PhoneGap 如何在更改 window.location/document.location 后保持 Javascript 执行的主要内容,如果未能解决你的问题,请参考以下文章

如何在启动时更改 phonegap/cordova 状态栏背景(启动画面)?

PhoneGap 如何在更改 window.location/document.location 后保持 Javascript 执行

远程构建时如何更改cordova/phonegap的默认图标

在PhoneGap Build中更改默认名称PG Build App

动态Phonegap状态栏颜色?

在phonegap中以编程方式更改页面