Skip to content

JS解惑-jQuery.clone #26

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
sunmaobin opened this issue May 26, 2017 · 0 comments
Open

JS解惑-jQuery.clone #26

sunmaobin opened this issue May 26, 2017 · 0 comments
Assignees
Milestone

Comments

@sunmaobin
Copy link
Owner


title: JS解惑-jQuery.clone
date: 20161107104059
categories: [WEB]
tags: [js]


关于jQuery中clone的一些解惑。

用途

假如你想把一个html元素copy一份到另一个元素中,就可以使用 .clone 了。

比如:

<div class="container">
  <div class="hello">Hello</div>
  <div class="goodbye">Goodbye</div>
</div>

如果你想把 .hello 放到 .goodbye 中,那么以下写法就是不对的。

$( ".hello" ).appendTo( ".goodbye" );

这样的结果将是:

<div class="container">
  <div class="goodbye">
    Goodbye
    <div class="hello">Hello</div>
  </div>
</div>

但是,如果你使用 clone() ,那么结果将是你预期的。

$( ".hello" ).clone().appendTo( ".goodbye" );
<div class="container">
  <div class="hello">Hello</div>
  <div class="goodbye">
    Goodbye
    <div class="hello">Hello</div>
  </div>
</div>

注意: jquery中的clone,只针对的是 html 原型而言的!如果你将一个js对象clone(),就会报错了。

jquery.min.js:2 Uncaught TypeError: Cannot read property 'ownerDocument' of undefined()

API

$.clone() 可以传递2个参数:

  • withDataAndEvents,默认:false
  • deepWithDataAndEvents,默认:等于withDataAndEvents(特别注意这里

这里就不区分jQuery的版本了,假设我们都 > 1.5。如果还有低版本的,可以看看 官网 的兼容性说明。

分析

  1. $.clone():仅仅克隆当前元素的html结构以及当前元素及其子元素html上绑定的事件和数据(下文解释);
    • 数据是指通过 data-* 属性赋值的属性。
  2. $.clone(true,false):克隆当前元素html结构、当前元素及其子元素html上绑定的事件和数据,但是不包括子元素上动态绑定的事件和数据;
  3. $.clone(true):克隆当前元素html结构、当前元素及其子元素html上绑定的事件和数据,以及子元素的事件和数据。
    • 等同于 $.clone(true,true),因为通过API我们知道,第2个参数默认等于第1个参数。

示例

<p class="wrapper">
    <input class="test" type="text" oninput="inputEvt(this)"/>
</p>

<script src="http://code.jquery.com/jquery-1.6.1.js"></script>
function inputEvt(obj){
    console.log($(obj).val())
};

$('.wrapper').click(function () {
    console.log('click');
});

$('.test').data('obj','test');

//clone1
$('.wrapper').clone(false).prependTo($("body"));

//clone2
$('.wrapper').clone(true,false).prependTo($("body"));

//clone3
$('.wrapper').clone(true).prependTo($("body"));

结果说明:

  1. clone1
    • .wrapper,click *无输出(click);
    • .test,输入文字立即有输出(oninput
    • .test,data=undefined(data
  2. clone2
    • .wrapper,click有输出(click);
    • .test,输入文字立即有输出(oninput
    • .test,data=undefined(data
  3. clone3
    • .wrapper,click有输出(click);
    • .test,输入文字立即有输出(oninput
    • .test,data=test(data

总结

clone()方法其实包含了3部分内容:

  • html结果以及一开始绑定写在html上的事件和数据
  • + 动态绑定到html上的事件和数据(直接绑定,live/delegate/on等委托绑定除外)
  • + 子元素及其事件和数据

而以上3部分内容,分别对应以下用法:

  • clone()
  • clone(true,false)
  • clone(true) 或 clone(true,true)

特例

处于性能的考虑 textareaselect 这2个标签动态增加的属性有点例外。

  • textara 克隆后,值不会带过去;
  • select 选中的 option 克隆后,依然是未选择状态;

副作用

如果你把一个含有ID的元素进行克隆,那么克隆以后就会出现ID重复!

为了避免这问题,建议你这么做:

  • 克隆的元素尽量使用 class 而非 id;
  • 克隆以后修改新元素的 id

(全文完)

参考

  1. jQuery官网API
@sunmaobin sunmaobin added this to the 2016年 milestone May 26, 2017
@sunmaobin sunmaobin self-assigned this Jun 7, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant