所有function于一身的位置/ hashchange历史pipe理库
首先,我知道有一些库为location.pushState
/ popState
( History.js , Hash.js , jQuery hashchange )提供了polyfills ,所以请不要链接到这些库。
我需要一个更强大的库来实现RIA中的以下function:
- 用户点击一个链接
- 库被通知并通过Ajax加载上下文(没有完全重载!)
- 所有的
<a>
元素都与一个点击处理程序杠杆- 防止页面重新加载2.(
preventDefault
)和 - 调用
location.pushState
代替/为早期浏览器设置location.hash
- 防止页面重新加载2.(
- 加载的内容被插入页面并replace当前的内容
- 继续1。
而且,之前加载的内容应当在用户导航回来时被恢复。
例如,在Internet Explorer <10和任何其他浏览器中通过Google+轻敲。
有什么更接近的? 我需要支持IE8,FF10,Safari 5和Chrome 18.而且,它应该有像MIT或Apache这样的许可许可证。
我相信Sammy.js( http://sammyjs.org )(麻省理工学院许可)最关注你想做什么,它的两大支柱是:
- 路线
- 活动
我可以从文档引用,但它非常简单:
-
设置客户端路线,涉及到要做的东西,例如:通过ajax更新视图
-
链接事件来呼叫路由,例如:当我点击一个链接时调用上面的路由。 (你将不得不确定e.preventDefault是在我相信的已定义事件中被调用的,因为这是一个真正的应用程序决策,所以不能被任何你将要使用imho的库抽象出来)
一些相关的文档
路由示例:(来自http://sammyjs.org/docs/tutorials/json_store_1 )
this.get('#/', function(context) { $.ajax({ url: 'data/items.json', dataType: 'json', success: function(items) { $.each(items, function(i, item) { context.log(item.title, '-', item.artist); }); } }); });
或者类似的东西
this.get('#/', function(context) { context.app.swap(''); ///the 'swap' here indicates a cleaning of the view //before partials are loaded, effectively rerendering the entire screen. NOt doing the swap enables you to do infinite-scrolling / appending style, etc. // ... });
当然,其他客户端的MVC框架也可能是一个select,这会带走更多的pipe道,但在这种情况下可能会过度。
一个相当不错的(也是相当近期的)比较:
http://codebrief.com/2012/01/the-top-10-javascript-mvc-frameworks-reviewed/ (我自己使用Spine.js)。
最后,我认为包括我之前写过的一个答案可能是有用的,这个答案会在客户端刷新等方面详细介绍整个最佳实践(如我所见)。也许您会发现它很有用:
辅助function和所有这些JavaScript框架
我目前在我的一个应用程序中使用PathJS 。 这是我做出的最好的决定。 对于您的特定用例,请参阅HTML5示例 。
使这个例子工作的代码片段(来自源代码):
<script type="text/javascript"> // This example makes use of the jQuery library. // You can use any methods as actions in PathJS. You can define them as I do below, // assign them to variables, or use anonymous functions. The choice is yours. function notFound(){ $("#output .content").html("404 Not Found"); $("#output .content").addClass("error"); } function setPageBackground(){ $("#output .content").removeClass("error"); } // Here we define our routes. You'll notice that I only define three routes, even // though there are four links. Each route has an action assigned to it (via the // `to` method, as well as an `enter` method. The `enter` method is called before // the route is performed, which allows you to do any setup you need (changes classes, // performing AJAX calls, adding animations, etc. Path.map("/users").to(function(){ $("#output .content").html("Users"); }).enter(setPageBackground); Path.map("/about").to(function(){ $("#output .content").html("About"); }).enter(setPageBackground); Path.map("/contact").to(function(){ $("#output .content").html("Contact"); }).enter(setPageBackground); // The `Path.rescue()` method takes a function as an argument, and will be called when // a route is activated that you have not yet defined an action for. On this example // page, you'll notice there is no defined route for the "Unicorns!?" link. Since no // route is defined, it calls this method instead. Path.rescue(notFound); $(document).ready(function(){ // This line is used to start the HTML5 PathJS listener. This will modify the // `window.onpopstate` method accordingly, check that HTML5 is supported, and // fall back to hashtags if you tell it to. Calling it with no arguments will // cause it to do nothing if HTML5 is not supported Path.history.listen(); // If you would like it to gracefully fallback to Hashtags in the event that HTML5 // isn't supported, just pass `true` into the method. // Path.history.listen(true); $("a").click(function(event){ event.preventDefault(); // To make use of the HTML5 History API, you need to tell your click events to // add to the history stack by calling the `Path.history.pushState` method. This // method is analogous to the regular `window.history.pushState` method, but // wraps calls to it around the PathJS dispatched. Conveniently, you'll still have // access to any state data you assign to it as if you had manually set it via // the standard methods. Path.history.pushState({}, "", $(this).attr("href")); }); }); </script>
PathJS有一些路由库最想要的function:
- 轻量级
- 支持HTML5 History API,“onhashchange”方法和优雅的降级
- 支持根路由,救援方法,参数化路由,可选路由组件(dynamic路由)和面向方面编程
- testing良好(testing可在./tests目录中find)
- 兼容所有主stream浏览器(testingFirefox 3.6,Firefox 4.0,Firefox 5.0,Chrome 9,Opera 11,IE7,IE8,IE9)
- 独立于所有第三方图书馆,但与所有这些都很好
我发现最后一点太吸引人了。 你可以在这里find它们
希望这个对你有帮助。
我想build议一个组合
crossroads.js作为路由器http://millermedeiros.github.com/crossroads.js/
和哈希处理浏览器的历史和哈希url(瓦特/大量的后备解决scheme): https : //github.com/millermedeiros/hasher/ (基于http://millermedeiros.github.com/js-signals/ )
这仍然需要几行代码(加载ajax内容等),但在处理路由时给你加载和其他可能性的负载。
下面是一个使用jQuery的例子(上面的库都不需要jQuery,我只是懒惰…)
http://fiddle.jshell.net/Fe5Kz/2/show/light
HTML
<ul id="menu"> <li> <a href="foo">foo</a> </li> <li> <a href="bar/baz">bar/baz</a> </li> </ul> <div id="content"></div>
JS
//register routes crossroads.addRoute('foo', function() { $('#content').html('this could be ajax loaded content or whatever'); }); crossroads.addRoute('bar/{baz}', function(baz) { //maybe do something with the parameter ... //$('#content').load('ajax_url?baz='+baz, function(){ // $('#content').html('bar route called with parameter ' + baz); //}); $('#content').html('bar route called with parameter ' + baz); }); //setup hash handling function parseHash(newHash, oldHash) { crossroads.parse(newHash); } hasher.initialized.add(parseHash); hasher.changed.add(parseHash); hasher.init(); //add click listener to menu items $('#menu li a').on('click', function(e) { e.preventDefault(); $('#menu a').removeClass('active'); $(this).addClass('active'); hasher.setHash($(this).attr('href')); });
你看过微软的BigShelf示例SPA(单页应用程序)吗? 这听起来像涵盖了如何实现你所要求的大部分。
它利用History.js,一个自定义的包装器对象来轻松地控制NavHistory和Knockout.js的导航来进行点击处理。
下面是一个极其简化的工作stream程:首先,您需要初始化一个包含history.js的NavHistory
对象,并注册一个在存在推送状态或哈希更改时执行的callback:
var nav = new NavHistory({ params: { page: 1, filter: "all", ... etc ... }, onNavigate: function (navEntry) { // Respond to the incoming sort/page/filter parameters // by updating booksDataSource and re-querying the server } });
接下来,您将使用可以绑定到链接button的命令来定义一个或多个Knockout.js视图模型:
var ViewModel = function (nav) { this.search = function () { nav.navigate({ page: 2, filter: '', ... }); // JSON object matching the NavHistory params }; }
最后,在您的标记中,您将使用Knockout.js将您的命令绑定到各种元素:
<a data-bind="click: search">...</a>
链接资源在解释所有这些工作如何更详细。 不幸的是,这不是一个像你正在寻找的框架,但你会惊讶得到这个工作是多么容易。
还有一件事,按照BigShelf的例子,我构build的网站完全是跨浏览器兼容的,IE6 +,Firefox,Safari(移动和桌面)和Chrome(移动和桌面)。
AjaxTCR Library
似乎涵盖了所有的基础,并包含我以前从未见过的健壮的方法。 它是在BSD许可证( 开放源代码计划 )下发布的。
例如,这里有五个AjaxTCR.history();
方法:
init(onStateChangeCallback,initState);
addToHistory(id,data,title,url,options);
得到所有();
为getPosition();
enableBackGuard(message,immediate);
上面的addToHistory();
有足够的参数允许在网站中进行深度散列链接。
.com.cookie() ,.storage()和.template()提供了更多的方法来处理任何会话数据需求。
有据可查的AjaxTCR API网页有大量的信息与可下载的文档启动!
状态更新:
该网站还有一个示例网页部分,包括可下载的.zip文件 ,可以使用前端 ( 客户端 )和后端 ( 服务器 )项目文件。
值得注意的是以下即时可用的例子:
单向Cookie
HttpOnly Cookie
历史偷窃
历史浏览器
还有其他一些例子说明了使用它们的许多API方法的过程,使得任何小的学习曲线都可以更快地完成。
几个build议
- ExtJs ,请参阅他们的历史示例 ,这里是文档 。
- YUI浏览器历史loggingpipe理器
- jQuery BBQ似乎通过jQuery.hashcode提供了更高级的function集。
- 真正简单的历史也可能是有帮助的,尽pipe它已经很老了,可能已经过时了。
注意: ExtJs历史logging已被扩展,以优化重复(冗余)调用add()
。
PJAX是你正在描述的过程。
更高级的pjax技术甚至会在用户hover在链接上时开始预加载内容。
这是一个很好的pjax库。 https://github.com/MoOx/pjax
您在随后的请求中标记需要更新的容器:
new Pjax({ selectors: ["title", ".my-Header", ".my-Content", ".my-Sidebar"] })
所以在上面,只有title
, .my-header
, .my-content
和.my-sidebar
会被ajax调用的内容replace。
有些事情要注意
请注意您的JS如何加载并检测页面何时准备就绪。 JavaScript不会重新加载新页面。 同样要注意,何时调用任何分析呼叫,出于同样的原因。