【问题标题】:Simulating frames with jQuery load() and pushState()使用 jQuery load() 和 pushState() 模拟帧
【发布时间】:2011-12-16 00:32:27
【问题描述】:

tl;dr 摘要:jQuery 的load() 方法调用如下:

$('#foo').load('similar.html #foo')

DOM 结构的结果:

<div id="foo">
  <div id="foo">…</div>
</div>

使用不加倍包装器的 jQuery 将页面的一部分与相似页面中的等效部分交换出的正确方法是什么?


我想创建一个网站:

  1. 在所有页面(标题、导航侧边栏、搜索框等)周围都有一致的网站“chrome”。
  2. 在导航期间交换网站的“内容”(所有 chrome 都是持久的)。
  3. 提供标准浏览的历史记录和书签体验。

由于#3,我不想使用框架,也因为我希望持久性内容与动态内容重叠(注意持久性搜索结果以粉红色覆盖内容)。

因此,站点中的每个页面都将具有类似于以下缩写外壳的结构:

<html><head><title>NAME</title>…</head><body>
  <div id="chrome">…</div>
  <div id="content">…</div>
</body></html>

使用 jQuery,我可以拦截导航和搜索链接,并使用 AJAX 加载页面并仅替换内容。我可以使用history.pushState() 以可导航和可收藏的方式更新地址栏:

$('#nav a').click(function(e){
  var url = this.href;
  $('#content').load(url+" #content",function(html){
    var title = /<title>(.+?)<\/title>/i.exec(html)[1];
    history.pushState({},title,url);
    $('title').html(title);
  });
  e.preventDefault();
});

需要额外的代码来正确处理历史的前后移动;这些与问题无关。

然而,上面的代码导致 DOM 有:

<div id="content">
  <div id="content">contents from other page</div>
</div>

除了将我的所有标记更改为...之外,还有其他更好的方法防止id非法加倍吗?

<div id="content-wrap"><div id="content">…</div></div>

还有 JS 到……

$('#content-wrap').load(url+" #content",…);

【问题讨论】:

    标签: javascript html jquery


    【解决方案1】:

    您可以使用$.get() 请求并过滤服务器响应以仅包含响应的innerHTML,而不是使用自动将服务器响应加载到选定元素中的.load()(使用.html()):

    $.get('similar.html', function (serverResponse) {
        var filter = $(serverResponse).filter('#foo').html();
        $('#foo').html(filter);
    });
    

    这是一个演示:http://jsfiddle.net/QRBaw/

    您也可以使用.children().parent() 来选择#foo 元素,而不是使用.filter()(如果您想动态地执行此操作)。

    未经测试

    您是否尝试更改 .load() 函数调用中的选择器以选择 #foo 元素的子元素?

    $('#foo').load('similar.html #foo>*');
    

    【讨论】:

    • 在放弃接受标记之前,我打算等待更多建议,但您的“未经测试”建议在我的本地测试中很有吸引力。不错!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多