在jquery mobile中导航时等待页面加载

时间:2014-08-18 08:35:30

标签: javascript jquery-mobile promise es6-promise

我有一个使用jQuery Mobile构建的单页Web应用程序。在用户完成某个操作后,我想以编程方式将它们带回菜单页面,其中包括返回历史记录,然后对菜单页面的元素执行某些操作。

简单地做

window.history.go(-1); //or $.mobile.back();
doSomethingWith(menuPageElement);

不起作用,因为返回操作是异步的,即我需要一种在调用doSomethingWith()之前等待页面加载的方法。

我最终使用了window.setTimeout(),但我想知道在jQM中是否有更简单的方法(不同的模式?)。另一种选择是监听页面加载事件,但从代码组织的角度来看,我发现它更糟糕。

(编辑:结果是Mobile Safari不支持原生js承诺;需要替换第三方库)

//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);
            }
        }
    });
}

可以这样使用:

go(-2, menuPageElement).then(function() { 
    doSomethingWith(menuPageElement);
}, function() {
    handleError();
});

在此处发布,而不是在Code Review中,因为问题是关于在jQM / js中执行此操作的替代方法,而不是代码本身的性能/安全性。

1 个答案:

答案 0 :(得分:0)

更新

要区分用户是否来自pageX,您可以在 pagecontainer change 功能中传递自定义参数。在pagecontainerchange上,检索该参数并将绑定pagecontainershow仅限doSomething()一次。

$(document).on("pagecreate", "#fooPage", function () {
    $("#bar").on("click", function () {
        /* determine whether the user was directed */
        $(document).one("pagecontainerbeforechange", function (e, data) {
            if ($.type(data.toPage) == "string" && $.type(data.options) == "object" && data.options.stuff == "redirect") {
                /* true? bind pagecontainershow one time */
                $(document).one("pagecontainershow", function (e, ui) {
                    /* do something */
                    $(".ui-content", ui.toPage).append("<p>redirected</p>");
                });
            }
        });
        /* redirect user programmatically */
        $.mobile.pageContainer.pagecontainer("change", "#menuPage", {
            stuff: "redirect"
        });
    });
});
  

<强> Demo


您需要依赖 pageContainer事件,您可以选择以下任何事件:pagecontainershowpagecontainerbeforeshowpagecontainerhidepagecontainerbeforehide

上一页完全隐藏并显示菜单页之前,会发出前两个事件。

在隐藏上一页期间但在前两个事件之前发出了后两个事件。

所有活动都包含ui个对象,其中包含两个不同的属性ui.prevPageui.toPage。使用这些属性来确定何时运行代码。

请注意,以下代码仅适用于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") {
       /* do something */
   }
});