/ Published in: Other
Expand |
Embed | Plain Text
Copy this code and paste it in your HTML
/* * jQuery history plugin * * The MIT License * * Copyright (c) 2006-2009 Taku Sano (Mikage Sawatari) * Copyright (c) 2010 Takayuki Miwa * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ (function($) { var locationWrapper = { put: function(hash, win) { (win || window).location.hash = this.encoder(hash); }, get: function(win) { var hash = ((win || window).location.hash).replace(/^#/, ''); try { return $.browser.mozilla ? hash : decodeURIComponent(hash); } catch (error) { return hash; } }, encoder: encodeURIComponent }; var iframeWrapper = { id: "__jQuery_history", init: function() { var html = '<iframe id="'+ this.id +'" style="display:none" src="javascript:false;" />'; $("body").prepend(html); return this; }, _document: function() { return $("#"+ this.id)[0].contentWindow.document; }, put: function(hash) { var doc = this._document(); doc.open(); doc.close(); locationWrapper.put(hash, doc); }, get: function() { return locationWrapper.get(this._document()); } }; function initObjects(options) { options = $.extend({ unescape: false }, options || {}); locationWrapper.encoder = encoder(options.unescape); function encoder(unescape_) { if(unescape_ === true) { return function(hash){ return hash; }; } if(typeof unescape_ == "string" && (unescape_ = partialDecoder(unescape_.split(""))) || typeof unescape_ == "function") { return function(hash) { return unescape_(encodeURIComponent(hash)); }; } return encodeURIComponent; } function partialDecoder(chars) { var re = new RegExp($.map(chars, encodeURIComponent).join("|"), "ig"); return function(enc) { return enc.replace(re, decodeURIComponent); }; } } var implementations = {}; implementations.base = { callback: undefined, type: undefined, check: function() {}, load: function(hash) {}, init: function(callback, options) { initObjects(options); self.callback = callback; self._options = options; self._init(); }, _init: function() {}, _options: {} }; implementations.timer = { _appState: undefined, _init: function() { var current_hash = locationWrapper.get(); self._appState = current_hash; self.callback(current_hash); setInterval(self.check, 100); }, check: function() { var current_hash = locationWrapper.get(); if(current_hash != self._appState) { self._appState = current_hash; self.callback(current_hash); } }, load: function(hash) { if(hash != self._appState) { locationWrapper.put(hash); self._appState = hash; self.callback(hash); } } }; implementations.iframeTimer = { _appState: undefined, _init: function() { var current_hash = locationWrapper.get(); self._appState = current_hash; iframeWrapper.init().put(current_hash); self.callback(current_hash); setInterval(self.check, 100); }, check: function() { var iframe_hash = iframeWrapper.get(), location_hash = locationWrapper.get(); if (location_hash != iframe_hash) { if (location_hash == self._appState) { // user used Back or Forward button self._appState = iframe_hash; locationWrapper.put(iframe_hash); self.callback(iframe_hash); } else { // user loaded new bookmark self._appState = location_hash; iframeWrapper.put(location_hash); self.callback(location_hash); } } }, load: function(hash) { if(hash != self._appState) { locationWrapper.put(hash); iframeWrapper.put(hash); self._appState = hash; self.callback(hash); } } }; implementations.hashchangeEvent = { _init: function() { self.callback(locationWrapper.get()); $(window).bind('hashchange', self.check); }, check: function() { self.callback(locationWrapper.get()); }, load: function(hash) { locationWrapper.put(hash); } }; var self = $.extend({}, implementations.base); if($.browser.msie && ($.browser.version < 8 || document.documentMode < 8)) { self.type = 'iframeTimer'; } else if("onhashchange" in window) { self.type = 'hashchangeEvent'; } else { self.type = 'timer'; } $.extend(self, implementations[self.type]); $.history = self; })(jQuery);