如何克隆已被jQuery UI小部件绑定的元素?

5
以下代码无法正确克隆输入元素。单击/聚焦克隆的输入会在原始输入上打开日期选择器。 http://jsfiddle.net/musicisair/YUkZw/
<input>
<script>
    var input = $("input").datepicker();
    $("body").append("<br>Input 2: ").append(
        input.clone(true);
    );
</script>

如何正确克隆已绑定jQuery UI小部件的元素?如果有,请分享正确方法。

2个回答

5

通常情况下,原始元素上绑定的任何事件处理程序都不会被复制到克隆元素。可选的withDataAndEvents参数可以改变这种行为,并将所有事件处理程序的副本一同绑定到新元素上。自jQuery 1.4以来,所有通过.data()方法附加的元素数据也会复制到新元素中。

然而,在元素数据中的对象和数组并不会被复制,它们将继续在克隆元素和原始元素之间共享。要深度复制所有数据,请手动复制每一个元素:

var $elem = $('#elem').data( "arr": [ 1 ] ), // Original element with attached data
    $clone = $elem.clone( true )
    .data( "arr", $.extend( [], $elem.data("arr") ) ); // Deep copy to prevent data sharing

自jQuery 1.5版本以来,可以选择使用deepWithDataAndEvents来增强withDataAndEvents,以复制克隆元素的所有子元素的事件和数据。

来源:http://api.jquery.com/clone/

我相信您正在寻找上面的代码,它实际上是复制与元素相关联的数据,而不是在元素之间共享数据。

更新

在这里尝试了几分钟后,我得出了以下结论:

//create original datepicker
var $input = $("input").datepicker(),

//clone the datepicker, copy the data from the original, and change the ID of the new element
    $clone = $input.clone(true).data( "datepicker", $.extend( true, {}, $input.data("datepicker") ) ).attr('id', 'test-id');

//now change the references in the data for the clone to point to the clone
$clone.data('datepicker').input = $clone;
$clone.data('datepicker').id = 'test-id';


//add the clone to the DOM
$("body").append("<br><br><br>Input 2: ").append(
    $clone
);
​

以下是一个演示:http://jsfiddle.net/YUkZw/5/


@SKS 感谢您的评论。我粘贴了错误的代码,如果您扩展datepicker数据以克隆而不仅仅是复制它,那么每个元素都会有自己的一组数据(请参见:http://jsfiddle.net/YUkZw/5/)。然后对于克隆体,您必须设置其`datepicker`数据中的引用以引用克隆体。 - Jasper
@SKS 我同意,但是找出来还是很有趣的 :) - Jasper
1
@DavidMurdoch 你可以创建自己的函数来利用.clone()$.fn.customClone = function ($ele) { return $ele.clone(true); }。当然,这个例子没有什么好处,但是你可以在这个自定义函数中做额外的工作,这样你就可以只调用$clone = $input.customClone(); - Jasper
它对我不起作用。我尝试克隆一个Kendo日程安排器,但一些引用仍然指向原始日程安排器,就像OP所描述的那样。 - AGuyCalledGerald
@AGuyCalledGerald,我不熟悉那个产品。这个答案非常具体,涉及到jQuery UI日期选择器在克隆时的更改。你有一个fiddle或一些错误吗? - Jasper
显示剩余3条评论

0

这是我的技巧。

如果您必须克隆一个带有小部件的元素,请不要在 document.ready 上绑定小部件。相反,每次元素获得焦点时重新生成小部件。

$(document).ready(function(){
    $("[type=date]").focusin(function(){
        $("[type=date]").not(this).datepicker("destroy");
        if($(this).data("datepicker") == null) {
            $(this).datepicker({dateFormat: 'yy-mm-dd'});
        }
    });
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接