我有两个<div>
元素,以及以下JavaScript代码:
var myObject = {
$input: $('<input />'),
insert: function () {
$('div').append(this.$input);
$('div').append(' ');
}
};
myObject.insert();
正如我所期望的那样,这会在两个<div>
元素中的每一个元素中产生一个<input>
元素。
现在,当我创建一个新的myObject
实例并再次调用insert()
时,我将期待 4 个<input>
元素,每个元素<div>
两个。奇怪的是,我只得到 3 个<input>
元素!
请参阅此处的示例代码:http://jsfiddle.net/FNEax/
您正在显式创建 1 个输入:
$input: $('<input />',{value:i}),
。但是当您尝试将其附加到多个div 时隐式克隆它
// 2 divs
$('div').append(this.$input);
然后Object.create
不会创建新的$input
,所以在第二次传递时,它将输入从第二个div
(实际上是原始的(追加(移动(到第一个div
,然后执行隐式克隆以填充第二个。
下面是一个 jsFiddle 示例,该示例在调用 insert()
时递增一个 i
变量,并将其添加为输入的值。请注意,它始终设置为 0
。
我还修改了它以将字符串传递给insert
以便您可以查看每个输入来自哪个调用。
来自第二个调用的两个输入仍然将字符串传递给第一个调用。
编辑:
我在解释中翻了过来,但概念是一样的。
当调用第二个insert()
时,首先创建原始克隆并将其添加到第一个div
,然后将原始克隆附加到第二个div
(它已经存在(。
jQuery首先制作克隆,然后附加原始的最后一个。
这是另一个 jsFiddle 示例,它向原始属性添加一个自定义属性,然后在每个insert()
之后使用该自定义属性的元素旁边添加一些文本。在第二个div
中,文本始终添加到该原件旁边。
这就是正在发生的事情。来自 jQuery 文档:
如果以这种方式选择的元素插入到其他位置,它将被移动到目标中(而不是克隆(
但是,如果有多个目标元素,则会在第一个目标之后为每个目标创建插入元素的克隆副本。
所以第一次,因为你的输入不在 DOM 中的任何位置,它被克隆并插入到两个div 中。但是,第二次调用它时,它会从第二个div 中删除,然后再克隆并重新添加到两个div 中。
在代码结束时,第一个div 包含两个输入,但第二个div 仅包含最新的输入,因为每个输入都已从上一个div 中删除。
http://jsfiddle.net/hePwM/
一旦将元素插入 DOM 中,另一个.append()
调用它作为附加的内容会导致它在 DOM 中移动(文档(。 您的代码创建一个包含单个输入的 jQuery 集合,该输入尚未追加到 DOM 中。 因此,对 insert()
的第一次调用会将其附加到每个(使用 jQ 内部的克隆或复制机制(。
但是,在第二次调用中,this.$input
引用了 DOM 中已有的内容(由于第一次调用(。在内部,jQuery正在each
DIV的集合并附加位于this.$input
内部的输入。所以它添加它,移动它。
主要问题是您一遍又一遍地重新附加相同的输入。请记住,JavaScript 通常引用现有对象而不是创建新对象。 相同的输入元素不断被重新引用。
如果你想要一个方法向每个 DIV 添加一个输入,你应该简单地将输入标记传递到 append 中:
$( 'div' ).append( '<input />' );
奇怪的行为是由于您在不应该使用的地方使用了 JQuery 集合。 它最初是如何工作的超出了我的技能范围。
var myObject = {
input: '<input />',
insert: function () {
$('div').append(this.input);
//$('div').append(' ');
}
};
试试 each((:
var myObject = {
insert: function () {
$('div').each(function(index) {
$(this).append($('<input />'));
$(this).append(' ');
});
}
};
myObject.insert();
myObject.insert();