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。
然后为td绑定事件,使得每一次点击td都会变红,语句:
var tds=$('table tr');
$('table').on('click','td',function(){
$(this).css('background-color','red');
$('table').append(tds);
});
点击有什么现象?单元格变红了,但是你可能很奇怪,为什么table没有append内容呢?使劲点,使劲点,还是只变红不增加。原来,tds只是指向了$('tr')这个jQuery对象,按照上面清单的解释,相当于是抽出第一行的tr,然后又把它自己插入table,所以,等于没有变化嘛,我们加上.clone()方法。
var tds=$('table tr').clone();
然后我们发现,成功了,点击一下,table内容扩大了一倍。但是,继续点击,不会增加了????
原理分析:此时虽然在给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());
});
发现问题了?后面每次增加的那行都完整复制表格第一行的样子!如果第一行已经有格子被“污染变红”了,新增的那一行也是这样!图如下所示
原因很简单,因为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就可以随便使用任意多次而不会被移动。