动态创建文件输入时,jQuery 文件上传不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19468104/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 00:02:41  来源:igfitidea点击:

jQuery File Upload not working when file input dynamically created

javascriptjqueryhtmlfile-uploadblueimp

提问by Andy Holmes

i am using this jquery uploader (http://blueimp.github.io/jQuery-File-Upload/basic.html) and it works fine when the file input is put in the raw code of the site, however i am dynamically appending the fields with jquery and it doesnt work. here is the jquery to trigger the upload:

我正在使用这个 jquery 上传器(http://blueimp.github.io/jQuery-File-Upload/basic.html),当文件输入被放入网站的原始代码时它工作正常,但是我动态附加带有 jquery 的字段,它不起作用。这是触发上传的jquery:

$('.fileupload').fileupload({
    dataType: 'json',
    done: function (e, data) {
        $.each(data.result.files, function (index, file) {
            alert(file.name);
            //$('<p/>').text(file.name).appendTo(document.body);
        });
    }
});

and this is what SHOULD trigger the upload:

这就是应该触发上传的内容:

<input class="fileupload" type="file" name="files[]" data-url="uploads/">

Here is the code that is appended by jquery:

这是jquery附加的代码:

$(document).on('click','.addItem', function(){
            $('<!--ROW START-->\
                <form class="widget-content item" data-url="uploads/">\
                    <div class="row">\
                        <div class="col-md-3"><input type="text" class="form-control" name="itemName[]"></div>\
                        <div class="col-md-3"><textarea class="auto form-control" name="itemDescription[]" cols="20" rows="1" style="word-wrap: break-word; resize: vertical;"></textarea></div>\
                        <div class="col-md-3"><textarea class="auto form-control" name="itemCondition[]" cols="20" rows="1" style="word-wrap: break-word; resize: vertical;"></textarea></div>\
                        <input type="hidden" class="itemId" name="itemId[]" value="">\
                        <input type="hidden" name="itemInventoryId[]" value="<?=$_GET["inventory_id"]?>">\
                        <input type="hidden" name="itemParent[]" value="'+$(this).closest('.formHolder').data('parent-room')+'">\
                        <div class="col-md-2">\
                            <div class="fileinput-holder input-group">\
                                <input class="fileupload" type="file" name="files[]">\
                            </div>\
                        </div>\
                        <div class="col-md-1 align-center"><i class="save icon-ok large"> </i>&nbsp;&nbsp;&nbsp;<i class="delete icon-trash large"> </i></div>\
                    </div>\
                </form>\
            <!--/ROW END-->').fadeIn(500).appendTo($(this).parents().siblings('.items'));
            $(this).parent().parent().siblings('.widget-header, .header-margin, .hide').removeClass('hide').fadeIn();
        });

like i say, when i add it into the actual code, not dynamically its fine. Can someone help please?

就像我说的,当我将它添加到实际代码中时,不是动态的就好了。有人可以帮忙吗?

回答by Micha? Rybak

This is because you bind fileuploadevent before element is added.

这是因为您fileupload在添加元素之前绑定了事件。

Try moving your code into callback function which will be executed after you create input element. Since appendTo()doesn't support callback, you can use each(callback):

尝试将您的代码移动到回调函数中,该函数将在您创建输入元素后执行。由于appendTo()不支持 callback,您可以使用each(callback)

$('code_that_you_append').appendTo('some_element').each(function () {
    // here goes $('.fileupload').fileupload({ ... }) function
});

If you need to bind event to .fileuploadin multiple places in code, you can create a function to avoid code repetition, like this:

如果你需要.fileupload在代码中的多个地方绑定事件,你可以创建一个函数来避免代码重复,如下所示:

function bindFileUpload() {
    $('.fileupload').fileupload({
        dataType: 'json',
        done: function (e, data) {
            $.each(data.result.files, function (index, file) {
                alert(file.name);
            });
        }
    });
};

and then call it in the callback, like before:

然后在回调中调用它,就像以前一样:

$('code_that_you_append').appendTo('some_element').each(function () {
    bindFileUpload();
});

I've created a little demo. It binds clickinstead of fileuploadto simplify things (fileupload is external plugin...), but the general rule stays the same.

我创建了一个小演示。它绑定click而不是fileupload简化事情(fileupload 是外部插件......),但一般规则保持不变。

回答by Ross

You need to use the jQuery live() function.

您需要使用 jQuery live() 函数。

This tip I found worked for me.

我发现这个技巧对我有用。

jQuery fileupload for dynamically added input field

用于动态添加输入字段的 jQuery 文件上传

回答by Sajan Gurung

Just bind the upload function with a static identifier at first. Here, 'document' is the static identifier. You can use anything like this that has not been added dynamically. Usually, document is used more often.

只需首先将上传功能与静态标识符绑定。这里,'document' 是静态标识符。您可以使用尚未动态添加的任何此类内容。通常,文档被更频繁地使用。

$(document).on('click', '.fileupload', function () {
    $('.fileupload').fileupload({
        dataType: 'json',
        done: function (e, data) {
            $.each(data.result.files, function (index, file) {
                alert(file.name);
                //$('<p/>').text(file.name).appendTo(document.body);
            });
        }
    });
});

回答by Engr. Hasanuzzaman Sumon

N.B: Please see accepted answer first.

注意:请先查看已接受的答案。

I think accepted answer has little mistake. I just trying to recover that. On @Micha? Rybak little demoyou will see that every time we click add itemanother click event also will be added to previous added new link( add more then new linkand see first new linkshow alert number of time new item). Because every time it add new linkwe again add click event to all new linkelements.

我认为接受的答案几乎没有错误。我只是想恢复它。在@Micha?Rybak小演示你会看到,每次我们点击add item另一个点击事件也会被添加到之前添加的new link(添加更多然后 new link看到第一次new link显示警报次数new item)。因为每次添加时,new link我们都会再次向所有new link元素添加点击事件。

 $('<p><a href="#" class="link">new link</a></p>').appendTo('body').each(function () {
      // bindClickToLink call every 'new link' and add click event on it
        bindClickToLink();
    });  

To solve that issues, instead add click event to all item we just add to newly created item. Here is my solution my demo.

要解决该问题,请向我们刚刚添加到新创建的项目的所有项目添加点击事件。这是我的解决方案我的演示