ChatGPT解决这个技术问题 Extra ChatGPT

使用 jQuery 清除 <input type='file' />

是否可以使用 jQuery 清除 <input type='file' /> 控件值?我尝试了以下方法:

$('#control').attr({ value: '' }); 

但它不起作用。


C
Community

简单:您将 <form> 包裹在元素周围,在表单上调用 reset,然后使用 .unwrap() 删除表单。与此线程中的 .clone() 解决方案不同,您最终会得到相同的元素(包括在其上设置的自定义属性)。

在 Opera、Firefox、Safari、Chrome 和 IE6+ 中测试和工作。也适用于除 type="hidden" 之外的其他类型的表单元素。

window.reset = function(e) { e.wrap('

').closest('form').get(0).reset(); e.unwrap(); }

JSFiddle

正如 Timo 在下面指出的,如果您有用于触发 <form> 内的字段重置的按钮,则必须在事件上调用 .preventDefault() 以防止 <button> 触发提交。

编辑

由于未修复的错误,在 IE 11 中不起作用。输入中的文本(文件名)被清除,但其 File 列表仍被填充。


优胜者!适用于所有浏览器并避免克隆输入字段。但如果清除按钮在表单内,请将 reset() 重命名为 eg。 reset2(),因为至少在 Chrome 中,如果它是 reset(),则所有字段都会被清除。并在清除调用后添加 event.preventDefault() 以防止提交。这样:<button onclick="reset2($('#file'));event.preventDefault()">Reset file</button>。工作示例:jsfiddle.net/rPaZQ/23
@Timo,我已将该函数重命名为 resetFormElement 并添加了一条注释,说明您应该在按钮 onclick 上 preventDefault() 。
问题是,这至少暂时使文档无效。 (表格不能包含其他表格。)无论它当前是否有效,它都可以随时随意中断。
@cHao,当然,这仅在输入元素实际上是一种形式时才成立,而不必如此。
最新的 Chrome 不喜欢它(get(0) 未定义),我不得不按照 jQuery 文档中的建议执行 .wrap('<form></form>')
1
14 revs, 2 users 99%

快速回答:更换它。

在下面的代码中,我使用 replaceWith jQuery 方法将控件替换为自身的克隆。如果您有任何处理程序绑定到此控件上的事件,我们也希望保留这些处理程序。为此,我们传入 true 作为 clone 方法的第一个参数。

<input type="file" id="control"/>
<button id="clear">Clear</button>
var control = $("#control");

$("#clear").on("click", function () {
    control.replaceWith( control = control.clone( true ) );
});

小提琴:http://jsfiddle.net/jonathansampson/dAQVM/

如果克隆在保留事件处理程序的同时会出现任何问题,您可以考虑使用事件委托来处理来自父元素的对此控件的单击:

$("form").on("focus", "#control", doStuff);

这可以防止在刷新控件时将任何处理程序与元素一起克隆。


这个解决方案的烦人之处在于您必须在代码中包含两次元素,因此如果有人更改了名称,例如名称,您必须更改您的代码两次(这很容易忘记)
您还可以在字段 $('#clone').replaceWith($(this).clone()); 上使用 .clone() 方法
它仍然不起作用。更换前需要清除。因此,您需要在 .replaceWith() 之前使用 .val()。所以应该是 control.val('').replaceWith(...);
X
Xotic750

Jquery 应该为您处理跨浏览器/旧浏览器的问题。

这适用于我测试过的现代浏览器:Chromium v25、Firefox v20、Opera v12.14

使用 jquery 1.9.1

HTML

<input id="fileopen" type="file" value="" />
<button id="clear">Clear</button>

jQuery

$("#clear").click(function () {
    $("#fileopen").val("");
});

jsfiddle

以下 javascript 解决方案也适用于上述浏览器。

document.getElementById("clear").addEventListener("click", function () {
    document.getElementById("fileopen").value = "";
}, false);

jsfiddle

我无法用 IE 进行测试,但理论上这应该可行。如果 IE 足够不同以至于 Javascript 版本无法工作,因为 MS 以不同的方式完成了它,我认为 jquery 方法应该为您处理它,否则值得将它与 jquery 团队一起指出IE 需要的方法。 (我看到人们说“这在 IE 上不起作用”,但没有香草 javascript 来展示它如何在 IE 上工作(据说是“安全功能”?),也许也将它作为一个错误报告给 MS(如果他们愿意这样算),以便它在任何新版本中得到修复)

就像另一个答案中提到的那样,jquery forum 上的帖子

 if ($.browser.msie) {
      $('#file').replaceWith($('#file').clone());
 } else {
      $('#file').val('');
 }

但是 jquery 现在已经取消了对浏览器测试的支持,jquery.browser.

这个 javascript 解决方案也对我有用,它是 jquery.replaceWith 方法的香草等价物。

document.getElementById("clear").addEventListener("click", function () {
    var fileopen = document.getElementById("fileopen"),
        clone = fileopen.cloneNode(true);

    fileopen.parentNode.replaceChild(clone, fileopen);
}, false);

jsfiddle

需要注意的重要一点是 cloneNode 方法不保留关联的事件处理程序。

请参阅此示例。

document.getElementById("fileopen").addEventListener("change", function () {
    alert("change");
}, false);

document.getElementById("clear").addEventListener("click", function () {
    var fileopen = document.getElementById("fileopen"),
        clone = fileopen.cloneNode(true);

    fileopen.parentNode.replaceChild(clone, fileopen);
}, false);

jsfiddle

但是 jquery.clone 提供了这个[*1]

$("#fileopen").change(function () {
    alert("change");
});

$("#clear").click(function () {
    var fileopen = $("#fileopen"),
        clone = fileopen.clone(true);

    fileopen.replaceWith(clone);
});

jsfiddle

[*1] 如果事件是由 jquery 的方法添加的,jquery 能够做到这一点,因为它在 jquery.data 中保留一个副本,否则它不起作用,所以它有点作弊/工作-around 并且意味着事物在不同的方法或库之间不兼容。

document.getElementById("fileopen").addEventListener("change", function () {
    alert("change");
}, false);

$("#clear").click(function () {
    var fileopen = $("#fileopen"),
        clone = fileopen.clone(true);

    fileopen.replaceWith(clone);
});

jsfiddle

您不能直接从元素本身获取附加的事件处理程序。

这是 vanilla javascript 的一般原则,这就是 jquery 和所有其他库的方式(大致)。

(function () {
    var listeners = [];

    function getListeners(node) {
        var length = listeners.length,
            i = 0,
            result = [],
            listener;

        while (i < length) {
            listener = listeners[i];
            if (listener.node === node) {
                result.push(listener);
            }

            i += 1;
        }

        return result;
    }

    function addEventListener(node, type, handler) {
        listeners.push({
            "node": node,
                "type": type,
                "handler": handler
        });

        node.addEventListener(type, handler, false);
    }

    function cloneNode(node, deep, withEvents) {
        var clone = node.cloneNode(deep),
            attached,
            length,
            evt,
            i = 0;

        if (withEvents) {
            attached = getListeners(node);
            if (attached) {
                length = attached.length;
                while (i < length) {
                    evt = attached[i];
                    addEventListener(clone, evt.type, evt.handler);

                    i += 1;
                }
            }
        }

        return clone;
    }

    addEventListener(document.getElementById("fileopen"), "change", function () {
        alert("change");
    });

    addEventListener(document.getElementById("clear"), "click", function () {
        var fileopen = document.getElementById("fileopen"),
            clone = cloneNode(fileopen, true, true);

        fileopen.parentNode.replaceChild(clone, fileopen);
    });
}());

jsfiddle

当然 jquery 和其他库具有维护此类列表所需的所有其他支持方法,这只是一个演示。


L
Laurent

出于明显的安全原因,您不能设置文件输入的值,即使是空字符串。

您所要做的就是重置字段所在的表单,或者如果您只想重置包含其他字段的表单的文件输入,请使用以下命令:

function reset_field (e) {
    e.wrap('<form>').parent('form').trigger('reset');
    e.unwrap();
}​

这是一个示例:http://jsfiddle.net/v2SZJ/1/


S
SyntaxError

这对我有用。

$("#file").replaceWith($("#file").clone());

http://forum.jquery.com/topic/how-to-clear-a-file-input-in-ie

希望能帮助到你。


为我工作!值得注意的是,如果您有任何由文件输入更改触发的事件侦听器,那么您需要在替换输入后重新分配它们。
C
Community

在 IE8 中,为了安全起见,他们将文件上传字段设为只读。请参阅 IE team blog post

从历史上看,HTML 文件上传控件 () 一直是大量信息泄露漏洞的来源。为了解决这些问题,对控件的行为进行了两项更改。为了阻止依靠“窃取”击键来秘密诱骗用户在控件中键入本地文件路径的攻击,文件路径编辑框现在是只读的。用户必须使用“文件浏览”对话框明确选择要上传的文件。此外,Internet 区域的“上传文件时包括本地目录路径”URLAction 已设置为“禁用”。此更改可防止潜在敏感的本地文件系统信息泄露到 Internet。例如,Internet Explorer 8 现在将只提交文件名 image.png,而不是提交完整路径 C:\users\ericlaw\documents\secret\image.png。


A
Adam

$("#control").val('') 就是您所需要的!使用 JQuery 1.11 在 Chrome 上测试

其他用户也在 Firefox 中进行了测试。


正如这里的许多其他帖子所解释的,这不是跨浏览器友好的。
据我了解,这在哪些浏览器中失败?
在 Internet Explorer 中失败,因为输入类型文件在 IE 中是只读的>
适用于 chrome 和 firefox。绰绰有余。
S
Saneem

我被这里的所有选项卡住了。这是我制作的一个有效的技巧:

<form>
 <input type="file">
 <button type="reset" id="file_reset" style="display:none">
</form>

您可以使用 jQuery 触发重置,代码类似于:

$('#file_reset').trigger('click');

(jsfiddle:http://jsfiddle.net/eCbd6/


好的,但它会清除整个表单..不是特定的文件输入
s
skvalen

我最终得到了这个:

if($.browser.msie || $.browser.webkit){
  // doesn't work with opera and FF
  $(this).after($(this).clone(true)).remove();  
}else{
  this.setAttribute('type', 'text');
  this.setAttribute('type', 'file'); 
}

可能不是最优雅的解决方案,但据我所知它是有效的。


在 chrome 34 (linux) 中不起作用。 replaceWith() 方法适用于两种浏览器(chrome、firefox)
首先,我必须注意到“$.browser 已从 jquery 1.9 中删除”,但最后两行(将类型属性更改为文本,然后将其设置回文件)有效。另外我尝试设置 $('#control').val('');或在 javascript document.getElementById(control).value = '';并且也工作过,不知道为什么我们不应该使用这种方法!?最后,我决定同时使用它们。
T
Timo Kähkönen

我使用了 https://github.com/malsup/form/blob/master/jquery.form.js,它有一个名为 clearInputs() 的函数,它是跨浏览器,经过良好测试,易于使用,并且还可以处理 IE 问题和隐藏字段清除(如果需要)。仅清除文件输入的解决方案可能有点长,但是如果您正在处理跨浏览器文件上传,那么建议使用此解决方案。

用法很简单:

// Clear all file fields:
$("input:file").clearInputs();

// Clear also hidden fields:
$("input:file").clearInputs(true);

// Clear specific fields:
$("#myfilefield1,#myfilefield2").clearInputs();
/**
 * Clears the selected form elements.
 */
$.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
    var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list
    return this.each(function() {
        var t = this.type, tag = this.tagName.toLowerCase();
        if (re.test(t) || tag == 'textarea') {
            this.value = '';
        }
        else if (t == 'checkbox' || t == 'radio') {
            this.checked = false;
        }
        else if (tag == 'select') {
            this.selectedIndex = -1;
        }
        else if (t == "file") {
            if (/MSIE/.test(navigator.userAgent)) {
                $(this).replaceWith($(this).clone(true));
            } else {
                $(this).val('');
            }
        }
        else if (includeHidden) {
            // includeHidden can be the value true, or it can be a selector string
            // indicating a special test; for example:
            //  $('#myForm').clearForm('.special:hidden')
            // the above would clean hidden inputs that have the class of 'special'
            if ( (includeHidden === true && /hidden/.test(t)) ||
                 (typeof includeHidden == 'string' && $(this).is(includeHidden)) )
                this.value = '';
        }
    });
};

我不明白为什么这个答案没有得到更多的支持?!
@AlexB:因为,正如 Timo 解释的那样,仅清除一个文件输入字段就有点过头了。
不知道这是否有效,但在 FF 45.0.2 上不再有效:(
Q
Quentin

文件输入的值是只读的(出于安全原因)。您不能以编程方式将其清空(除了调用表单的 reset() 方法,该方法的范围比该字段更广泛)。


我很困惑 - 我尝试了 $("#inputControl").val("") 并且它确实使该字段空白。我错过了什么吗?
@Jonathan,也适用于我,但如果您将其设置为其他任何内容,则会出现安全错误。在FF4中测试。
reset() 是一种 JS 原生方法,因此如果您通过 jQuery 选择表单,则需要将元素从 jQuery 范围中取出。 $("form#myForm")[0].reset();
@Jonathan 它对你有用,因为你没有在 IE 中这样做。这个安全问题只有 IE 才会停止。定期清除值在 Chrome 和 Firefox 中都有效,但在 IE 中无效
P
Purusartha

我能够让我使用以下代码:

var input = $("#control");    
input.replaceWith(input.val('').clone(true));

c
chebaby

我一直在寻找简单而干净的方法来清除 HTML 文件输入,上面的答案很棒,但没有一个能真正回答我正在寻找的东西,直到我在网上遇到了一种简单而优雅的方法:

var $input = $("#control");

$input.replaceWith($input.val('').clone(true));

所有功劳归于 Chris Coyier

// 引用 var control = $("#control"), clearBn = $("#clear"); // 设置清除功能 clearBn.on("click", function(){ control.replaceWith( control.val('').clone( true ) ); }); // 克隆时要保留的一些绑定处理程序 control.on({ change: function(){ console.log( "Changed" ) }, focus: function(){ console.log( "Focus" ) } }); < br>
清除


S
SpoonNZ

.clone() 在 Opera(可能还有其他)中工作。它保留内容。

对我来说最接近的方法是 Jonathan 的早期方法,但是在我的情况下,确保该字段保留其名称、类等会导致代码混乱。

像这样的东西可能会很好用(也感谢 Quentin):

function clearInput($source) {
    var $form = $('<form>')
    var $targ = $source.clone().appendTo($form)
    $form[0].reset()
    $source.replaceWith($targ)
}

这在所有主要浏览器中都经过测试了吗?
它似乎在最新版本的 Chrome/FF/Opera 和 IE8 中运行良好。我看不出它不能在任何东西上工作的任何原因 - 表单上的重置选项已经存在很长时间了。
1
1DMF

我已经设法使用以下方法让它工作......

function resetFileElement(ele) 
{
    ele.val(''); 
    ele.wrap('<form>').parent('form').trigger('reset');   
    ele.unwrap();
    ele.prop('files')[0] = null;
    ele.replaceWith(ele.clone());    
}

这已经在 IE10、FF、Chrome 和 Opera 中进行了测试。

有两个警告...

在 FF 中仍然无法正常工作,如果您刷新页面,文件元素会重新填充所选文件。从哪里获取这些信息超出了我的范围。我还可以尝试清除与文件输入元素相关的其他内容吗?请记住对附加到文件输入元素的任何事件使用委托,以便在进行克隆时它们仍然有效。

我不明白的是,到底谁认为不允许您从无效的不可接受的文件选择中清除输入字段是个好主意?

好的,不要让我用一个值动态设置它,这样我就不能从用户的操作系统中提取文件,但是让我在不重置整个表单的情况下清除无效的选择。

无论如何,“接受”除了过滤器之外什么都不做,而且在 IE10 中,它甚至不理解 MS Word 的 mime 类型,这是个笑话!


这几乎可以工作。要在 Firefox 中进行这项工作,您需要做的一件事是在文件数组上使用 .pop(),而不是将其设置为 null。这似乎可以正确清除文件。
R
Roger Russel

在我的 Firefox 40.0.3 上只能使用这个

 $('input[type=file]').val('');
 $('input[type=file]').replaceWith($('input[type=file]').clone(true));

$('input[type=file]').replaceWith($('input[type=file]').clone(true).val(''));
s
srsajid

它在每个浏览器中都适用于我。

        var input = $(this);
        var next = this.nextSibling;
        var parent = input.parent();
        var form = $("<form></form>");
        form.append(input);
        form[0].reset();
        if (next) {
            $(next).before(input);
        } else {
            parent.append(input);
        }

J
Juan

我尝试了用户提到的大多数技术,但它们都不能在所有浏览器中工作。即:clone() 在 FF 中不适用于文件输入。我最终手动复制了文件输入,然后用复制的替换原件。它适用于所有浏览器。

<input type="file" id="fileID" class="aClass" name="aName"/>

var $fileInput=$("#fileID");
var $fileCopy=$("<input type='file' class='"+$fileInput.attr("class")+" id='fileID' name='"+$fileInput.attr("name")+"'/>");
$fileInput.replaceWith($fileCopy);

N
Niraj

$("input[type=file]").wrap("<div id='fileWrapper'/>");
$("#fileWrapper").append("<div id='duplicateFile'   style='display:none'>"+$("#fileWrapper").html()+"</div>");
$("#fileWrapper").html($("#duplicateFile").html());

嗨,尼拉吉。欢迎。这个答案很可能是正确的,但它可以使用一些解释。
W
Wilhelm

这适用于 Chrome、FF 和 Safari

$("#control").val("")

可能不适用于 IE 或 Opera


看起来几乎与 OP 中的问题相同
不是 ecmascript 标准,输入类型文件的值是出于安全原因的保护属性。
J
JEPAAB

使其异步,并在完成按钮所需的操作后将其重置。

    <!-- Html Markup --->
    <input id="btn" type="file" value="Button" onchange="function()" />

    <script>
    //Function
    function function(e) {

        //input your coding here           

        //Reset
        var controlInput = $("#btn");
        controlInput.replaceWith(controlInput = controlInput.val('').clone(true));
    } 
    </script>

C
Claudio Guirunas
function clear() {
    var input = document.createElement("input");
    input.setAttribute('type', 'file');
    input.setAttribute('value', '');
    input.setAttribute('id', 'email_attach');

    $('#email_attach').replaceWith( input.cloneNode() );
}

O
Omid-RH

它对我不起作用:

$('#Attachment').replaceWith($(this).clone());
or 
$('#Attachment').replaceWith($('#Attachment').clone());

所以在 asp mvc 中我使用剃须刀功能来替换文件输入。首先为具有 Id 和 Name 的输入字符串创建一个变量,然后将其用于在页面中显示并在重置按钮单击时替换:

@{
    var attachmentInput = Html.TextBoxFor(c => c.Attachment, new { type = "file" });
}

@attachmentInput

<button type="button" onclick="$('#@(Html.IdFor(p => p.Attachment))').replaceWith('@(attachmentInput)');">--</button>

佚名

一种简单的方法是更改输入类型并再次将其更改回来。

像这样的东西:

var input = $('#attachments');
input.prop('type', 'text');
input.prop('type', 'file')

G
G'ofur N

您可以像这样用它的克隆替换它

var clone = $('#control').clone();

$('#control').replacewith(clone);

但是这个克隆也有它的价值,所以你最好像这样

var emtyValue = $('#control').val('');
var clone = emptyValue.clone();

$('#control').replacewith(clone);

A
Anonymous

这很容易大声笑(适用于所有浏览器[除了歌剧]):

$('input[type=file]').each(function(){
    $(this).after($(this).clone(true)).remove();
});

JS 小提琴:http://jsfiddle.net/cw84x/1/


我一点也不关心歌剧。如果你在乎,只需将其包装在表格中即可。我个人不在乎,我会使用我的方法。
这根本不是一个好的答案,但主要问题是态度非常糟糕
M
Mxyk

什么?在您的验证功能中,只需输入

document.onlyform.upload.value="";

假设上传是名称:

<input type="file" name="upload" id="csv_doc"/>

我正在使用 JSP,不确定这是否会有所不同...

对我有用,我认为这更容易。