Reputation: 166
This jQuery/History.js code works for loading in content via Ajax by clicking a link and navigating back/forward in the browser, but on manual page refresh the history stack/log is lost and instead of just loading in the same content I loaded in prior I get the actual .erb file and lose the styling/formatting of the page.
$(function(){
$('.nav-bar li a').on('click', function(event){
var urlPath = $(this).attr('href');
// not implemeneted
var title = urlPath.capitalize();
loadContent(urlPath);
// pushes the current page state onto the history stack, and changes the URL
History.pushState('', null, urlPath);
event.preventDefault();
});
// This event makes sure that the back/forward buttons work too
window.onpopstate = function(event){
console.log("pathname: " + location.pathname);
loadContent(location.pathname);
};
});
function loadContent(url){
// Uses jQuery to load the content
$('#content').load(url+'#content', function(){
console.log("Ajax success"); // Ajax
// bxSlider image slider
$('.bxslider').bxSlider({
adaptiveHeight: true,
mode: 'fade',
captions: true
});
});
}
String.prototype.capitalize = function(){
// add capitalize to string - uppercase the first character, add it to the rest of the word
return this.charAt(0).toUpperCase() + this.slice(1);
}
How do I persist data / the history across a manual page refresh? I tried setting the current html to a variable and passing it as a JSON object for the first argument in pushState() but I believe I might have been doing it wrong. What's the best way to implement this? Also, the window.onpopstate function is not run on a manual page refresh so I'm not sure how I would access the object and get the data anyway.
I'm not sure how relevant this is... but I'm running this application in Sinatra
My layout.erb
<!DOCTYPE html>
<html>
<head>
<title>/title>
<link href="http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="/css/style.css" media="screen"/>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="//browserstate.github.io/history.js/scripts/bundled/html4+html5/jquery.history.js"> </script>
<script src="/js/jquery.bxslider.js"></script>
<script src="/js/jquery.bxslider.min.js"></script>
<link href="/css/jquery.bxslider.css" rel="stylesheet" type="text/css" />
<script src="/js/application.js"></script>
<link rel="shortcut icon" href="/images/favicon.ico" type="image/x-icon">
</head>
<body>
<nav class="nav-bar">
<ul>
<li><a href="/" id="nav-bar">Home</a></li>
<li><a href="about" id="nav-bar">About</a></li>
<li><a href="portfolio" id="nav-bar">Portfolio</a></li>
<li><a href="resume" id="nav-bar">Resume</a></li>
</ul>
</nav>
<%= yield %>
</body>
The rest of my .erb views consist of a div with an ID of content and other HTML markup inside of them. Also, when the ajax call works, it seems to append a second div with an ID of content upon ajax success. How do I prevent that?
TL;DR
How to maintain page state with manual refresh, instead of loading in the actual view and losing the formatting/styling.
Upvotes: 1
Views: 1329
Reputation: 6089
You can use localStorage
, that in the first page store you data and at any other page you get your again.
Upvotes: 0
Reputation: 3650
You have defined
// This event makes sure that the back/forward buttons work too
window.onpopstate = function(event){
console.log("pathname: " + location.pathname);
loadContent(location.pathname);
};
within a jQuery block:
$(function(){
...
)
This forces it to be ran after the document has loaded, so it isn't defined until after the first popstate event has occurred.
Upvotes: 1