使用带有 .change() 事件的 input type="file" 字段上传文件并不总是在 IE 和 Chrome 中触发

IT技术 javascript jquery internet-explorer firefox google-chrome
2021-03-03 01:18:01

我有一段简单的代码来上传文件:

$(document).ready(function () {
    $(".attachmentsUpload input.file").change(function () {
        $('form').submit();
    });
});

<form class="attachmentsUpload" action="/UploadHandler.ashx" method="post" enctype="multipart/form-data">
    <input type="file" class="file" name="file" />
</form>

当我单击输入然后在对话框中选择一个文件时,我正在使用 ajax 提交这个文件。这不是这里的重要部分。重要的部分是,当我在对话框中第二次选择同一个文件时,在提交第一个文件后, .change() 事件不会在 IE 和 Chrome 中触发。但是当我选择不同的文件时,事件会触发并正常工作。在 Firefox 下,它一直在发射。

如何解决这个问题,按预期工作(如在 Firefox 中)?

2个回答

描述

发生这种情况是因为如果您再次选择相同的文件,输入字段(选定的文件路径)的值不会更改。

您可以将onChange()事件中的值设置为空字符串,并仅在该值不为空时提交表单。看看我的示例和这个jsFiddle Demonstration

样本

$(".attachmentsUpload input.file").change(function () {
    if ($(".attachmentsUpload input.file").val() == "") {
        return;
    }
    // your ajax submit
    $(".attachmentsUpload input.file").val("");
});

更新

出于任何原因,这在 IE9 中不起作用。您可以替换元素以重置它们。 在这种情况下,您需要 jQuerylive()来绑定事件,因为您的输入字段将动态(重新)创建。 这将适用于所有浏览器。

我在 stackoverflow 答案Clearing input type='file' using jQuery上找到了这个解决方案

$(".attachmentsUpload input.file").live("change", function () {
    if ($(".attachmentsUpload input.file").val() == "") {
        return;
    }
    // get the inputs value
    var fileInputContent = $(".attachmentsUpload input.file").val();
    // your ajax submit
    alert("submit value of the file input field=" + fileInputContent);
    // reset the field
    $(".attachmentsUpload input.file").replaceWith('<input type="file" class="file" name="file" />');
});​

更多信息

查看我更新的jsFiddle

注意: live现在从更高版本的 jQuery 中删除请使用on代替live

这对 Chrome 有帮助,但对 IE (IE9) 没有帮助
2021-04-25 01:18:01
请注意,从 jQuery 1.7 开始,不推荐使用 .live() 方法,但可以使用 .on() 或 .delegate() 代替。有关更多信息,请参阅api.jquery.com/live 上的 jQuery 文档
2021-04-30 01:18:01
@dknssck:感谢您的努力,但出于某种原因,这在 Chrome 和 Firefox 中有效,但不会在 IE 中向服务器提交文件(IE9,服务器端的 ContentLength 等于 0)。
2021-05-03 01:18:01
@JarekWaliszko 你是对的。我的答案已更新。
2021-05-04 01:18:01
@JarekWaliszko 我认为这是因为 ajax 请求是异步的。因此,您可以尝试在重置之前将该字段的值保存在变量中。然后提交您的变量。我的答案已更新
2021-05-14 01:18:01

基于 dknaack 的回答,线索是使用 jquery live 绑定更改事件并在提交后重置输入字段

$(document).ready(function () {
    $(".attachmentsUpload input.file").change(function () {
        $('form').submit();  /* sync submit */
        $(".attachmentsUpload input.file").replaceWith('<input type="file" class="file" name="file" />');
    });
});

必须在提交事件完成进行重置当提交是async 时,例如在ajax 成功事件中重置该字段

$(document).ready(function () {
    $(".attachmentsUpload input.file").change(function () {
        $('form').submit();  /* async submit */
    });
});

.ajaxForm({
    ...
    success: function (result) {
        // reset the field - needed for IE to upload the same file second time                    
        $this.find("input.file").replaceWith('<input type="file" class="file" name="file" />');
    }
});