3

当我尝试使用 构建一系列断开连接的 DOM 节点.after时,如果它们为空,它可以正常工作:

[14:56:45.186] $('<span></span>').after('<p></p>');
[14:56:45.193] ({0:({}), length:2, prevObject:{0:({}), length:1}, context:(void 0), selector:".after([object Arguments])", 1:({})})

但是,如果我尝试在第一个节点中添加任何文本,则会失败:

[14:56:41.521] $('<span>test</span>').after('<p></p>');
[14:56:41.525] ({0:({}), length:1})

如果我将该结果分配给一个变量并尝试检查它,它看起来好像after根本没有被调用过。

这里发生了什么,我该如何解决?


编辑:对于那些感兴趣的人,我最终编写了以下包装器,这似乎让我的生活变得更加轻松:

function tag(name) {
    return function(contents, options) {
        var o = options || {};
        var is_array = $.type(contents) === "array";
        if (!is_array) {
            o.text = contents;
        }
        result = $('<' + name + ' />', o);
        if (is_array) {
            $.each(contents, function(i, child) { result.append(child); });
        }
        return result;
    }
}
var span = tag('span');
var div = tag('div');
4

2 回答 2

8

为了澄清你的错误——当我在我的 JavaScript 控制台中运行你的代码时,我得到以下信息:

> $('<span></span>').after('<p></p>');
[<span>​&lt;/span>​,<p>​&lt;/p>]
> $('<span>test</span>').after('<p></p>');
[<span>​test​&lt;/span>​]

根据jQuery 1.9 升级指南

在 1.9 之前,如果集合中的第一个节点未连接到文档,.after()、.before() 和 .replaceWith() 将尝试在当前 jQuery 集合中添加或更改节点,并且在这些情况下返回一个新的 jQuery 集合而不是原始集合。这造成了一些不一致和彻底的错误——该方法可能会也可能不会返回新结果,具体取决于它的参数!从 1.9 开始,这些方法总是返回原始的未修改集,并且尝试在没有父节点的节点上使用 .after()、.before() 或 .replaceWith() 无效——也就是说,集或它包含的节点已更改。

所以:您观察到的行为是.after()在没有父节点的节点上使用导致的错误。从 1.9 开始,jQuery 开发团队已经通过完全删除它来解决这种不一致问题——使用.after()这种方式应该总是返回初始节点而没有<p>后面的(小提琴)。

解决方法:

将你的 DOM 节点推送到一个简单的数组上。或者将它们附加到父节点,然后获取所有子节点:(小提琴

$chain = $('<div>').append('<span></span>').append('<p>qwer</p>').children();
于 2013-01-15T20:40:13.877 回答
1

创建新节点通常是这样完成的:

$('<span />', {text: 'test'}).after($('<p />'));
于 2013-01-15T20:07:24.053 回答