dojo.back.addToHistory
dojo.require("dojo.back");
defined in dojo/back.js
To support getting back button notifications, the object
argument should implement a function called either "back",
"backButton", or "handle". The string "back" will be passed as
the first and only argument to this callback.
To support getting forward button notifications, the object
argument should implement a function called either "forward",
"forwardButton", or "handle". The string "forward" will be
passed as the first and only argument to this callback.
If you want the browser location string to change, define "changeUrl" on the object. If the
value of "changeUrl" is true, then a unique number will be appended to the URL as a fragment
identifier (http://some.domain.com/path#uniquenumber). If it is any other value that does
not evaluate to false, that value will be used as the fragment identifier. For example,
if changeUrl: 'page1', then the URL will look like: http://some.domain.com/path#page1
Usage
// BROWSER NOTES:
// Safari 1.2:
// back button "works" fine, however it's not possible to actually
// DETECT that you've moved backwards by inspecting window.location.
// Unless there is some other means of locating.
// FIXME: perhaps we can poll on history.length?
// Safari 2.0.3+ (and probably 1.3.2+):
// works fine, except when changeUrl is used. When changeUrl is used,
// Safari jumps all the way back to whatever page was shown before
// the page that uses dojo.undo.browser support.
// IE 5.5 SP2:
// back button behavior is macro. It does not move back to the
// previous hash value, but to the last full page load. This suggests
// that the iframe is the correct way to capture the back button in
// these cases.
// Don't test this page using local disk for MSIE. MSIE will not create
// a history list for iframe_history.html if served from a file: URL.
// The XML served back from the XHR tests will also not be properly
// created if served from local disk. Serve the test pages from a web
// server to test in that browser.
// IE 6.0:
// same behavior as IE 5.5 SP2
// Firefox 1.0+:
// the back button will return us to the previous hash on the same
// page, thereby not requiring an iframe hack, although we do then
// need to run a timer to detect inter-page movement.
//If addToHistory is called, then that means we prune the
//forward stack -- the user went back, then wanted to
//start a new forward path.
forwardStack = [];
var hash = null;
var url = null;
if(!historyIframe){
if(dojo.config["useXDomain"] && !dojo.config["dojoIframeHistoryUrl"]){
console.debug("dojo.back: When using cross-domain Dojo builds,"
+ " please save iframe_history.html to your domain and set djConfig.dojoIframeHistoryUrl"
+ " to the path on your domain to iframe_history.html");
}
historyIframe = window.frames["dj_history"];
}
if(!bookmarkAnchor){
bookmarkAnchor = document.createElement("a");
dojo.body().appendChild(bookmarkAnchor);
bookmarkAnchor.style.display = "none";
}
if(args["changeUrl"]){
hash = ""+ ((args["changeUrl"]!==true) ? args["changeUrl"] : (new Date()).getTime());
//If the current hash matches the new one, just replace the history object with
//this new one. It doesn't make sense to track different state objects for the same
//logical URL. This matches the browser behavior of only putting in one history
//item no matter how many times you click on the same #hash link, at least in Firefox
//and Safari, and there is no reliable way in those browsers to know if a #hash link
//has been clicked on multiple times. So making this the standard behavior in all browsers
//so that dojo.back's behavior is the same in all browsers.
if(historyStack.length == 0 && initialState.urlHash == hash){
initialState = createState(url, args, hash);
return;
}else if(historyStack.length > 0 && historyStack[historyStack.length - 1].urlHash == hash){
historyStack[historyStack.length - 1] = createState(url, args, hash);
return;
}
changingUrl = true;
setTimeout(function() {
setHash(hash);
changingUrl = false;
}, 1);
bookmarkAnchor.href = hash;
if(dojo.isIE){
url = loadIframeHistory();
var oldCB = args["back"]||args["backButton"]||args["handle"];
//The function takes handleName as a parameter, in case the
//callback we are overriding was "handle". In that case,
//we will need to pass the handle name to handle.
var tcb = function(handleName){
if(getHash() != ""){
setTimeout(function() { setHash(hash); }, 1);
}
//Use apply to set "this" to args, and to try to avoid memory leaks.
oldCB.apply(this, [handleName]);
};
//Set interceptor function in the right place.
if(args["back"]){
args.back = tcb;
}else if(args["backButton"]){
args.backButton = tcb;
}else if(args["handle"]){
args.handle = tcb;
}
var oldFW = args["forward"]||args["forwardButton"]||args["handle"];
//The function takes handleName as a parameter, in case the
//callback we are overriding was "handle". In that case,
//we will need to pass the handle name to handle.
var tfw = function(handleName){
if(getHash() != ""){
setHash(hash);
}
if(oldFW){ // we might not actually have one
//Use apply to set "this" to args, and to try to avoid memory leaks.
oldFW.apply(this, [handleName]);
}
};
//Set interceptor function in the right place.
if(args["forward"]){
args.forward = tfw;
}else if(args["forwardButton"]){
args.forwardButton = tfw;
}else if(args["handle"]){
args.handle = tfw;
}
}else if(!dojo.isIE){
// start the timer
if(!locationTimer){
locationTimer = setInterval(checkLocation, 200);
}
}
}else{
url = loadIframeHistory();
}
historyStack.push(createState(url, args, hash));
Examples
Example 1
dojo.back.addToHistory({
back: function(){ console.debug('back pressed'); },
forward: function(){ console.debug('forward pressed'); },
changeUrl: true
});