jQuery移动端如何检测页面刷新

6

一些背景信息;

默认情况下,当您单击链接到单独的HTML页面时,JQM会加载该页面上的第一个data-role="page"并将其附加到第一个页面的DOM中,问题在于JQM仅加载该页面div而不加载任何位于容器外部的脚本等。

我有一个jQuery移动应用程序,其中包含5个页面:"login.html","menu.html","account.html","settings.html"等。

我使用以下方式更改页面;

 $.mobile.changepage("account.html")

我将所有页面加载逻辑都放到了我的第一个页面login.html中,像这样;

<script>
     $(document).on('pageinit', '#loginpage', function() {
       //do some stuff run some ajax scripts and add some html to its body
    });

  $(document).on('pageinit', '#accountpage', function() {
        //do some stuff run some ajax scripts and add some html to its body
    });

   $(document).on('pageinit', '#settingspage', function() {
        //do some stuff run some ajax scripts and add some html to its body
    });

</script>

虽然这个应用程序工作得很好,但问题在于我发现它非常脆弱,难以从意外错误中恢复。例如:
由于每个页面的 body html 如何加载是在 login.html 中定义的,这意味着如果用户手动刷新其中任何一个页面,页面将在不运行那些脚本并且没有 body 的情况下加载。此时,由于正确的 DOM 已从内存中删除,用户被困在一个空白页面的应用中,唯一的方法是他足够聪明地去输入 "login.html" 到地址栏,然后所有流程才能顺利地开始。
我认为我们无法完全隐藏地址栏,它在向下滚动后又可见了。
所以这是我遇到的一个问题,还有一些奇怪的事情可能会发生,如果某种方式导致 DOM 损坏,使用应用程序的唯一方法就是在地址栏中键入 login.html,而用户可能不会考虑到这一点。
如何使这个应用程序更加健壮,例如检测任何 DOM 损坏或刷新,并将用户转发到 login.html,以便他不会被困在一个有空白页面的应用程序中。

为什么不在所有页面上放置所有脚本,这样无论用户从哪个页面开始,他都将运行所有脚本?然后,如果您想进行优化,可以使用条件加载器(如requireJS)仅在用户访问的第一个页面中拉取JS文件。这样,您可以使页面保持干净,并且require会在用户首次访问的任何位置放置您的逻辑。 - frequent
1个回答

2
缓解一些疼痛的方法之一是将页面特定脚本放置在适当的HTML文件中的data-role="page"元素内,并将所有页面通用的脚本放在该元素外(在body和/或head的末尾)
这样,即使用户刷新页面,所有必要的脚本仍将被执行。但有一个问题,绑定任何处理程序之前,您需要先取消绑定它们。否则,您最终会附加多个处理程序。
举例说明:
login.html中(已更新):
<div data-role="page" id="loginpage">
    <script>
        $(document).off('pageinit', '#loginpage').on('pageinit', '#loginpage', function() {
            $(document).off('click', '#btnaccount').on('click', '#btnaccount', function(){
                $.mobile.changePage("jqmaccount.html", {reloadPage: true});
            });
            console.log("paginit in loginpage");
        });
        $(document).off('pageshow', '#loginpage').on('pageshow', '#loginpage', function() {
            console.log("pageshow in loginpage");
        });
    </script>
    <div data-role="content">
        <a id="btnaccount" href="#" data-role="button">Account</a>
    </div>
</div>

account.html 中(已更新):
<div data-role="page" id="accountpage">
    <script>
    $(document).off('pageinit', '#accountpage').on('pageinit', '#accountpage', function() {
        $(document).off('click', '#btnlogout').on('click', '#btnlogout', function(){
            $.mobile.changePage("jqmlogin.html", {reloadPage: true});
        });
        console.log("pageinit in accountpage");
    });
    $(document).off('pageshow', '#accountpage').on('pageshow', '#accountpage', function() {
        console.log("pageshow in accountpage");
    });
    </script>
    <div data-role="content">
        <a id="btnlogout" href="#" data-role="button">Logout</a>
    </div>
</div>

在这个设置中,如果用户刷新account.html页面,该页面上的“注销”按钮仍然可以使用。

谢谢,它大部分都可以工作,但我有一个问题...如果我刷新页面,它会完美地加载,但是如果我回退一页,然后再次前进到那个页面,它不会再次加载,并显示缓存中的上一页。 有什么想法吗? - Spring
我尝试在每个changepage上使用reloadpage:true,但没有帮助,仍然从缓存加载。 - Spring
我非常欣赏你对此的想法 :) - Spring
更新了一下示例代码。对我来说,使用 reloadPage 完全正常。无论我手动刷新账户页面与否,两个事件 pageinitpageshow 都会触发。 - peterm
纯魔法,谢谢!pageshow与取消点击绑定一起起了作用。所以我猜我不需要在任何地方使用pageinit了? - Spring

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接