我正在做一个小项目,我想在其中创建一个 Ajax 风格的网站。内容使用 jQuery 的 load()
加载.正如你们中的一些人所知,这样做的缺点是 URL 不会根据显示的内容相应地更改。要完成这项工作,您可以使用 pushState()
.因为这个不支持跨浏览器,所以我用了插件history.js
.
这工作得很好,但问题是我的后退和前进按钮没有正常工作,我不知道我做错了什么。 URL 正在正确更改,内容也是如此,但标题根本没有更改。标题是指显示为浏览器窗口(或选项卡)标题的内容。 IE。 <title>
加载页面的名称或引用该页面的链接的标题属性(它们是相同的)。我认为这与我只调用我需要标题的页面部分这一事实有关(即通过将 #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. 如果我能看到一个人的解决方案并在我已经编写的脚本中实现它,而不是想出一个全新的脚本,这将节省时间。
注意2:赏金只会给予能够回答我所有问题(3)的人!
最佳答案
答案 1 - 让标题在前进和后退时发挥作用
据我了解,您想更改链接中的文档标题 html 已加载到 div 中。当您通过 jQuery .load
在 div 中加载文件时,您只是在其中的 ajax 请求之后插入完整的响应文本。所以所有不应该在 div 中的东西,比如 title
或 meta
标签。但是,当前文档的标题 (http://bramvanroy.be/sectionLoaderTest/index.html
) 是在 head< 内的
标签而不是 div 内的 title
中定义的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 中解析出 html
、head
和 body
标记,但不会删除其中的子元素。
答案 2 - 优化主页的加载时间
文档正在从上到下加载。
所以首先应该加载 css、JavaScript 等,然后是主文档。
因为 jQuery 总是在执行之前等待文档,所以将所有 script
元素放在正文末尾之前并不是一个非常糟糕的主意,这样您的 HTML 就可以在之前加载。
顺便说一句,在所有内容都被缓存并且文档加载速度非常快之后,我第一次遇到这个问题。
答案3 - 修复前进后退时的active-class
我会说循环遍历 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();
});
});
});
关于jquery - pushState() 和 popState() : manipulating browsers' history,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10632483/