I have a single-page web app built with jQuery Mobile. After the user completes a certain action, I want to programmatically bring them back to a menu page, which involves going back in history and then performing some actions on elements of the menu page.
Simply doing
window.history.go(-1); //or $.mobile.back();
doSomethingWith(menuPageElement);
doesn't work, because the going-back action is asynchronous, i.e. I need a way of waiting for the page to load before calling doSomethingWith()
.
I ended up using window.setTimeout(), but I'm wondering if there's not an easier way (different pattern?) to do this in jQM. One other option is to listen for pageload events, but I find it worse from code organization point of view.
(EDIT: turns out native js promises are not supported on Mobile Safari; will need to substitute by a 3rd-party library)
//promisify window.history.go()
function go(steps, targetElement) {
return new Promise(function(resolve, reject) {
window.history.go(steps);
waitUntilElementVisible(targetElement);
//wait until element is visible on page (i.e. page has loaded)
//resolve on success, reject on timeout
function waitUntilElementVisible(element, timeSpentWaiting) {
var nextCheckIn = 200;
var waitingTimeout = 1000;
timeSpentWaiting = typeof timeSpentWaiting !== 'undefined' ? timeSpentWaiting : 0;
if ($(element).is(":visible")) {
resolve();
} else if (timeSpentWaiting >= waitingTimeout) {
reject();
} else { //wait for nextCheckIn ms
timeSpentWaiting += nextCheckIn;
window.setTimeout(function() {
waitUntilElementVisible(element, timeSpentWaiting);
}, nextCheckIn);
}
}
});
}
which can be used like this:
go(-2, menuPageElement).then(function() {
doSomethingWith(menuPageElement);
}, function() {
handleError();
});
Posting it here instead of in Code Review since the question is about alternative ways to do this in jQM/js rather than performance/security of the code itself.