为何jQuery代码$("p").before($("p").clone());生成4个p元素而非2个?
为什么
$("p").before($("p").clone())会生成4个新<p>元素而非2个? 嘿,我来帮你拆解这段代码的执行逻辑,搞清楚为啥会多出两个<p>~
首先先明确前提:我假设你的页面初始状态有2个原始<p>元素(毕竟结果是新增4个,这个前提是合理的),比如初始DOM大概是这样:
<p>第一段</p> <p>第二段</p> <button>点击添加</button>
接下来咱们一步步分析$("p").before($("p").clone());的执行过程:
第一步:先执行括号内的$("p").clone()
JavaScript的函数调用规则是先计算所有参数,再执行主函数,所以这一步会先选中当前DOM里所有的原始<p>(也就是2个),然后克隆出2个全新的<p>节点。这时候这两个克隆节点还没被插入到DOM里,只是形成了一个包含2个元素的jQuery对象。
到这里你可能会想:“哦,那接下来把这2个克隆节点插到原始p前面,应该只新增2个啊?”别急,重点在第二步。
第二步:执行$("p").before(刚才的克隆集合)
这一步里的$("p")会再次选中当前DOM里的2个原始<p>元素(注意:这时候克隆节点还没插入,所以选中的还是原始的2个)。
然后jQuery的.before()方法有个关键特性:它会把传入的内容,分别插入到每个选中元素的前面。也就是说:
- 首先对第一个原始
<p>,把刚才那2个克隆节点插入到它前面; - 接着对第二个原始
<p>,再把那2个克隆节点插入到它前面。
这就导致原本的2个克隆节点被插入了两次,总共新增了2×2=4个新的<p>元素。
直观看DOM变化过程
初始DOM:
<p>第一段</p> <p>第二段</p>
插入第一个原始p前面后:
<p>第一段(克隆)</p> <p>第二段(克隆)</p> <p>第一段</p> <p>第二段</p>
插入第二个原始p前面后:
<p>第一段(克隆)</p> <p>第二段(克隆)</p> <p>第一段</p> <p>第一段(克隆)</p> <p>第二段(克隆)</p> <p>第二段</p>
你看,新增的就是4个克隆节点,正好和你看到的结果一致。
如果你想只新增2个<p>(每个原始p前插自己的克隆)
那可以用.each()遍历每个<p>,单独克隆自己再插入:
$("p").each(function() { // 只克隆当前这个p,然后插到它前面 $(this).before($(this).clone()); });
这样每个原始p只会生成一个自己的克隆,总共新增2个,符合最初的预期。
内容的提问来源于stack exchange,提问作者user602874
相关产品推荐
相关产品推荐

