jQuery完全替换元素的DOM,有更快的方法吗?

5
我使用jQuery的AJAX从服务器获取新内容。数据以JSON格式加载:
$.ajax({
    url: url,
    data: {
        'ajax': '1',
    },
    dataType: 'json',
    success: somefunction
});

由于服务器端应用限制,我无法在其中设置更多的JSON变量,因此我必须将所有内容加载到内容中。这就是为什么我不得不将结果加载到jQuery中,然后搜索并替换页面上的一些元素,例如(在somefunction中使用):

var somefunction = function(data) {
    var con = $('<div></div>').html(data.content); // just $(data.content) is not working
    $('div#mainContent').html(con.find('div#ajax-content').html());
    ... // same process with three more divs
}

编辑:请注意,我需要进行相同的过程来替换三个div!

还有更多相关内容,但作为示例,我希望这已经足够了。我的问题是:出于某种逻辑方式,我期望将结果加载到DOM中($(data.content)),解析为html(con.find('dix#ajax-content').html())并返回到DOM($('div#mainContent').html())似乎会浪费一些资源并降低性能,因此我想知道是否有更快速的方法可以直接加载DOM,例如:

$('div#mainContent').dom(con.find('div#ajax-content').dom());

我试着在谷歌上搜索,但可能是因为我不知道该输入什么。此外,jQuery文档并没有给我很大的帮助。

一些事实:

  • jQuery 1.9.1
  • 可用jQuery UI 1.10.3

最后,我知道使用服务器端应用程序提供更多的JSON变量会更好,然而,我需要编写不太容易的代码,这需要更长的开发时间,而我现在没有这个时间。在客户端上执行它将是暂时的解决方案,但是,我不想降低性能。

附带问题:

在这种情况下使用find()函数是否正确,或者有更好的方法?

编辑2(无法解析字符串) 我期望这样工作,但它没有:

content = '<div id="ajax-title">Pečivo běžné, sladké, slané</div>
<div id="ajax-whereami"><a href="/category/4">Chléba a pečivo</a> » Pečivo běžné, sladké, slané</div>';
$(content);

尝试使用data.content.toString()。 - basarat
@BASarat 我假设 data.content 是一个字符串。 - HMR
@BASarat 那我就无法解析它并在请求中找到特定 div 的内容了。data.content 无论如何都是字符串。而且它对于标记为“不起作用”的行也没有帮助。 - tomis
@tomis 如果所有需要替换 $('div#mainContent') 中的元素,那么你应该缓存它:$content=$('div#mainContent'); $content.find("something").replaceWith(con.find("somethingElse"); - HMR
3个回答

3

我不确定这是否有帮助:

$('div#mainContent').replaceWith(con.find('div#ajax-content'))
 .attr("id","mainContent")

现在您无需设置元素的html,也可以从JSON中获取刚创建的元素的html。不确定这是否更快,但它确实跳过了2个html()步骤。


嘿,这可能有帮助……我能够替换请求中的ID,所以它比看起来容易:$('div#mainContent').replaceWith(con.find('div#mainContent')); 它会起作用吗?它有效吗?(我是个愚蠢的人,没有自己找到它)。 - tomis
根据文档,它应该可以工作。replaceWith接受字符串、元素或jQuery对象作为参数。http://api.jquery.com/replaceWith/ - HMR
这将为我的脚本节省一个.find()函数。如果它能够正常工作,我会尝试并考虑接受您的答案(也许稍作编辑以便未来的访问者更好地理解)。 - tomis
@tomis,回头看,我发现我错过了一些东西,我以为你必须替换#mainContent内的几个元素,但你要替换的是#mainContent本身。在这种情况下,你可以去掉.find部分,并使用.attr重新设置id。我会更新我的答案。 - HMR

1

实际上,$(data.content)应该可以正常工作,但您必须记住,只有通过.filter()而不是.find()才能访问顶层元素。如果您希望定位的元素比根元素深至少一级,则应使用.find(); 在下面的示例中,您可以根据需要将.filter()替换为.find()

var $con = $(data.content);
$('div#mainContent')
  .empty()
  .append($con.filter('div#ajax-content'))
  .append($con.filter('div#another-id'))
  .append($con.filter('div#and-another-id'));

您也可以将选择器结合在一起:

  .append($con.filter('div#ajax-content, div#another-id, div#and-another-id'));

最后,由于标识符应该在文档中只出现一次,因此您可以删除 div 部分:
  .append($con.filter('#ajax-content, #another-id, #and-another-id'));

更新

好的,看起来当data.content中有错误的换行时,jQuery无法正确评估它;这应该适用于所有情况:

var wrapper = document.createElement('div');
wrapper.innerHTML = data.content;

var $con = $(wrapper);

1
请看我的第二次编辑,因为$(data.content)真的无法工作。 - tomis
1
@tomis 是的,或者在行末添加反斜杠,但更推荐的方法是使用 + 连接多行。 - Ja͢ck
是啊...正在思考如何解决这个问题 :-) 无论如何,还是谢谢你的帮助。 - tomis
@tomis 我稍微更新了我的回答,展示了何时使用 .find().filter()。此外,如果响应直接来自服务器,您不必担心换行符会使解析出错。请告诉我这是否回答了您的问题。 - Ja͢ck
@tomis 这里的问题不是字符串结尾;如果响应来自content.data服务器,就不需要对其进行操作;只有在手动测试时才会出现这个问题。 - Ja͢ck
显示剩余7条评论

0
你可以使用.load,虽然我相信它本质上只是相同东西的包装器:
$("#mainContent").load(url + " #ajax-content", data);

通过仅发送特定的ajax内容(下载和解析较少)可以提高服务器端的性能,尽管这可能很困难。

除此之外,最好使用原生JS而不是jQuery,至少在附加方面(直接使用innerHTML)。


也许你会纠正我,但是当使用.load()时,我无法处理错误状态,对吧?不太可能,我必须替换完全放置在不同位置的3个div的内容,以及页面标题(这很简单)。三个请求是不可接受的(innerHTML解决方案、load解决方案)。但还是谢谢。 - tomis
@tomis,你仍然可以在三个单独的div上执行innerHTML,只需要使用循环即可。 - Explosion Pills
.load() 方法会清空目标元素吗?我认为它只是将内容追加到目标元素中。 - Ja͢ck
从文档中可以看出,似乎已经替换了:(...).load()将匹配元素的HTML内容设置为返回的数据。(...) - tomis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接