jQuery Mobile:重新加载/深度链接/书签通过AJAX添加到DOM的页面时中断

时间:2012-02-02 02:21:39

标签: jquery ajax jquery-mobile reload deep-linking

我正在使用jQuery Mobile构建一个移动网站,我的一位测试人员在使用标准页面加载功能重新加载,深度链接或书签我加载到DOM中的任何页面时指出了一个问题内置于jQuery Mobile中。我一直在审查文档,论坛帖子,github错误列表等等,寻找解决方案,我在我的智慧结束我可能做错了什么。我编写了一个非常基本的两页示例,演示了我所看到的内容。

首先,我的示例站点根文件夹(即/index.html)中有一个index.html页面,如下所示:

<!DOCTYPE html>
<html>
<head>
   <title>Home Page</title>
   <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css" />
   <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
   <script src="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.js"></script>
</head>
<body>
<!-- main page -->
<div data-role="page" data-theme="b" id="main">
   <div data-role="header" data-theme="b">
      <h1>Home Page</h1>
   </div><!-- /header -->
   <div data-role="content">
      <ul data-role="listview" data-inset="true">
         <li><a href="news/">News</a></li>
      </ul>
   </div><!-- /content -->
</div><!-- /main page -->
</body>
</html>

我在名为'news'(即/news/index.html)的文件夹中有第二页,如下所示:

<div data-role="page" data-theme="b" data-add-back-btn="true" id="news">
   <div data-role="header" data-theme="b">
      <h1>News</h1>
   </div><!-- /header -->
   <div data-role="content">
      TODO: page content goes here
   </div><!-- /content -->
</div><!-- /#news page -->

所以,这很有效。 “主页”加载正常。浏览器地址字段显示http://m.example.com/

我可以点击“新闻”链接将该页面加载到DOM中。浏览器地址字段现在显示http://m.example.com/news/。这就是我的问题所在。如果单击浏览器重新加载按钮,/news/index.html页面将重新加载,但完全缺少主页面上下文,因此没有jQuery,css或正确的HTML文档结构。鉴于URL及其文档内容,我希望是这种情况。但是当我从移动网站外部深层链接时,我需要链接到子页面。

如果您使用http://m.example.com/#news/链接到子页面,则可以正常加载子页面,并且浏览器地址字段会自动重写为http://m.example.com/news/。这样做的问题是人们需要知道他们需要在书签,推文,电子邮件等页面URL时手动编辑URL。

有没有办法自动将浏览器踢回主页,然后触发加载子页面,对用户透明,以便正确地重新创建DOM?我错过了什么?

4 个答案:

答案 0 :(得分:3)

好的,基于Kane的建议,我已经修改了我的示例代码,现在它似乎按照我想要的方式工作。

我的示例网站根文件夹中的index.html页面(即/index.html)现在看起来像这样:

<!DOCTYPE html>
<html>
<head>
   <title>Home Page</title>
   <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css" />
   <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
   <script src="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.js"></script>
   <script type="text/javascript">
if( window.firstload === undefined ) {
    window.firstload = true;
}
   </script>
</head>
<body>
<!-- main page -->
<div data-role="page" data-theme="b" id="main">
   <div data-role="header" data-theme="b">
      <h1>Home Page</h1>
   </div><!-- /header -->
   <div data-role="content">
      <ul data-role="listview" data-inset="true">
         <li><a href="news/">News</a></li>
      </ul>
   </div><!-- /content -->
</div><!-- /main page -->
</body>
</html>

我在名为'news'(即/news/index.html)的文件夹中的第二页现在看起来像这样:

<script type="text/javascript">
if(window.firstload === undefined) {
    for(var i=0, c=0; i < window.location.href.length; i++){
      if(window.location.href.charAt(i) == '/') {
        c++;
        if(c==3) window.location = window.location.href.substr(0,i) 
                                   + '/#'
                                   + window.location.href.substr(i);
      }
    }
}
</script>
<div data-role="page" data-theme="b" data-add-back-btn="false" id="news">
   <div data-role="header" data-theme="b">
      <a href="#main" data-icon="arrow-l" data-iconpos="notext" data-direction="reverse"></a>
      <h1>News</h1>
      <a href="#main" data-icon="home" data-role="button" data-iconpos="notext" data-transition="fade">Home</a>
   </div><!-- /header -->
   <div data-role="content">
      TODO: page content goes here
   </div><!-- /content -->
</div><!-- /#news page -->

在子页面上点击重新加载或深层链接/书签,现在将访问者弹回到主页面,然后正确加载到子页面中。在子页面中,重定向生成为http://m.example.com/#/news/

希望这些信息可以帮助别人在键盘上敲打几个小时。

答案 1 :(得分:1)

非常感谢您提供此解决方案。它给了我一些错误,所以我简化了一下它现在似乎对我有用了:

/**
 * fixes the problem where a subpage in jquerymobile will lose its back button after a refresh. Instead a refresh takes you back to the top page
 * http://stackoverflow.com/questions/9106298/jquery-mobile-breaks-when-reloading-deep-linking-bookmarking-pages-added-to
 */
if(window.firstload === undefined && /#.+$/.test(window.location.href)) {
    window.location = window.location.href.replace(/#.+$/, '');
}

希望能帮助遇到此问题的其他人。

祝你好运

Will Ferrer

答案 2 :(得分:1)

最简单的方法是重定向到主页面: 示例subapge:login.htm

<script type="text/javascript">
    window.location="index.htm";
</script>

<div data-role="page" id='login'>
    Ur sub page
</div><!-- /page -->

只有在重新加载页面时才会触发js代码,因为只有带有 data-role =“page”的代码才会通过ajax插入。

答案 3 :(得分:0)

我有类似的情况,我使用一些服务器端处理来确定是否在我的网站模板中为新请求呈现内容,或仅为ajax请求呈现内容。

基本上,我只是在我的ajax请求中添加一个帖子或获取名为'partial'的变量,并决定是否包含该模板。

如果你不想做任何服务器端的工作(这是做IMO的理想方式),那么我能想到的另一种方法是在每个页面上添加这样的东西:

if( window.firstload === undefined )
{
    // Add script tags and stylesheets to the page and potentially load
    // your site template into the DOM

    window.firstload = true;
}

当第一个页面加载变量window.firstload时将是未定义的,因此您可以将所有脚本标记和样式表添加到页面中。然后通过ajax window.firstload将后续页面加载设置为true,这样就不会再发生了。