首页 > 解决方案 > Javascript向后执行

问题描述

一个应用程序正在使用带有InAppBrowser插件版本 3.2.1 的Cordova来加载在 Asp.Net 4.5.2 中构建的网页。我们一直在经历不稳定的行为,所以我制作了一个页面来捕捉问题并在这里分享。

这个页面包含一个在onclick 事件中执行 JS 的非常简单的按钮:

<button onclick="alert('1'); alert('2'); alert('3');"> EXECUTION</button>

它工作得很好,但是当网站嵌入到应用程序中时,执行顺序会向后运行,显示:

使用具有相同结果的不显眼的 JS:

<button id="testButton">Test</button>
$(document).ready(function () {
    $("#testButton").click(function () {
       alert('1');
       alert('2');
       alert('3');
    });
});

使用 Safari 在 ios 中运行网站效果很好。

任何的想法?

更新

正如@Bergi 在评论中所建议的那样,添加睡眠可以timeout验证管理同步调用的问题。以下代码以正确的顺序触发警报:

$("#testButton").click(function () {
    alert('1');
    setTimeout(function () { alert('2'); }, 2000);
    setTimeout(function(){ alert('3'); }, 4000);
});

但不是在超时更近的时候。以下以错误的顺序显示警报:

$("#testButton").click(function () {
    alert('1');
    setTimeout(function () { alert('2'); }, 1);
    setTimeout(function(){ alert('3'); }, 2);
});

更新 2

正如@Bergi 在评论中提出的那样,我尝试过:

$("#testButton").click(function () {
    var x = []; x.push(1); x.push(2); alert(x);
});

结果正确,显示包含:“1,2”的警报。

问题已报告。

标签: javascriptcordovacordova-pluginsinappbrowser

解决方案


正如@Bergi 在评论中建议的那样,alert()您调用的版本在某些平台上可能是异步的,而在其他平台上可能是同步的。这将解释您所看到的行为。

window.alert()当您需要一个警报框时,您可能应该使用navigator.notification.alert()cordova -plugin-dialogs ,而不是根本不使用。

请注意此函数的签名:

navigator.notification.alert( message, alertCallback, [title], [buttonName] )

alertCallback解除警报框后调用该函数。即使有些实现是同步的(因为它们使用本机浏览器alert()功能)而有些是异步的,也navigator.notification.alert()为这两种情况提供了兼容的接口。

嗯,主要是兼容的。在navigator.notification.alert()调用 native的平台上alert(),在用户关闭警报框之前,该函数不会返回。在使用其他实现的平台上,该函数可能会立即返回。但在这两种情况下,alertCallback都会在警报框被解除时调用。

cordova-plugin-dialogs 也提供了类似的navigator.notification.confirm()和实现navigator.notification.prompt(),每个都有完成回调。

tests.jscordova-plugin-inappbrowser中有一段有趣的代码:

window.alert = window.alert || navigator.notification.alert;
if (isWindows && navigator && navigator.notification && navigator.notification.alert) {
    // window.alert is defined but not functional on UWP
    window.alert = navigator.notification.alert;
}

请注意,此功能如何设置window.alert为与navigator.notification.alert没有 的平台window.alert以及 UWP 上的相同。虽然与您的情况没有直接关系,但这说明了在不同平台上可能会有不同的实现。但是使用navigator.notification.alert()应该可以让你为所有人编写兼容的代码。只是不要假设这个函数是立即返回还是等待警报被解除 -alertCallback改用。


推荐阅读