Javascript 向后执行

Mar*_*ero 6 javascript cordova inappbrowser cordova-plugins

一个应用程序使用CordovaInAppBrowser插件版本 3.2.1 来加载内置于 Asp.Net 4.5.2 的网页。我们一直遇到不稳定的行为,所以我制作了一个页面来捕捉问题并在此处分享。

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

<button onclick="alert('1'); alert('2'); alert('3');"> EXECUTION</button>
Run Code Online (Sandbox Code Playgroud)

它运行良好,但是当网站嵌入应用程序时,执行顺序向后运行,显示:

  • 警报 3
  • 警报 2
  • 警报 1

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

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

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

任何的想法?

更新

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

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

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

$("#testButton").click(function () {
    alert('1');
    setTimeout(function () { alert('2'); }, 1);
    setTimeout(function(){ alert('3'); }, 2);
});
Run Code Online (Sandbox Code Playgroud)

更新 2

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

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

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

问题已报告。

Mic*_*ary 2

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

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

请注意该函数的签名:

navigator.notification.alert( message, alertCallback, [title], [buttonName] )
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

navigator.notification.alert( message, alertCallback, [title], [buttonName] )
Run Code Online (Sandbox Code Playgroud)

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