6

我正在做一个小项目,我想在其中创建一个 Ajax 风格的网站。内容使用 jQuery 加载load()。正如你们中的一些人所知,这样做的不利方面是 URL 不会根据显示的内容而相应更改。要完成这项工作,您可以使用pushState(). 因为这不支持跨浏览器,所以我使用了插件history.js.

这工作得很好,但问题是我的后退和前进按钮没有正常工作,我不知道我做错了什么。URL 正在正确更改,内容也在更改,但标题根本没有更改。标题我的意思是显示为浏览器窗口的窗口(或选项卡)的标题。即<title>加载的页面或指向该页面的链接的标题属性(它们是相同的)。我认为这与我只调用我需要其标题的页面部分(即通过添加#contentload())这一事实有关。我仍然想要那个页面的标题。这是我到目前为止的测试用例。(自 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. 前进和后退时使标题正常工作
  2. 优化首页加载时间
  3. 前进后退时修正active-class

欢迎大家帮忙!

注意 1:我想在 history.js 和我自己的脚本上构建,因此保持对< HTML5浏览器的支持。我更喜欢这个,因为 1. 我知道这必须有效,只是出了点问题。2. 如果我能看到一个解决方案并在我已经编写的脚本中实现它,而不是找出一个全新的脚本,这将节省时间。

注意 2:赏金只会提供给能够回答我所有问题 (3) 的人!

4

2 回答 2

11

答案 1 - 在前进和后退时使标题正常工作

据我了解,您想从链接更改文档标题 html 加载到 div 中。当您通过 jQuery 在 div 中加载文件时,.load您只是在其中的 ajax 请求之后插入完整的响应文本。因此,所有不应该在 div 中的东西,如titleormeta标签。但是,当前文档 ( http://bramvanroy.be/sectionLoaderTest/index.html) 的标题是在标签内的titlewhich 中定义的,head而不是在titlediv 内的标签中定义的,这就是文档标题不会改变的原因。

那么我该如何解决呢?

好问题,因为title元素内的div元素是无效的,大多数浏览器会删除它,所以你不能只使用这个:

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 是一种解析htmlhead并且body标签从 html 中取出,但没有删除那里的子元素。

答案 2 - 优化主页的加载时间

正在从上到下加载文档。

所以首先应该加载 css、JavaScript 等,然后是主文档。因为 jQuery 在执行之前总是在等待文档,所以将所有script元素放在正文末尾之前并不是一个坏主意,这样您的 HTML 就可以在之前加载。

顺便说一句,在所有内容都被缓存并且文档加载速度非常快之后,我第一次遇到了这个问题。

答案 3 - 在前进和后退时修复活动类

我会说循环遍历元素的href属性a并将其与来自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();
        }); 
    });
});
于 2012-05-19T16:37:14.407 回答
0

您还可以尝试可用的路由插件,如davis.jsjQuery Pusher https://github.com/salvan13/jquery-pusher

于 2013-07-10T07:05:00.783 回答