JQuery Mobile: Breaks When Reloading / Deep Linking / Bookmarking Pages Added to DOM via AJAX

I am creating a mobile site using jQuery Mobile, and one of my testers pointed out a problem while reloading, deep linking or bookmarking any pages loaded in the DOM using the standard page loading functions built into jQuery Mobile. I was looking through documentation, forum posts, lists of github errors, etc., etc., Looking for a solution, and I am on my way that I can do wrong. I made a very simple two-page example that shows what I see.

Firstly, I have an index.html page in the root folder of my site (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 have a second page in the "news" folder (ie /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 displays http://m.example.com/ .

I can click the News link to load this page in the DOM. The browser address field now displays http://m.example.com/news/ . That is where my problem is. If you click the reload button of the browser, the /news/index.html page will reload, but the main context of the main page is completely missing, so there is no jQuery, css or proper HTML document structure. I expect this to be the case considering the URL and contents of its document. But I need links to subpages to work when they are deeply connected to my mobile site.

If you link to a subpage using http://m.example.com/#news/ , this works, if the subpage is loaded correctly, the browser address field will automatically be rewritten to http://m.example.com/news/ . The problem is that people need to know that they need to manually edit the URL whenever they bookmark, tweet, email, etc. URL of the page.

Is there a way to automatically drop the browser to the home page and then start loading the subpage transparent to the user so that the DOM is recreated? What am I missing?

+4
source share
4 answers

Well, based on Kaneโ€™s suggestion, I changed my sample code as such, and now it works the way I wanted.

The index.html page in my 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 the "news" folder (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 --> 

Pressing the reload or deep binding / bookmark on the subpage now bounces the visitor to the main page, and then loads onto the subpage correctly. On the subpage, a redirect is created using http://m.example.com/#/news/ .

I hope this information saves someone else a few hours by hitting his head on the keyboard.

+3
source

Thanks so much for this solution. This gave me some errors, so I simplified it a bit and seems to work 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 this helps others who are experiencing this issue.

Regards

Will Ferrer

+1
source

The easiest way is to redirect to the main page: Subapge example: 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 be launched only when the page is reloaded, because through ajax only code with the data role = "page" is inserted.

+1
source

I have a similar situation where I use some server-side processing to determine whether to display content in my site template for new requests or only for my own content for requests from ajax.

Basically, I just add a message or get a variable called "partial" in my ajax requests and decides whether to include the template.

If you don't want to do any server-side work (which is the ideal way to do this 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 tags and script stylesheets to your page. Then at subsequent page loads via ajax window.firstload will be set to true so that this does not happen again.

0
source

Source: https://habr.com/ru/post/1394318/


All Articles