javascript - Wait for page to load when navigating back in jquery mobile -
i have single-page web app built jquery mobile. after user completes action, want programmatically bring them menu page, involves going in history , performing actions on elements of menu page.
simply doing
window.history.go(-1); //or $.mobile.back(); dosomethingwith(menupageelement);
doesn't work, because going-back action asynchronous, i.e. need way of waiting page load before calling dosomethingwith()
.
i ended using window.settimeout(), i'm wondering if there's not easier way (different pattern?) in jqm. 1 other option listen pageload events, find worse code organization point of view.
(edit: turns out native js promises not supported on mobile safari; need substitute 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 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 nextcheckin ms timespentwaiting += nextcheckin; window.settimeout(function() { waituntilelementvisible(element, timespentwaiting); }, nextcheckin); } } }); }
which can used this:
go(-2, menupageelement).then(function() { dosomethingwith(menupageelement); }, function() { handleerror(); });
posting here instead of in code review since question alternative ways in jqm/js rather performance/security of code itself.
update
to differntiate whether user directed pagex, can pass custom parameter in pagecontainer change function. on pagecontainerchange
, retrieve parameter , according bind pagecontainershow
1 time dosomething()
.
$(document).on("pagecreate", "#foopage", function () { $("#bar").on("click", function () { /* determine whether user directed */ $(document).one("pagecontainerbeforechange", function (e, data) { if ($.type(data.topage) == "string" && $.type(data.options) == "object" && data.options.stuff == "redirect") { /* true? bind pagecontainershow 1 time */ $(document).one("pagecontainershow", function (e, ui) { /* */ $(".ui-content", ui.topage).append("<p>redirected</p>"); }); } }); /* redirect user programmatically */ $.mobile.pagecontainer.pagecontainer("change", "#menupage", { stuff: "redirect" }); }); });
you need rely on pagecontainer events, can choose of these events, pagecontainershow
, pagecontainerbeforeshow
, pagecontainerhide
, pagecontainerbeforehide
.
the first 2 events emitted when previous page hidden , before showing menu page.
the second 2 events emitted during hiding previous page before first 2 events.
all events carry ui
object, 2 different properties ui.prevpage
, ui.topage
. use these properties determine when run code.
note below code works jqm 1.4.3
$(document).on("pagecontainershow", function (e, ui) { var previous = $(ui.prevpage), next = $(ui.topage); if (previous[0].id == "pagex" && next[0].id == "menupage") { /* */ } });
Comments
Post a Comment