【问题标题】:Wait for page to load when navigating back in jquery mobile在jquery mobile中导航时等待页面加载
【发布时间】:2014-08-19 17:42:57
【问题描述】:

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

只是做

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

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

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

(编辑:原来 Mobile Safari 不支持原生 js 承诺;需要由第 3 方库替换)

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

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

【问题讨论】:

    标签: javascript jquery-mobile promise es6-promise


    【解决方案1】:

    更新

    要区分用户是否来自 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 */
       }
    });
    

    【讨论】:

    • 正如我在问题中所写,我认为使用事件会使代码更难读,+ 您还需要区分上述用例和用户导航的用例从 pageX 到 menuPage。
    • @marrgold 无论您以编程方式还是手动方式导航,这些事件都会在 pagecontainer 上持续发出。
    • 是的,因此需要区分这两种情况,因为在用户手动导航到那里的情况下,您不想 doSomething()
    • @marrgold 你可以在更改页面函数中传递一个参数来区分用户是否被系统引导stackoverflow.com/questions/21139572/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多