首页 文章

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

提问于
浏览
518

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

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

但它不起作用 .

25 回答

  • 98
    function clear() {
        var input = document.createElement("input");
        input.setAttribute('type', 'file');
        input.setAttribute('value', '');
        input.setAttribute('id', 'email_attach');
    
        $('#email_attach').replaceWith( input.cloneNode() );
    }
    
  • -4

    这适用于Chrome,FF和Safari

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

    可能无法与IE或Opera一起使用

  • -1

    你可以用它的克隆代替它

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

    但是这个克隆的 Value 太高,所以你最好这样

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

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

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

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

  • 426

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

    在Opera,Firefox,Safari,Chrome和IE6中测试和使用 . 除 type="hidden" 外,还适用于其他类型的表单元素 .

    http://jsfiddle.net/rPaZQ/

    function resetFormElement(e) {
      e.wrap('<form>').closest('form').get(0).reset();
      e.unwrap();
    
      // Prevent form submission
      e.stopPropagation();
      e.preventDefault();
    }
    

    正如Timo在下面所说,如果您有按钮来触发 <form> 内部字段的重置,则必须在事件上调用preventDefault以防止 <button> 触发提交 .

    编辑

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

  • -1

    快速回答:更换它 .

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

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

  • 48

    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的一个bug报告(如果他们愿意的话)算它这样),以便在任何较新的版本中得到修复)

    就像在另一个答案中提到的那样,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中保留副本,否则它不起作用,所以它有点作弊/解决方法并且意味着事情之间不兼容不同的方法或库 .

    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和其他库都有维护这样一个列表所需的所有其他支持方法,这只是一个演示 .

  • 4

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

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

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

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

  • -4

    这对我有用 .

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

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

    希望能帮助到你 .

  • 0

    在IE8中,他们将“文件上载”字段设置为只读以确保安全性 . 见IE team blog post

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

  • 2

    我在这里遇到了所有选择 . 这是我制作的一个有效的黑客:

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

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

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

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

  • 43

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

    其他用户也在Firefox中测试过 .

  • 20

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

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

    我使用了https://github.com/malsup/form/blob/master/jquery.form.js,它有一个名为 clearInputs() 的函数,它是交叉浏览器,经过良好测试,易于使用,并且还可以处理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 = '';
            }
        });
    };
    
  • 7

    我最终得到了这个:

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

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

  • 8

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

  • 1

    我能够使用以下代码:

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

    .clone() 确实在Opera(以及其他人)中工作 not . 它保留了内容 .

    对我来说最接近的方法是Jonathan先前的方法,但确保该字段保留了它的名称,类等,以便在我的情况下使用凌乱的代码 .

    这样的事情可能会很好(感谢Quentin):

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

    我已设法使用以下内容使其工作...

    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类型,这是一个笑话!

  • 4

    我一直在寻找简单而干净的方法来清除HTML文件输入,上面的答案很棒,但是他们都没有真正回答我正在寻找的东西,直到我用简单优雅的方式在网上找到它:

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

    所有的功劳都归于Chris 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>
    
  • 10

    在我的Firefox 40.0.3上只能使用它

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

    它适用于每个浏览器 .

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

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

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

    什么?在您的验证功能中,只需添加

    document.onlyform.upload.value="";
    

    假设upload是名称:

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

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

    适合我,我认为这更容易 .

相关问题