Reputation: 105
I'm building out a mobile site using jQuery Mobile and one of my testers pointed out a problem when re-loading, deep linking to, or bookmarking any pages that I've loaded into the DOM using the standard page loading functionality built into jQuery Mobile. I've been reviewing the documentation, forum posts, github bug lists, etc, etc looking for a solution and I'm at my wits end on what I might be doing wrong. I've compiled an extremely basic two page example that demonstrates what I'm seeing.
First off, I've got an index.html page in my example site root folder (i.e. /index.html
) that looks like this:
<!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>
I've got a second page in a folder called 'news' (i.e. /news/index.html
) that looks like this:
<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 -->
So, this works great. The "home page" loads fine. The browser address field shows http://m.example.com/
.
I can click the 'News' link to load that page into the DOM. The browser address field now shows http://m.example.com/news/
. This is where my problem lies. If you click the browser reload button, the /news/index.html
page gets reloaded but is completely missing the main home page context, so no jQuery, css or proper HTML document structure. I'd expect that to be the case given the URL and its document content. But I need links to sub-pages to work when being deep linked to from outside my mobile site.
If you link to the subpage using http://m.example.com/#news/
, this works, with the subpage loading correctly and the browser address field getting automatically rewritten to http://m.example.com/news/
. The problem with this is that people would need to know that they need to manually edit the URL whenever they bookmark, tweet, e-mail, etc the page URL.
Is there a way to automatically kick the browser back to the home page and then trigger the loading of the subpage, transparent to the user, so that the DOM is re-created correctly? What am I missing?
Upvotes: 4
Views: 3200
Reputation: 5887
the easiest way is to redirect to the main page: Example subapge: login.htm
<script type="text/javascript">
window.location="index.htm";
</script>
<div data-role="page" id='login'>
Ur sub page
</div><!-- /page -->
The js code will only be fired, when the page is reloaded, because only the code with data-role="page" is inserted via ajax.
Upvotes: 1
Reputation: 41
Thank you very much for this solution. It was giving me some errors so I simplified it a bit and it seems to be working for me now:
/**
* 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(/#.+$/, '');
}
Hope that helps others that are experiencing this issue.
Best regards
Will Ferrer
Upvotes: 1
Reputation: 105
Okay, based on Kane's suggestion, I've modified my sample code as such and it now seems to work as I wanted.
The index.html page in my example site root folder (i.e. /index.html
) now looks like this:
<!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>
And my second page in a folder called 'news' (i.e. /news/index.html
) now looks like this:
<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 -->
Hitting reload, or deep linking/bookmarking, on the subpage now bounces the visitor up to the main page and then loads in the subpage properly. In the subpage, the redirect is generated to http://m.example.com/#/news/
.
Hopefully this info will save someone else a few hours of banging their head on the keyboard.
Upvotes: 3
Reputation: 2322
I have a similar situation where I use some server-side processing to determine whether to render the content in my site template for new requests or just the content on its own for requests from ajax.
Basically, I just add a post or get variable called 'partial' to my ajax requests and that decides whether to include the template.
If you do not want to do any server-side work (which is the ideal way to do it IMO) then the only other way I can think of is to add something like this to every page:
if( window.firstload === undefined )
{
// Add script tags and stylesheets to the page and potentially load
// your site template into the DOM
window.firstload = true;
}
When the first page loads the variable window.firstload will be undefined so you can add all the script tags and stylesheets to your page. Then on subsequent page loads via ajax window.firstload will be set to true so it won't happen again.
Upvotes: 0