Bobscript

jQuery中append特性分析(一)

jQuery中append特性分析(一)

jQuery中append、insert、after等函数的特性刚接触会摸不着头脑,为什么有时候A.append(B)执行之后B会消失?有时候又不会?本文就是为此疑惑准备的,如果不想看过程,可以直接跳到文末的总结处。

方法 源包装集/字串 目标包装集体 特性描述
A.append(B)
B.appendTo(A)
A.prepend(B)
B.prependTo(A)
A.before(B)
B.insertBefore(A)
A.after(B)
B.insertAfter(A)
B A 若目标包装集只匹配一个元素,则源(也包括同源包装集匹配的所有元素)将被移动到目标位置;若目标包装集包含多个元素,则源将保留在原来的位置,但同时复制一份相同的副本到目标位置。
由此,若目标只匹配一个元素时,使用前述方法后源将被删除。

举例说明:在上图中,A.append(B)表示把B添加到与A匹配的所有元素的现有内容后面,因此B是源,A是目标包装集。

以上内容是我从网上搜索到的,现在具体说明。比如,有一个table,只有一行tr。

jAppend2

然后为td绑定事件,使得每一次点击td都会变红,语句:

var tds=$('table tr');
$('table').on('click','td',function(){
  $(this).css('background-color','red');
  $('table').append(tds);
});

jAppend4

点击有什么现象?单元格变红了,但是你可能很奇怪,为什么table没有append内容呢?使劲点,使劲点,还是只变红不增加。原来,tds只是指向了$('tr')这个jQuery对象,按照上面清单的解释,相当于是抽出第一行的tr,然后又把它自己插入table,所以,等于没有变化嘛,我们加上.clone()方法。

var tds=$('table tr').clone();

然后我们发现,成功了,点击一下,table内容扩大了一倍。但是,继续点击,不会增加了????

jAppend3

原理分析:此时虽然在给tds赋值时候加上了clone,但是tds依旧只是一个对象,它只能使用一次,所以,如果想要达到我们预想的目的,应该是

$('table').append(tds.clone());

最终的符合我们预期的代码如下:

var tds=$('table tr').clone();//此时tds复制了最原始的时候table的所有tr元素。
$('table').on('click','td',function(){
  $(this).css('background-color','red');//这句用来显示当前点击的位置
  $('table').append(tds.clone());
});

如果我们把第一行的clone去掉会怎样?代码变成:

var tds=$('table tr'); //此时tds指向此时,也就是最初的时候table的所有tr元素。
$('table').on('click','td',function(){
  $(this).css('background-color','red');
  $('table').append(tds.clone());
});

发现问题了?后面每次增加的那行都完整复制表格第一行的样子!如果第一行已经有格子被“污染变红”了,新增的那一行也是这样!图如下所示

jAppend

原因很简单,因为js的赋值其实是传地址而不是传值,看起来是在操作tds,其实是对tds指向的对象进行操作,所以tds其实是指向table的第一行,当然复制也是复制它咯。所以我们应该最开始就把它clone出来,避免后期被改变。

以上所有是对于B为jQuery对象的情况,如果是字符串呢?就像

tds="<tr> <td>1</td> <td>2</td> </tr>";

这种情况下,tds能够随便用任意多次。

总结:对于上文的几种对DOM操作的方法,假如B是jQuery对象,把B应用到A上面,A也是一个jQuery对象,那么如果A的长度大于1,则B不会受影响,可以反复使用很多次;如果A长度为1,那么B应用到A之后,B会被移动(看起来就像从原来的位置删除了,但是没有被删除,只是被移动到了A的某个位置)。

如果B是一个简单的字符串,那么B就可以随便使用任意多次而不会被移动。