jQuery.on('change') 不适用于动态添加的元素

9

我有一个页面,其结构如下:

<div class="editCampaignBanner">
    <div>
    <hr>
    <label for="file">Upload a new image</label>
    <input id="file" type="file" name="file" class="valid">
    <label for="NewImageURLs">Link URL (Optional)</label>
    <input id="NewImageURLs" type="text" value="" name="NewImageURLs">
    <hr>
    </div>
</div>

我写了一些jquery代码:

$('div.editCampaignBanner input:file').on('change', function () {
        var value = $(this).val();
        var div = $(this).parent();
        var html = '<div>'+ div.html() + '</div>';
        if (value.length > 0) {
            div.after(html);
        }
        else if ($(this) > 1) {
            div.remove();
        }
    });

因此,当我在文件中输入一个元素时,它会在前一个元素下方生成一个div:

    <div class="editCampaignBanner">
        <div>
        <hr>
        <label for="file">Upload a new image</label>
        <input id="file" type="file" name="file" class="valid">
        <label for="NewImageURLs">Link URL (Optional)</label>
        <input id="NewImageURLs" type="text" value="" name="NewImageURLs">
        <hr>
        </div>
        <div>
        <hr>
        <label for="file">Upload a new image</label>
        <input id="file" type="file" name="file" class="valid">
        <label for="NewImageURLs">Link URL (Optional)</label>
        <input id="NewImageURLs" type="text" value="" name="NewImageURLs">
        <hr>
        </div>
    </div>

但是现在,尽管使用.on()注册了事件,div中的第二个文件输入不会触发该事件。我错过了什么吗?

4个回答

13
替换
$('div.editCampaignBanner input:file').on('change', function () {

通过

$('div.editCampaignBanner').on('change', 'input:file', function () {

好的,所以你使用选择器将 on 绑定到文档上!太棒了,谢谢! - Liam
1
由于您似乎没有删除 div.editCampaignBanner,因此您可以将其用作您的 on 的基础,而不是使用 document。 - Denys Séguret

4
$(document).delegate("div.editCampaignBanner input:file", "change", function() {
  //code goes here
});


$(document).on('change', 'div.editCampaignBanner input:file', function () {
 //code goes here
});

基于特定的一组根元素,为与选择器匹配的所有元素附加一个或多个事件处理程序,无论是现在还是将来。自 jQuery 1.7 起,.delegate() 已被 .on() 方法取代。然而,在早期版本中,它仍然是使用事件委托的最有效手段。有关事件绑定和委托的更多信息,请参见 .on() 方法。

jQuery .bind() vs .live() vs .delegate() vs .on() 的区别


我说两种都可能。我不知道他在用哪个jquery版本。 - Techie
他使用on,所以显然他至少有1.7。 - Denys Séguret
我正在向他展示可能性,他可以逐步学习。希望展示情景的可能性不是犯罪。 - Techie
1
当有人使用正确的函数时,提醒他不应该使用的函数列表是没有意义的。 - Denys Séguret
2
就像我所说的那样,我只是指出了可能性。如果您阅读我在结尾处发布的链接,那篇文章展示了最佳方法和选项是什么。我只是好心向他展示了可用的选项。 - Techie

1

试试这个:

$('div.editCampaignBanner').on('change','input:file', function () {
        var value = $(this).val();
        var div = $(this).parent();
        var html = '<div>'+ div.html() + '</div>';
        if (value.length > 0) {
            div.after(html);
        }
        else if ($(this) > 1) {
            div.remove();
        }
    });

0

可能使用$.live() jQuery方法,虽然已被弃用但对我来说仍然有效:

$('div.editCampaignBanner input:file').live('change', function () {
        var value = $(this).val();
        var div = $(this).parent();
        var html = '<div>'+ div.html() + '</div>';
        if (value.length > 0) {
            div.after(html);
        }
        else if ($(this) > 1) {
            div.remove();
        }
    });

更多信息:http://api.jquery.com/live/ 如果您不想使用最新的(.on()),可以像这样使用它:
function fileChanged(ele){
    var value = ele.val();
    var div = ele.parent();
    var html = '<div>'+ div.html() + '</div>';
    if (value.length > 0) {
        div.after(html);
    }
    else if (ele > 1) {
        div.remove();
    }
    $('div.editCampaignBanner').unbind().on('change','input:file', function () {
        fileChanged($(this))
    });
}
$(function(){
    $('div.editCampaignBanner').on('change','input:file', function () {
        fileChanged($(this))
    });
});

请注意,自JQuery 1.7以来,live实际上与on完全相同(http://www.jquery4u.com/jquery-functions/on-vs-live-review/#.UH-6cMW5_mc)。Live存在重大问题,因此已被其替代。 - Liam

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