An app is using Cordova with InAppBrowser plugin version 3.2.1 to load a webpage built in Asp.Net 4.5.2. We have been experiencing erratic behaviour, so I've made a page to catch the problem and share it here.
This page contains a really simple button executing JS within the onclick event:
<button onclick="alert('1'); alert('2'); alert('3');"> EXECUTION</button>
It works perfectly, but when the website is embed in the app, the execution order runs backwards, displaying:
Using unobstrusive JS with the same results:
<button id="testButton">Test</button>
$(document).ready(function () {
$("#testButton").click(function () {
alert('1');
alert('2');
alert('3');
});
});
Running the website in ios with Safari works perfectly fine.
Any idea?
As suggested by @Bergi in the comments, adding a sleep timeout
verifies a problem managing synchronous calls. Following code triggers the alerts in the right order:
$("#testButton").click(function () {
alert('1');
setTimeout(function () { alert('2'); }, 2000);
setTimeout(function(){ alert('3'); }, 4000);
});
But not when the timeouts are closer. The following displays the alerts in wrong order:
$("#testButton").click(function () {
alert('1');
setTimeout(function () { alert('2'); }, 1);
setTimeout(function(){ alert('3'); }, 2);
});
As proposed by @Bergi in the comments, I've tried:
$("#testButton").click(function () {
var x = []; x.push(1); x.push(2); alert(x);
});
With a correct result, displaying an alert containing: "1,2".
Issue has been reported.
As @Bergi suggests in a comment, the version of alert()
you're calling is likely to be asynchronous on some platforms and synchronous on others. This would explain the behavior you're seeing.
Instead of using window.alert()
at all, when you need an alert box you should probably use navigator.notification.alert()
from cordova-plugin-dialogs.
Note the signature for this function:
navigator.notification.alert( message, alertCallback, [title], [buttonName] )
The alertCallback
function gets called after the alert box is dismissed. Even if some implementations are synchronous (because they use the native browser alert()
function) and some are asynchronous, navigator.notification.alert()
provides a compatible interface for both cases.
Well, mostly compatible. On platforms where navigator.notification.alert()
calls the native alert()
, the function will not return until the alert box is dismissed by the user. On platforms that use some other implementation, the function may return immediately. But in both cases, alertCallback
will be called when the alert box is dismissed.
cordova-plugin-dialogs also provides similar implementations of navigator.notification.confirm()
and navigator.notification.prompt()
, each with completion callbacks.
There is an interesting bit of code in tests.js
from cordova-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;
}
Note how this function sets window.alert
to be the same as navigator.notification.alert
on platforms where there is no window.alert
, and also on UWP. While not directly related to your situation, this illustrates how there may be different implementations on different platforms. But using navigator.notification.alert()
should let you write compatible code for all. Just don't assume anything about whether this function returns immediately or waits for the alert to be dismissed - use the alertCallback
instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With