Solved

pushState weird issue

Posted on 2014-03-03
14
276 Views
Last Modified: 2014-03-14
Using pushState I load new content on the page and slide it over the current content and change the url.
If I click the back button then everything happens in reverse and this is all fine.

But if I load the new content (page slide), refresh the page and then click back, the URL changes correctly but it is still showing the refreshed page html.
Looking in Firebug it shows the refreshed page html, looking at the source it shows the correct source of the page i.e. the previous page.
If I click back again and then forward, the page reloads correctly.
I'm confused!

(where are you leakim)
0
Comment
Question by:Gary
  • 7
  • 7
14 Comments
 
LVL 82

Expert Comment

by:leakim971
ID: 39903522
First line of the javascript loading the content of the page, place an alert(or add a console.log).
You should easily understand what happening

I think your ajax get the url to choose what to load but that doesn't match with the history page(its original content)
0
 
LVL 58

Author Comment

by:Gary
ID: 39911388
Sorry leakim thought I had replied to this.
What I don't understand is why when I refresh the page and click back I am not getting the previous page HTML.
I think I need to do some deep research into how this works.
0
 
LVL 82

Expert Comment

by:leakim971
ID: 39911483
My thought :
The refreshed page content is different than the content replaced by ajax
That why I asked you to put a breakpoint before your ajax call so you will be able to check the DOM before the ajax call.
0
 
LVL 58

Author Comment

by:Gary
ID: 39916604
This is really annoying.
I've uploaded a test page
http://www.book-your-trip.com/master.php

Click the button and you get the ajax response, click back and it resets the page (nothing is reloaded) All good.

Click the button, refresh the page, click back, the page content doesn't change even though history.pushState is being fired.  It is definitely not loading because you cannot access the master page divs.
Do I need to store the previous page data and push that back to the page - if so it doesn't make sense as it should be there in the history already.
0
 
LVL 82

Accepted Solution

by:
leakim971 earned 500 total points
ID: 39929266
I got it working with the following code snippet.

As you said, you need to store the "state/view/part"
You need to save it before altering (line 9 must be before line 10)

<!DOCTYPE html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script> 
<script>
	$(function(){
		history.replaceState({ "view":$("#view").html() }, null, "/master.php");
		$("#button").click(function(e) {
			$.get('/myajax.php', function(response) {
				history.pushState({ "view":$("#view").html() }, null, "/myajax.php");
				$("#view").html(response);
			});
		});
	});

	$(window).on("popstate", function(event) {
		var state = event.originalEvent.state;
		if(state && state.view) {
			$("#view").html(state.view);
		}
	});

</script>
</head>
<body>
	<div id="view">
		<div class="hideme">This is the master page</div>
		<input type="button" id="button" value="Click Me to load the ajax">
	</div>
</body>
</html>

Open in new window

0
 
LVL 58

Author Comment

by:Gary
ID: 39929902
Thought yeahhh!!!
But it's not working leakim, changes uploaded - same problem.

Even more weird if you click back again and then click forward the page does load properly.
0
 
LVL 82

Expert Comment

by:leakim971
ID: 39930041
Your server need to deliver the master.php page everytime else, when you hit the refresh button you're reloading the Ajax page, not the master.php page where you're the code to put the right view content on popstate.

Somewhere in Apache, look for This should be changed to whatever you set DocumentRoot to:

#
# This should be changed to whatever you set DocumentRoot to.
#
<Directory "path/to/httpd/htdocs">
    Options Indexes FollowSymLinks ExecCGI

    AllowOverride None

    Order allow,deny
    Allow from all

    Options +FollowSymLinks -MultiViews
    RewriteEngine On

    RewriteRule ^([^/\.]+)/?$ master.php [L]

</Directory>

Open in new window

0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 58

Author Comment

by:Gary
ID: 39930221
Uhmm, but the page should be in the history when you click back.
It is there since if you click back twice (from the refreshed page) and then click forward the correct page shows from history. But not if you only click back once - the page isn't loaded from history even tho the source of the page shows the correct HTML

I don't use Apache. Not seeing what document root would do.

I just had a play with history.js and it has the same problem, refresh the page and click back and its lost.

edit.
I think I am getting somewhere...
0
 
LVL 82

Expert Comment

by:leakim971
ID: 39930232
Uhmm, but the page should be in the history when you click back.
It is there since if you click back twice (from the refreshed page) and then click forward the correct page shows from history. But not if you only click back once - the page isn't loaded from history even tho the source of the page shows the correct HTML

When you're doing the reload, you're not anymore on the original page but on another one, your simple myajax.php

When not doing the refresh you're on the original page but you just add history (pushed new url which is different from "page caching")

yes, state and page caching are not the same thing
state add URL in history but not content until you save it yourself and associate it with the page

What is your php server? IIS ?
0
 
LVL 58

Author Comment

by:Gary
ID: 39930241
I use nGinx

you're not anymore on the original page but on another one
So logic would dictate that if I click back (remembering I am not changing the history as their is no code on this refreshed page) then I should be loading the previous page.
0
 
LVL 82

Expert Comment

by:leakim971
ID: 39930266
I think the logic is broken as soon you refresh the page
0
 
LVL 82

Expert Comment

by:leakim971
ID: 39930288
For nGinx : https://gist.github.com/shreyas-satish/8452999
# Re-route nested routes through index
  location / {
    try_files $uri $uri/ /index.html =404;
  }

Open in new window

0
 
LVL 58

Author Comment

by:Gary
ID: 39930376
Don't see what routes have to do with it. Anyway that is a default configuration on nginx.

But I think I am getting somewhere. I need to have the pushstate code in the refreshed page, but not in the ajaxed page.
Only problem now is if you refresh and click back (which now works) and then click the button I get a state error, but I think that's down to the code somewhere.
0
 
LVL 58

Author Closing Comment

by:Gary
ID: 39930659
Seems to be working fine now, just need to get the forward button working now.

Thanks
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Introduction A frequently asked question goes something like this:  "I am running a long process in the background and I want to alert my client when the process finishes.  How can I send a message to the browser?"  Unfortunately, the short answer …
JavaScript can be used in a browser to change parts of a webpage dynamically. It begins with the following pattern: If condition W is true, do thing X to target Y after event Z. Below are some tips and tricks to help you get started with JavaScript …
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now