【问题标题】:How to clone elements and their associated event callbacks?如何克隆元素及其关联的事件回调?
【发布时间】:2015-10-26 17:54:01
【问题描述】:

我正在克隆一个元素并将其添加到 DOM。我预计新创建的克隆元素中的this 会引用自身,但它似乎引用了原始克隆元素。

为了说明,我创建了以下脚本。通过单击“cloneIt”,添加了一个新元素,单击新元素后,this 引用原始克隆。我希望data('type') 显示“已添加”。

如何克隆元素并让回调与新克隆的对象相关?

https://stackoverflow.com/

$('.fileupload').fileupload({
    start: function (e, data) {
        console.log('start', this, $(this).parent().data('type'));
    }
})
    .on('fileuploadsubmit', function (e, data) {
    console.log('fileuploadsubmit', this, $(this).parent().data('type'));
});

$('#cloneIt').click(function () {
    $('#clone').clone(true).removeAttr('id').data('type', 'added').appendTo('#container');
});

#clone {
    display:none;
}

<button id="cloneIt">cloneIt</button>
<ul id="container">
    <li id="clone" data-type="clone">
        <input class="fileupload" name="file" type="file" />
    </li>
    <li data-type="existing">
        <input class="fileupload" name="file" type="file" />
    </li>
</ul>

【问题讨论】:

  • 不确定你究竟在追求什么,但如果你定义了$('.fileupload') 并且然后创建了一个克隆,它将不会被包括在内。更改数据属性似乎仅在使用 .attr('data-type', 'added') 时有效。
  • @Shikkediel .attr() 提供了相同的结果。见jsfiddle.net/fq4rqc1u/5。我将$('.fileupload') 应用于#clone 以及具有data-typedata-typeexisting 的另一个input,这两个似乎都有效。但是,当我克隆时,它会保留现有的数据值。也许某种回调函数而不是直接访问this
  • console.log($(this).parent().index()); 记录了什么?
  • @Roamer-1888 编辑:0.
  • 好的,这符合你的意思 - 开始回调中的this 可靠地指向原始元素,而不是克隆。

标签: javascript jquery dom clone


【解决方案1】:

当调用.fileupload() 时,启动回调的this 概念似乎被锁定,并且this 被传递到克隆。

就我个人而言,我会将模板 LI 与实时 LI 分开,并且永远不会在其上调用 .fileupload()

HTML

<button id="cloneIt">cloneIt</button>
<ul id="template">
    <li data-type="original">
        <input class="fileupload" name="file" type="file" />
    </li>
</ul>
<ul id="container">
    <li data-type="existing">
        <input class="fileupload" name="file" type="file" />
    </li>
</ul>

CSS

#template {
    display:none;
}

最初,仅在 #container 中的 INPUT 上调用 .fileupload(),然后在模板创建后的任何克隆上调用。

Javascript

$('#container .fileupload').fileupload({
    start: function (e, data) {
        console.log('start', this, $(this).parent().data('type'));
    }
}).on('fileuploadsubmit', function (e, data) {
    console.log('fileuploadsubmit', this, $(this).parent().data('type'));
});

$('#cloneIt').click(function () {
    $('#template li').clone().data('type', 'clone').appendTo('#container').find('.fileupload').fileupload(...);
});

我会推荐这种方法与 any 插件。克隆一个小部件元素是危险的。不保证克隆行为是可靠的。使用一些插件,您可能会侥幸成功;与其他人,你不会。

【讨论】:

    【解决方案2】:

    http://jsfiddle.net/1as47aeb/5/

    在创建 DOM 对象之后,您似乎需要再次从库中调用 fileupload 方法。

    如果您检查代码中的 DOM,您将看到该属性已添加,并且您可以在克隆后在原始代码中查询它。

    编辑

    更正了在克隆输入中上传时调用两个输入事件的行为。

    【讨论】:

    • 谢谢 Niloct,是的,我相信这样做会奏效。然而,似乎应该可以从最初克隆的元素访问新创建的元素的 DOM。
    • 你可以。但似乎也需要文件上传的初始化。该属性在那里你可以检查 DOM,注释我在代码底部介绍的文件上传,你会看到。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-29
    • 2018-05-16
    • 1970-01-01
    • 2011-12-20
    • 1970-01-01
    • 2013-01-26
    • 2012-06-26
    相关资源
    最近更新 更多