Backbone.History和Backbone.Router
history和router都是控制路由的,做一个单页应用,要控制前进后退,就可以用到他们了。
History类用于监听URL的变化,和触发Action方法,他可以添加对url的监听,
Router类用于定义和解析路由规则,并将URL映射到Action。
router和history一些个人的注解
<!DOCTYPE html><html><head> <meta charset="utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" /> <title>backbone</title> <style type="text/CSS"> *{padding:0;margin:0;} .wrap{width:960px; margin: 100px auto; padding: 20px 0;} ul{ list-style: none;} </style></head><body> <div class="wrap"> <div id="a1"></div> <div id="a2"></div> <div id="a3"></div> </div><script src="http://files.cnblogs.com/wtcsy/jquery.js"></script> <script src="http://files.cnblogs.com/wtcsy/underscore.js"></script><script src="http://files.cnblogs.com/wtcsy/events.js"></script><script>(function(){ // Backbone.History // ---------------- // Cached regex for stripping a leading hash/slash and trailing space. var routeStripper = /^[#//]|/s+$/g; // Cached regex for stripping leading and trailing slashes. var rootStripper = /^//+|//+$/g; // Cached regex for stripping urls of hash. var pathStripper = /#.*$/; // Handles cross-browser history management, based on either // [pushState](http://diveintohtml5.info/history.html) and real URLs, or // [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange) // and URL fragments. If the browser supports neither (old IE, natch), // falls back to polling. var History = Backbone.History = function() { this.handlers = []; _.bindAll(this, 'checkUrl'); // Ensure that `History` can be used outside of the browser. if (typeof window !== 'undefined') { this.location = window.location; this.history = window.history; } }; // Has the history handling already been started? History.started = false; _.extend(History.PRototype, Backbone.Events, { // The default interval to poll for hash changes, if necessary, is // twenty times a second. interval: 50, // Are we at the app root? atRoot: function() { var path = this.location.pathname.replace(/[^//]$/, '$&/'); return path === this.root && !this.location.search; }, // Gets the true hash value. Cannot use location.hash directly due to bug // in Firefox where location.hash will always be decoded. getHash: function(window) { var match = (window || this).location.href.match(/#(.*)$/); return match ? match[1] : ''; }, // Get the pathname and search params, without the root. getPath: function() { var path = decodeURI(this.location.pathname + this.location.search); var root = this.root.slice(0, -1); if (!path.indexOf(root)) path = path.slice(root.length); return path.slice(1); }, // Get the cross-browser normalized URL fragment from the path or hash. getFragment: function(fragment) { if (fragment == null) { if (this._haspushState || !this._wantsHashChange) { fragment = this.getPath(); } else { fragment = this.getHash(); } } //var routeStripper = /^[#//]|/s+$/g; return fragment.replace(routeStripper, ''); }, // Start the hash change handling, returning `true` if the current URL matches // an existing route, and `false` otherwise. start: function(options) { if (History.started) throw new Error("Backbone.history has already been started"); History.started = true; // Figure out the initial configuration. Do we need an iframe? // Is pushState desired ... is it available? this.options = _.extend({root: '/'}, this.options, options); this.root = this.options.root; this._wantsHashChange = this.options.hashChange !== false; this._hasHashChange = 'onhashchange' in window; this._wantsPushState = !!this.options.pushState; this._hasPushState = !!(this.options.pushState && this.history && this.history.pushState); this.fragment = this.getFragment(); // Add a cross-platform `addEventListener` shim for older browsers. var addEventListener = window.addEventListener || function (eventName, listener) { return attachEvent('on' + eventName, listener); }; // Normalize root to always include a leading and trailing slash. // var routeStripper = /^[#//]|/s+$/g; this.root = ('/' + this.root + '/').replace(rootStripper, '/'); // Proxy an iframe to handle location events if the browser doesn't // support the `hashchange` event, HTML5 history, or the user wants // `hashChange` but not `pushState`. if (!this._hasHashChange && this._wantsHashChange && (!this._wantsPushState || !this._hasPushState)) { var iframe = document.createElement('iframe'); iframe.src = 'javascript:0'; iframe.style.display = 'none'; iframe.tabIndex = -1; var body = document.body; // Using `appendChild` will throw on IE < 9 if the document is not ready. this.iframe = body.insertBefore(iframe, body.firstChild).contentWindow; this.navigate(this.fragment); } // Depending on whether we're using pushState or hashes, and whether // 'onhashchange' is supported, determine how we check the URL state. if (this._hasPushState) { addEventListener('popstate', this.checkUrl, false); } else if (this._wantsHashChange && this._hasHashChange && !this.iframe) { addEventListener('hashchange', this.checkUrl, false); } else if (this._wantsHashChange) { this._checkUrlInterval = setInterval(this.checkUrl, this.interval); } }, // Add a route to be tested when the fragment changes. Routes added later // may override previous routes. route: function(route, callback) { this.handlers.unshift({route: route, callback: callback}); }, // Checks the current URL to see if it has changed, and if it has, // calls `loadUrl`, normalizing across the hidden iframe. checkUrl: function(e) { var current = this.getFragment(); if (current === this.fragment && this.iframe) { current = this.getHash(this.iframe); } if (current === this.fragment) return false; if (this.iframe) this.navigate(current); this.loadUrl(); }, // Attempt to load the current URL fragment. If a route succeeds with a // match, returns `true`. If no defined routes matches the fragment, // returns `false`. loadUrl: function(fragment) { fragment = this.fragment = this.getFragment(fragment); return _.any(this.handlers, function(handler) { if (handler.route.test(fragment)) { handler.callback(fragment); return true; } }); }, // Save a fragment into the has
新闻热点
疑难解答