pushState()和popState():操纵浏览器的历史记录
我正在开发一个小项目,我想在其中创建一个Ajax风格的网站。 内容加载了jQuery的load()
。 正如你们中的一些人所知,这样做的缺点是URL不会相应地改变显示的内容。 要使这项工作,您可以使用pushState()
。 因为这不支持跨浏览器,所以我使用了插件history.js
。
这很好用,但问题是我的后退和前进按钮不能正常工作,我不知道我做错了什么。 URL正在正确更改,内容也是如此,但标题根本没有变化。 对于标题,我的意思是显示为浏览器窗口的窗口(或标签)的标题。 即加载页面的
或引用该页面的链接的title属性(它们是相同的)。 我认为这与我只调用我需要标题的页面部分(即通过向load()
添加#content
load()
这一事实有关。 我仍然想要那个页面的标题。 这是我到目前为止的一个测试案例。 (自2013年12月28日起不再提供。)jQuery文件:
$(document).ready(function () { var firstLink = $("ul > li:first-child > a"); var menuLink = $("ul > li > a"); var firstLoadedHtml = firstLink.attr("href") + " #content"; $("#sectionContainer").hide().load(firstLoadedHtml).fadeIn("fast"); firstLink.addClass("active"); menuLink.click(function(e) { history.pushState(null, null, this.href); e.preventDefault(); e.stopImmediatePropagation(); var CurLink = $(this); var newLoadedHtml = CurLink.attr("href") + " #content"; var oldSection = $(".contentPage"); $("#sectionContainer").hide().load(newLoadedHtml).fadeIn("fast"); menuLink.removeClass("active"); CurLink.addClass("active"); }); $(window).bind('popstate', function() { var returnLocation = history.location || document.location; $('#sectionContainer').load(returnLocation + "#content"); }); });
我还注意到,当回到基本页面(即/ sectionLoaderTest /)时,它会空白一段时间,并且只在一段时间后加载第一页的内容。 有没有办法优化这个?
另外,我使用jQuery将一个活动类添加到已被单击的链接。 我怎样才能确保这会根据历史变化? 以便在用户导航回来时突出显示正确的链接?
所以这三个问题是:
- 前进和后退时使标题正常工作
- 优化主页的加载时间
- 前进和后退时修复活动类
欢迎大家帮忙!
注1 :我想建立在history.js和我自己的脚本之上,因此保持对< HTML5
浏览器的支持。 我更喜欢这个因为1.我知道这必须起作用,有些事情会出错。 如果我能看到一个解决方案并在我已编写的脚本中实现它而不是找出一个全新的脚本,那将节省时间。
注2 :赏金只会给予能够回答我所有问题的人(3)!
答案1 – 前进和后退时使标题正常工作
据我所知,你想要更改文档标题html从链接加载div。 当您通过jQuery .load
在div中加载文件时,您只需在其中输入ajax请求后插入完整的响应文本。 因此,所有的东西都不应该像title
或meta
标记一样在div中。 然而,当前文档的标题( http://bramvanroy.be/sectionLoaderTest/index.html
)是在head
标记内的title
中定义的,而不是在div内的title
标记中定义的,这就是文档标题没有的原因。改变。
那么我该如何解决呢?
好问题,因为div
元素中的title
元素无效,大多数浏览器会删除它,所以你不能只使用它:
document.title = $("#sectionContainer title").text();
因为title
元素可能不存在。
所以我们需要的是jQuery .load
函数的直接响应。 我可以通过向函数添加回调参数来获得它:
$("#sectionContainer") .hide() .load(newLoadedHtml, function(responseText) { document.title = $(responseText).filter("title").text(); }) .fadeIn("fast");
你可能不明白的是为什么我使用.filter
而不是.find
函数。 这是因为jQuery有点解析html
, head
和body
标签,但没有删除那些子元素。
答案2 – 优化主页的加载时间
文档正在从顶部到底部加载。
首先应该加载css,JavaScript等,然后加载主文档。 因为jQuery在执行文件之前总是在等待文档,所以将所有script
元素放在正文结尾之前并不是一个非常糟糕的主意,这样就可以在之前加载HTML了。
BtW我在第一次遇到这个问题后,所有内容都被缓存,文档加载速度非常快。
答案3 – 前进和后退时修复活动类
我想说循环通过a
元素的href
属性,并将它与History.getState()
的数据进行比较。 应该很容易。
您在代码中犯了一些错误 – 您的固定代码:
您将散列#content
附加到所有URL ..它没有意义,它将再次由jQuery删除: https : //github.com/jquery/jquery/blob/master/src/ajax.js#L617 (来自线路:158,190,337,617 – rhash在线6)
$(document).ready(function () { var firstLink = $("ul > li:first-child > a"); var menuLink = $("ul > li > a"); var firstLoadedHtml = firstLink.attr("href"); $("#sectionContainer").hide().load(firstLoadedHtml).fadeIn("fast"); firstLink.addClass("active"); menuLink.click(function(e) { e.preventDefault(); e.stopImmediatePropagation(); var newLoadedHtml = $(this).attr("href"); History.pushState(null, newLoadedHtml, newLoadedHtml); $("#sectionContainer") .hide() .load(newLoadedHtml, function(responseText) { document.title = $(responseText).filter("title").text(); }) .fadeIn("fast"); }); History.Adapter.bind(window, "statechange", function() { menuLink.removeClass("active"); $("a[href='" + History.getState().title + "']").addClass("active"); $('#sectionContainer').load(document.location.href, function(responseText) { document.title = $(responseText).filter("title").text(); }); }); });
您也可以尝试使用davis.js或jQuery Pusher这样的路由插件https://github.com/salvan13/jquery-pusher