输入类型='文件'/比;使用jQuery

是否有可能清除一个<input type='file' />控件值与jQuery?我试过以下几种方法:

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

但这并不奏效。

470867 次浏览

简单回答:换掉它。

在下面的代码中,我使用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 ) );
});

小提琴:# EYZ0

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

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

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

文件输入的值是只读的(出于安全原因)。不能通过编程方式使其变为空白(除非调用表单的reset()方法,该方法的范围比该字段更广)。

在IE8中,为了安全起见,他们将文件上传字段设置为只读。请看IE团队博客:

从历史上看,HTML文件上传控制()一直是大量信息泄露漏洞的来源。为了解决这些问题,对控件的行为进行了两个更改。

为了阻止依赖于“窃取”击键来秘密诱使用户在控件中键入本地文件路径的攻击,“文件路径”编辑框现在是只读的。用户必须使用“文件浏览”对话框显式地选择要上传的文件。

此外,“上传文件时包含本地目录路径”的URLAction已被设置为“禁用”;浏览互联网专区。这一更改可以防止可能敏感的本地文件系统信息泄露到Internet。例如,Internet Explorer 8现在只提交文件名image.png,而不是提交完整的路径C:\users\ericlaw\documents\secret\image.png。

< p >什么? 在验证函数中,只需输入

document.onlyform.upload.value="";

假设upload是名称:

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

我使用JSP,不确定这是否有区别…

对我来说是可行的,而且我觉得这样简单多了。


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

这适用于Chrome, FF和Safari

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

可能无法与IE或Opera工作

这很简单lol(适用于所有浏览器[除了opera]):

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

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

最后我得出了这个结论:

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');
}

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

.clone()的东西可以在Opera中使用(可能还有其他)。它保存内容。

对我来说,这里最接近的方法是Jonathan之前的方法,但是确保字段保留其名称、类等,在我的例子中导致了混乱的代码。

像这样的东西可能很管用(也要感谢昆汀):

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

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

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

window.reset = function(e) {
e.wrap('<form>').closest('form').get(0).reset();
e.unwrap();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<form>
<input id="file" type="file">
<br>
<input id="text" type="text" value="Original">
</form>


<button onclick="reset($('#file'))">Reset file</button>
<button onclick="reset($('#text'))">Reset text</button>

JSFiddle

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


编辑

由于一个未修复的错误,无法在ie11中工作。输入中的文本(文件名)被清除,但它的File列表仍然填充。

我使用了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 = '';
}
});
};

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

    <!-- 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>

这对我很有用。

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

http://forum.jquery.com/topic/how-to-clear-a-file-input-in-ie < a href = " http://forum.jquery.com/topic/how-to-clear-a-file-input-in-ie " > < / >

希望能有所帮助。

Jquery应该为你解决跨浏览器/旧浏览器的问题。

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

使用jquery 1.9.1

超文本标记语言

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

Jquery

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

在# EYZ0

下面的javascript解决方案也适用于我上面提到的浏览器。

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

在# EYZ0

我没有办法用IE测试,但理论上这应该是可行的。如果IE是不同的,Javascript版本不能工作,因为微软已经做了不同的方式,jquery方法应该在我看来为你处理它,否则它将值得指出jquery团队与IE需要的方法。(我看到有人说“这不能在IE上工作”,但没有香草的javascript来显示它是如何在IE上工作的(据说是一个“安全功能”?),也许把它作为一个bug报告给微软(如果他们把它算作这样的话),这样它就会在任何更新的版本中得到修复)

就像在另一个回答中提到的,jquery论坛上的一个帖子

 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);

在# EYZ0

需要注意的重要一点是,版本方法不保留相关的事件处理程序。

请看这个例子。

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);

在# EYZ0

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

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


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


fileopen.replaceWith(clone);
});

在# EYZ0

jquery能够做到这一点,如果事件是由jquery的方法添加的,因为它在jquery.data中保留了一个副本,否则它无法工作,所以这是一个作弊/变通,意味着不同方法或库之间不兼容。

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


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


fileopen.replaceWith(clone);
});

在# EYZ0

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

这是在香草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);
});
}());

在# EYZ0

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

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

你所要做的就是重置字段所在的表单,或者如果你只想重置包含其他字段的表单的文件输入,使用这个:

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

这里有一个例子:http://jsfiddle.net/v2SZJ/1/

我尝试了用户提到的大多数技术,但没有一个在所有浏览器中都有效。即:克隆()不工作在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);

我被这里的选项困住了。下面是我做的一个有效的方法:

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

你可以使用jQuery来触发重置,代码如下:

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

(jsfiddle: # EYZ0)

我能够得到我的工作与以下代码:

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

我已经设法让这个工作使用以下…

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 &测试;歌剧。

有两点需要注意……

  1. 在FF中仍然不能正常工作,如果您刷新页面,文件元素将使用所选文件重新填充。我不知道它是从哪里得到这些信息的。还有什么与文件输入元素相关,我可以尝试清除?

  2. 记住对附加到文件输入元素的任何事件使用委托,这样它们在克隆时仍然有效。

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

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

它不像'accept'做任何事情,除了一个过滤器,无论如何,在IE10,它甚至不理解微软Word mime类型,这是一个笑话!

我的火狐40.0.3只支持这个功能

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

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

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

它适用于所有浏览器。

        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);
}

我一直在寻找简单而干净的方法来清除HTML文件输入,上面的答案是伟大的,但没有一个真正回答我在寻找什么,直到我在网络上遇到了一个简单而优雅的方法来做到这一点:

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


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

这一切都要归功于克里斯Coyier

// Referneces
var control = $("#control"),
clearBn = $("#clear");


// Setup the clear functionality
clearBn.on("click", function(){
control.replaceWith( control.val('').clone( true ) );
});


// Some bound handlers to preserve when cloning
control.on({
change: function(){ console.log( "Changed" ) },
focus: function(){ console.log(  "Focus"  ) }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<input type="file" id="control">
<br><br>
<a href="#" id="clear">Clear</a>

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

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


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

但这个克隆与它的价值太,所以你最好喜欢这样

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


$('#control').replacewith(clone);
function clear() {
var input = document.createElement("input");
input.setAttribute('type', 'file');
input.setAttribute('value', '');
input.setAttribute('id', 'email_attach');


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

这对我不起作用:

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

所以在asp mvc中,我使用剃刀功能替换文件输入。 首先创建一个变量的输入字符串的Id和名称,然后使用它显示在页面和重置按钮上单击:

@{
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')