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