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

542 html javascript forms file-io jquery

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

$('#control').attr({ value: '' }); 
Run Code Online (Sandbox Code Playgroud)

但它不起作用.

sli*_*eed 525

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

在Opera,Firefox,Safari,Chrome和IE6 +中测试和使用.除了.unwrap().之外,还适用于其他类型的表单元素.

http://jsfiddle.net/rPaZQ/

window.reset = function(e) {
  e.wrap('<form>').closest('form').get(0).reset();
  e.unwrap();
}
Run Code Online (Sandbox Code Playgroud)

正如Timo在下面指出的那样,如果你有按钮来触发内部字段的重置.clone(),你必须在事件上调用preventDefault以防止type="hidden"触发提交.

编辑

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

  • 问题是,这至少暂时使文件无效.(表格不能包含其他表格.)无论目前是否有效,都可以随时随意打破. (27认同)
  • 优胜者!适用于每个浏览器,避免克隆输入字段.但是如果清晰按钮在窗体内,请将`reset()`重命名为eg.`reset2()`,因为至少在Chrome中,如果是`reset()`,则清除所有字段.并在清除调用后添加event.preventDefault()以阻止提交.这样:`<button onclick ="reset2($('#file')); event.preventDefault()">重置文件</ button>`.工作示例:http://jsfiddle.net/rPaZQ/23/. (13认同)
  • 关于在表单中使用表单,您可以始终在DOM外部创建新表单元素,或者如果需要将其附加到正文,然后将输入元素移动到该表单内部.然后,您将重置该新表单,将输入元素移回原来的位置,并删除其他表单元素. (7认同)
  • @cHao,当然只有当input元素实际上是一个形式时才是这样,它不一定是这样. (6认同)
  • 我刚刚发现这在IE 11中不起作用.我们正在使用PixelFileInput - 它使用这种方法.当文本和缩略图被清除时,对象的文件列表保持不变:( (4认同)
  • 为了使这个工作,我不得不改变前两行,所以他们使用jQuery来引用被点击的元素:`$(event.target).wrap('<form>').nearest('form').get( 0).reset段(); $(event.target).unwrap(); event.stopPropagation(); event.preventDefault();` (3认同)
  • 最新的Chrome不喜欢它(`get(0)`未定义),我不得不做`.wrap('<form> </ form>')`,正如jQuery doc中所建议的那样. (2认同)

Sam*_*son 430

快速回答:更换它.

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

<input type="file" id="control"/>
<button id="clear">Clear</button>
Run Code Online (Sandbox Code Playgroud)
var control = $("#control");

$("#clear").on("click", function () {
    control.replaceWith( control = control.clone( true ) );
});
Run Code Online (Sandbox Code Playgroud)

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

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

$("form").on("focus", "#control", doStuff);
Run Code Online (Sandbox Code Playgroud)

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

  • 您还可以在$('#clone')字段上使用.clone()方法.replaceWith($(this).clone()); (50认同)
  • 它仍然无法正常工作.它需要在更换前清除.所以你想在.replaceWith()之前想要.val().所以它是control.val('').replaceWith(...); (10认同)
  • 我有一个比这更清洁的解决方案:http://stackoverflow.com/a/13351234/909944 (6认同)
  • 它根本没有做任何事 - 萤火虫没有错误.我不得不添加control.val(''); 为它清除文件输入框.你的代码工作在chrome和ie9中. (4认同)
  • 这个答案出于历史原因.现代浏览器支持`input.value = null;` (2认同)

Xot*_*750 108

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

这适用于我测试的现代浏览器:Chromium v​​25,Firefox v20,Opera v12.14

使用jquery 1.9.1

HTML

<input id="fileopen" type="file" value="" />
<button id="clear">Clear</button>
Run Code Online (Sandbox Code Playgroud)

jQuery的

$("#clear").click(function () {
    $("#fileopen").val("");
});
Run Code Online (Sandbox Code Playgroud)

jsfiddle

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

document.getElementById("clear").addEventListener("click", function () {
    document.getElementById("fileopen").value = "";
}, false);
Run Code Online (Sandbox Code Playgroud)

jsfiddle

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

就像在另一个答案中提到的那样,在jquery论坛上发帖

 if ($.browser.msie) {
      $('#file').replaceWith($('#file').clone());
 } else {
      $('#file').val('');
 }
Run Code Online (Sandbox Code Playgroud)

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

这个javascript解决方案也适用于我,它是jquery.replaceWith方法的vanilla等价物.

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

    fileopen.parentNode.replaceChild(clone, fileopen);
}, false);
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

jsfiddle

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

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

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

    fileopen.replaceWith(clone);
});
Run Code Online (Sandbox Code Playgroud)

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);
});
Run Code Online (Sandbox Code Playgroud)

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);
    });
}());
Run Code Online (Sandbox Code Playgroud)

jsfiddle

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

  • 我准备添加一些你同样的答案,但主要是`.val('')`.这不仅仅是克隆上传元素或添加嵌套表单吗?+1. (4认同)
  • 第一个JQuery解决方案(使用`.val("")`完美地工作,谢谢.比克隆输入和替换它更简单. (3认同)

Lau*_*ent 50

出于明显的安全原因,您无法设置文件输入的值,即使是空字符串也是如此.

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

function reset_field (e) {
    e.wrap('<form>').parent('form').trigger('reset');
    e.unwrap();
}?
Run Code Online (Sandbox Code Playgroud)

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

  • 在IE中无法正常工作.视觉值已重置,但el.value仍会报告以前的版本.它有助于重新设置el.value,但仅限于IE10 +.http://jsfiddle.net/9uPh5/2/ (6认同)
  • 与上述解决方案相同 (2认同)
  • 那是错的,我们不能将字段设置为给定值,但希望我们可以清除它. (2认同)

Syn*_*ror 44

这适合我.

$("#file").replaceWith($("#file").clone());
Run Code Online (Sandbox Code Playgroud)

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

希望能帮助到你.


Jon*_*way 20

在IE8中,他们将"文件上载"字段设置为只读以确保安全性.查看IE团队博客文章:

从历史上看,HTML文件上载控件()已成为大量信息泄露漏洞的来源.为了解决这些问题,对控件的行为进行了两处更改.

为了阻止依赖"窃取"击键的攻击暗中欺骗用户输入控件的本地文件路径,文件路径编辑框现在是只读的.用户必须使用"文件浏览"对话框显式选择要上载的文件.

此外,"上载文件时包括本地目录路径"URLAction已设置为"禁用"Internet区域.此更改可防止潜在敏感的本地文件系统信息泄漏到Internet.例如,Internet Explorer 8现在只提交文件名image.png,而不是提交完整路径C:\ users\ericlaw\documents\secret\image.png.


Bod*_*odi 16

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

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

  • 适用于chrome和firefox.绰绰有余. (4认同)
  • 正如这里的许多其他帖子所解释的那样,这不是跨浏览器友好的. (2认同)

San*_*eem 12

我在这里遇到了所有的选择.这是我制作的黑客行为:

<form>
 <input type="file">
 <button type="reset" id="file_reset" style="display:none">
</form>
Run Code Online (Sandbox Code Playgroud)

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

$('#file_reset').trigger('click');
Run Code Online (Sandbox Code Playgroud)

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

  • 好但是它会清除整个表格..不是特定的文件输入 (3认同)

skv*_*len 8

我最终得到了这个:

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'); 
}
Run Code Online (Sandbox Code Playgroud)

可能不是最优雅的解决方案,但据我所知,它可以正常工作.


Tim*_*nen 8

我使用了https://github.com/malsup/form/blob/master/jquery.form.js,它有一个名为的函数clearInputs(),它是crossbrowser,经过良好测试,易于使用,并处理IE问题和隐藏字段清除如果需要的话.也许只是一个很长的解决方案,只清除文件输入,但如果你正在处理crossbrowser文件上传,那么建议使用此解决方案.

用法很简单:

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


Que*_*tin 5

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

  • 我很困惑 - 我尝试了$("#inputControl").val("")它确实使该字段空白.我错过了什么吗? (16认同)
  • @Jonathan它适合你,因为你没有在IE中这样做.此安全问题仅限IE停止.清除价值通常适用于Chrome和Firefox,但不适用于IE (4认同)

Pur*_*tha 5

我能够使用以下代码:

var input = $("#control");    
input.replaceWith(input.val('').clone(true));
Run Code Online (Sandbox Code Playgroud)


che*_*aby 5

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

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

$input.replaceWith($input.val('').clone(true));
Run Code Online (Sandbox Code Playgroud)

所有的功劳归克里斯·科耶尔Chris Coyier)

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

$input.replaceWith($input.val('').clone(true));
Run Code Online (Sandbox Code Playgroud)
// 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"  ) }
});
Run Code Online (Sandbox Code Playgroud)