Skip to content

Instantly share code, notes, and snippets.

@IUnknown68
Created August 18, 2015 18:13
Show Gist options
  • Save IUnknown68/c5e0f69e8bb7f5114f08 to your computer and use it in GitHub Desktop.
Save IUnknown68/c5e0f69e8bb7f5114f08 to your computer and use it in GitHub Desktop.
History manager.
//==============================================================================
(function(){
var _currentIndex = 0;
var _history = [{
url: location.hash.substr(1) || '/',
index: _currentIndex
}];
var _currentState = _history[_currentIndex];
var _ignorePopstate = false;
//----------------------------------------------------------------------------
function _sendEvent(name, data) {
var color = ('forward' === data.direction)
? 'green'
: ('back' === data.direction)
? 'red'
: 'grey';
$('<div style="color:' + color + '"/>').appendTo($('#logger')).text('Navigate ' + data.direction + ' to ' + data.to.url + '('+data.to.index+')');
if (data.to.index === data.length - 1) {
$('#fwd').attr('disabled', true);
}
else {
$('#fwd').removeAttr('disabled');
}
if (data.to.index === 0) {
$('#back').attr('disabled', true);
$('#back').attr('disabled', true);
}
else {
$('#back').removeAttr('disabled');
}
if (data.to.index < 3) {
$('#backALot').attr('disabled', true);
}
else {
$('#backALot').removeAttr('disabled');
}
$(document).attr('title', data.to.url);
_printHistory();
}
//----------------------------------------------------------------------------
function _printHistory() {
var $history = $('#historyLog');
$history.empty();
_history.forEach(function(entry, index) {
var tn = (entry.index === _currentIndex) ? $('<b/>') : $('<span/>');
tn.text(entry.index + ': ' + entry.url);
$('<div></div>').appendTo($history).append(tn);
});
}
//----------------------------------------------------------------------------
$(document).ready(function() {
history.replaceState(_currentState, '', '#' + _currentState.url);
_sendEvent('navigate', {direction: 'replace', from: null, to: _currentState, length: _history.length});
});
$(window).on('popstate', function(ev) {
if (_ignorePopstate) {
_ignorePopstate = false;
return;
}
var state = ev.originalEvent.state;
var truncate = false;
if (!state) {
// no state for this - create a new one at position _currentIndex + 1
state = {
url: location.hash.substr(1) || '/',
index: _currentIndex + 1
};
truncate = ((state.index < _history.length) && (state.url !== _currentState.url));
}
var direction = 'replace';
if ((state.index > _currentIndex) && (state.index < _history.length) && !truncate) {
direction = 'forward';
}
else if (state.index < _currentIndex) {
direction = 'back';
}
if (state.url === '/dolor' && !confirm('Navigate?')) {
_ignorePopstate = true;
if ('back' === direction) {
history.forward();
}
else {
history.back();
}
return;
}
if (truncate) {
// truncate history to new length
_history.splice(state.index, _history.length);
}
var previousState = _currentState;
_currentIndex = state.index;
_currentState = _history[state.index] = state;
history.replaceState(_currentState, '', '#' + _currentState.url);
_sendEvent('navigated', {direction: direction, from: previousState, to: _currentState, length: _history.length});
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment