2015-10-26 111 views
3

我克隆一个元素并将其添加到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> 
+0

不确定你到底在想什么,但是如果你定义了'$('。fileupload')'和*然后*创建一个克隆,它将不被包含。当使用'.attr('data-type','added')'时,更改数据属性似乎只能工作。 – Shikkediel

+0

@Shikkediel'.attr()'提供了相同的结果。请参阅http://jsfiddle.net/fq4rqc1u/5/。我将'$('。fileupload')'应用于'#clone'以及另一个'input',其''数据类型''存在',并且这些似乎都起作用。但是,当我克隆时,它与现有数据值保持一致。也许某种回调函数而不是直接访问'this'? – user1032531

+0

'console.log($(this).parent()是什么?index());'log? –

回答

2

看起来this的启动回调的概念在调用.fileupload()时被锁定,并且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; 
} 

最初,只有输入上调用.fileupload()#container,并随后在模板上的任何克隆作出后。

的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(...); 
}); 

我会建议与任何插件这种方式。克隆一个widgetized元素是危险的。克隆行为不保证可靠。有了一些插件,你可能会摆脱它;与其他人一样,你不会。

1

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

好像你需要再次调用从库中fileupload方法,创造了DOM对象之后。

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

编辑

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

+0

谢谢Niloct,是的,我相信这样做会起作用。但是,似乎应该可以从最初克隆的元素访问新创建的元素的DOM。 – user1032531

+0

你可以。但它似乎也需要fileupload的初始化。属性是在那里你可以检查DOM,评论我在代码底部引入的文件上传,你会看到。 – Niloct