使用jQuery清除<input type ='file'/>
是否有可能用jQuery清除<input type='file' />
控制值? 我已经尝试了以下内容:
$('#control').attr({ value: '' });
但它不工作。
简单:在元素周围包装<form>
,调用窗体上的重置,然后使用unwrap()删除表单。 与本次线程中的clone()解决scheme不同的是,最终会得到相同的元素(包括设置的自定义属性)。
testing并在Opera,Firefox,Safari,Chrome和IE6 +中工作。 也适用于其他types的表单元素,除了type="hidden"
。
function resetFormElement(e) { e.wrap('<form>').closest('form').get(0).reset(); e.unwrap(); // Prevent form submission e.stopPropagation(); e.preventDefault(); }
正如下面的Timo所指出的,如果您有触发<form>
内部字段重置的button,则必须在事件上调用preventDefault以防止<button>
触发提交。
编辑
由于未修复的错误,在IE 11中不起作用。 文本(文件名)在input上被清除,但其File
列表仍然填充。
快速回答:replace它。
在下面的代码中,我使用replaceWith
jQuery方法用自身的克隆replace控件。 如果您有任何处理程序绑定到此控件上的事件,我们也想保留这些。 为此,我们传入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);
这样可以防止在刷新控件时需要将任何处理程序与元素一起克隆。
jquery应该为您处理跨浏览器/较旧的浏览器问题。
这适用于我testing的现代浏览器: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解决scheme也在上面提到的浏览器上为我工作。
document.getElementById("clear").addEventListener("click", function () { document.getElementById("fileopen").value = ""; }, false);
在jsfiddle上
我没有办法与IEtesting,但理论上这应该工作。 如果IE不同,Javascript版本不能正常工作,因为MS做了不同的方式,我认为jQuery的方法应该为你处理,否则这是值得指出的jQuery队与IE需要的方法。 (我看到人们说“这不会在IE上工作”,但没有香草的JavaScript来显示它如何在IE浏览器上工作(据说是一个“安全function”?),也许报告它作为一个错误MS(如果他们按此计算),以便在任何新版本中得到修复)
就像在另一个答案中提到的,在jQuery论坛上的一个post
if ($.browser.msie) { $('#file').replaceWith($('#file').clone()); } else { $('#file').val(''); }
但jquery现在已经删除了对浏览器testing的支持, jquery.browser。
这个JavaScript解决scheme也为我工作,这是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中的副本,否则不起作用,所以这是一个作弊/变通办法,并且意味着事情不是兼容不同的方法或库。
document.getElementById("fileopen").addEventListener("change", function () { alert("change"); }, false); $("#clear").click(function () { var fileopen = $("#fileopen"), clone = fileopen.clone(true); fileopen.replaceWith(clone); });
在jsfiddle上
您不能直接从元素本身获取附加的事件处理程序。
这里是香草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和其他库有维护这样一个列表所需的所有其他支持方法,这只是一个示例。
出于明显的安全原因,您不能将文件input的值设置为空string。
你所要做的就是重置字段的表单,或者如果你只想重置包含其他字段的表单的文件input,使用这个:
function reset_field (e) { e.wrap('<form>').parent('form').trigger('reset'); e.unwrap(); }
这是一个例子: http : //jsfiddle.net/v2SZJ/1/
这对我有用。
$("#file").replaceWith($("#file").clone());
http://forum.jquery.com/topic/how-to-clear-a-file-input-in-ie
希望它有帮助。
在IE8中,为了安全起见,他们将“file upload”字段设置为只读。 查看IE小组的博客文章 :
历史上,HTMLfile upload控制()已成为大量信息泄露漏洞的来源。 为了解决这些问题,对控制的行为做了两处改变。
要阻止依赖于“窃取”按键暗中欺骗用户在控件中input本地文件path的攻击,“文件path”编辑框现在是只读的。 用户必须使用“文件浏览”对话框明确select要上载的文件。
此外,“上载文件时包含本地目录path”对于Internet区域,URLAction已被设置为“禁用”。 此更改可防止可能敏感的本地文件系统信息泄漏到Internet。 例如,Internet Explorer 8现在只提交文件名image.png,而不是提交完整pathC:\ users \ ericlaw \ documents \ secret \ image.png。
我被困在这里的所有选项。 这是我做的一个破解工作:
<form> <input type="file"> <button type="reset" id="file_reset" style="display:none"> </form>
你可以使用类似下面的代码来触发重置:
$('#file_reset').trigger('click');
(jsfiddle: http : //jsfiddle.net/eCbd6/ )
我已经使用了https://github.com/malsup/form/blob/master/jquery.form.js ,它有一个名为clearInputs()
的函数,它是交叉浏览器,testing良好,易于使用,并处理IE问题和隐藏的字段清除,如果需要 也许有点长的解决scheme,只清除文件input,但如果你正在处理crossbrowserfile upload,那么这个解决scheme是build议的。
用法很简单:
//清除所有文件字段: $( “input:文件”)clearInputs(); //清除隐藏字段: $( “input:文件”)clearInputs(真)。 //清除特定字段: $( “#myfilefield1,#myfilefield2”)clearInputs()。
/ ** *清除选定的表单元素。 * / $ .fn.clearFields = $ .fn.clearInputs = function(includeHidden){ var re = / ^(?: color | date | datetime | email | month | number | password | range | search | tel | text | time | url | week)$ / i; //“隐藏”不在此列表中 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; } 否则如果(t ==“文件”){ 如果(/MSIE/.test(navigator.userAgent)){ $(本).replaceWith($(本).clone(真)); } else { $(本).VAL( ''); } } else if(includeHidden){ // includeHidden可以是值true,也可以是select器string //表示一个特殊的testing; 例如: // $('#myForm')。clearForm('。special:hidden') //上面会清除隐藏的input,它们具有“特殊” if((includeHidden === true && / hidden / .test(t))|| (typeof includeHidden =='string'&& $(this).is(includeHidden))) this.value =''; } }); };
$("#control).val('')
就是你需要的!使用JQuery 1.11在Chrome上进行testing
我结束了这个:
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'); }
可能不是最优雅的解决scheme,但是据我所知可以工作。
文件input的值是只读的(出于安全原因)。 你不能以编程方式将其空白(除了通过调用表单的reset()方法,这个方法的范围比那个域更广)。
我能够得到我的工作与以下代码:
var input = $("#control"); input.replaceWith(input.val('').clone(true));
.clone()
东西在Opera(也可能是其他)中不起作用。 它保持内容。
对我来说最接近的方法是乔纳森之前,但确保该字段保留其名称,class级等在我的情况下为乱码。
像这样的东西可能会运作良好(也感谢昆汀):
function clearInput($source) { var $form = $('<form>') var $targ = $source.clone().appendTo($form) $form[0].reset() $source.replaceWith($targ) }
我设法得到这个工作使用以下…
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进行了testing。
有两个警告
-
在FF中仍然无法正常工作,如果刷新页面,文件元素将被重新填充选定的文件。 从哪里得到这个信息是超出我的。 还有什么与文件input元素相关的,我可以尝试清除?
-
请记住在任何附加到文件input元素的事件上使用委派,所以当克隆生成时它们仍然工作。
我不明白的是,谁在地球上认为不允许你从一个无效的不可接受的文件select清除input字段是一个好主意?
好吧,不要让我dynamic地设置一个值,所以我不能从用户的操作系统浸出文件,但让我清除一个无效的select,而不需要重置整个表单。
这不是像“接受”除了filter之外的任何东西,IE10,它甚至不理解MS Word的MIMEtypes,这是一个笑话!
在我的火狐40.0.3只适用于此
$('input[type=file]').val(''); $('input[type=file]').replaceWith($('input[type=file]').clone(true));
它的作品在我的每一个浏览器。
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); }
我尝试了大多数用户提到的技术,但是他们都没有在所有浏览器中工作。 即:克隆()不适用于文件inputFF。 我结束了手动复制文件input,然后用复制的原件replace原件。 它适用于所有浏览器。
<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);
$("input[type=file]").wrap("<div id='fileWrapper'/>"); $("#fileWrapper").append("<div id='duplicateFile' style='display:none'>"+$("#fileWrapper").html()+"</div>"); $("#fileWrapper").html($("#duplicateFile").html());
使其成为asynchronous,并在button的所需操作完成后重置它。
<!-- 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>
这适用于Chrome,FF和Safari
$("#control").val("")
可能无法使用IE或Opera
这很容易大声笑(适用于所有浏览器[歌剧除外]):
$('input[type=file]').each(function(){ $(this).after($(this).clone(true)).remove(); });
JS小提琴: http : //jsfiddle.net/cw84x/1/
什么? 在你的validationfunction,只要把
document.onlyform.upload.value="";
假设上传是名字:
<input type="file" name="upload" id="csv_doc"/>
我正在使用JSP,不知道这是否有所作为…
对我而言,我认为这样更容易。