diff --git a/examples/historyApi.html b/examples/historyApi.html
new file mode 100644
index 000000000..7601ba67a
--- /dev/null
+++ b/examples/historyApi.html
@@ -0,0 +1,38 @@
+
+
+
+
+
+
fullPage.js
+
+
Simple Demo
+
Only text
+
And text
+
And more text
+
+
No wraps, no extra markup
+
Just the simplest demo ever
+
+
+
+
+
+
diff --git a/src/fullpage.js b/src/fullpage.js
index d7c36b6ca..7a7ffb265 100644
--- a/src/fullpage.js
+++ b/src/fullpage.js
@@ -151,6 +151,7 @@
keyboardScrolling: true,
animateAnchor: true,
recordHistory: true,
+ historyApi: false,
//design
controlArrows: true,
@@ -668,11 +669,34 @@
//setting the class for the body element
setBodyClass();
+ /*
+ * HTML5 History API
+ * Test history features
+ */
+ if(options.historyApi){
+ historyApiTestFeatures();
+ }
if(document.readyState === 'complete'){
- scrollToAnchor();
+ /*
+ * HTML5 History API
+ * Scroll to the right section on document complete
+ */
+ if(options.historyApi){
+ historyApiScrollToPath();
+ } else {
+ scrollToAnchor();
+ }
+ }
+ /*
+ * HTML5 History API
+ * Scroll to the right section on document load
+ */
+ if(options.historyApi) {
+ window.addEventListener('load', historyApiScrollToPath);
+ } else {
+ window.addEventListener('load', scrollToAnchor);
}
- window.addEventListener('load', scrollToAnchor);
//if we use scrollOverflow we'll fire afterRender in the scrolloverflow file
if(!options.scrollOverflow){
@@ -725,6 +749,13 @@
forMouseLeaveOrTouch(eventName, true);
});
}
+ /**
+ * HTML5 History API
+ * Scroll to the right section when clicking on back or forward buttons
+ */
+ if(options.historyApi) {
+ window.addEventListener('popstate', historyApiPopStateHandler);
+ }
}
function delegatedEvents(e){
@@ -2143,6 +2174,75 @@
}
});
}
+
+ /**
+ * HTML5 History API
+ * Function called on init()
+ * It will test for history api features
+ */
+ function historyApiTestFeatures() {
+ if ('scrollRestoration' in history) {
+ window.history.scrollRestoration = 'manual';
+ }
+ }
+
+ /**
+ * HTML5 History API
+ * Function called from popstate eventlistener
+ * It will scroll to the right section and slide (restore state) when the user clicks on back or forward buttons
+ */
+ function historyApiPopStateHandler(event) {
+ var state = historyApiStateFromUrlString(event.state);
+ moveTo(state.section, state.slide);
+ }
+
+ /**
+ * HTML5 History API
+ * Will push a new history state and url only if the same record is not already in the previous history.state
+ * This will prevent from adding the same state when using the back or forward buttons
+ */
+ function historyApiPushRecord(url) {
+ if(window.history.state !== url) {
+ window.history.pushState(url, null, '/' + url);
+ }
+ }
+
+ /**
+ * HTML5 History API
+ * Convert URL string to state object
+ * NOTE: If accepted, this one could be merged with getAnchorsURL(urlString) and process any urlString as input
+ * regardless if it starts with #, / or #/
+ */
+ function historyApiStateFromUrlString(urlString) {
+ var urlParts = urlString;
+ var section;
+ var slide;
+
+ if (urlString && urlString !== '/' ) {
+ urlParts = urlParts.replace(/^\//, '').split('/');
+ section = urlParts[0];
+ slide = urlParts[1];
+ } else if (!urlString) {
+ // TODO: In the future this should query for the default active section/slide
+ section = 1;
+ }
+
+ return {
+ section: section,
+ slide: slide
+ }
+ }
+
+ /**
+ * HTML5 History API
+ * Get the url from location.pathname and scroll to the right section and slide when loading the site
+ */
+ function historyApiScrollToPath() {
+ if( window.location.pathname !== '/' ) {
+ var path = historyApiStateFromUrlString(window.location.pathname);
+ moveTo(path.section, path.slide);
+ }
+ }
/**
* Gets the active slide (or section) for the given section
@@ -2962,14 +3062,26 @@
*/
function setUrlHash(url){
if(options.recordHistory){
- location.hash = url;
+ if(options.historyApi) {
+ // Pushes State to history api
+ historyApiPushRecord(url);
+ } else {
+ location.hash = url;
+ }
+
}else{
- //Mobile Chrome doesn't work the normal way, so... lets use HTML5 for phones :)
- if(isTouchDevice || isTouch){
- window.history.replaceState(undefined, undefined, '#' + url);
- }else{
- var baseUrl = window.location.href.split('#')[0];
- window.location.replace( baseUrl + '#' + url );
+
+ if(options.historyApi) {
+ // Pushes State to history api
+ historyApiPushRecord(url);
+ } else {
+ //Mobile Chrome doesn't work the normal way, so... lets use HTML5 for phones :)
+ if(isTouchDevice || isTouch){
+ window.history.replaceState(undefined, undefined, '#' + url);
+ }else{
+ var baseUrl = window.location.href.split('#')[0];
+ window.location.replace( baseUrl + '#' + url );
+ }
}
}
}
@@ -3299,6 +3411,11 @@
['mouseenter', 'touchstart', 'mouseleave', 'touchend'].forEach(function(eventName){
document.removeEventListener(eventName, onMouseEnterOrLeave, true); //true is required!
});
+ /**
+ * HTML5 History API
+ * Remove EventListener Needed for back and forward buttons to work
+ */
+ window.removeEventListener('popstate', historyApiPopStateHandler);
//lets make a mess!
if(all){