Clearing <input type='file' /> using

2018-12-31 02:41发布

Is it possible to clear an <input type='file' /> control value with jQuery? I've tried the following:

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

But it's not working.

26条回答
牵手、夕阳
2楼-- · 2018-12-31 03:29

Easy: you wrap a <form> around the element, call reset on the form, then remove the form using unwrap(). Unlike the clone() solutions otherwise in this thread, you end up with the same element at the end (including custom properties that were set on it).

Tested and working in Opera, Firefox, Safari, Chrome and IE6+. Also works on other types of form elements, with the exception of 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();
}

As Timo notes below, if you have the buttons to trigger the reset of the field inside of the <form>, you must call preventDefault on the event to prevent the <button> from triggering a submit.

Edit

Does not work in IE 11 due to an unfixed bug. The text (file name) is cleared on the input, but its File list remains populated.

查看更多
何处买醉
3楼-- · 2018-12-31 03:29

I have managed to get this to work using the following...

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

This has been tested in IE10, FF, Chrome & Opera.

There are two caveats...

  1. Still doesn't work properly in FF, if you refresh the page, the file element gets re-populated with the selected file. Where it is getting this info from is beyond me. What else related to a file input element could I possible try to clear?

  2. Remember to use delegation on any events you had attached to the file input element, so they still work when the clone is made.

What I don't understand is who on earth thought not allowing you to clear an input field from an invalid unacceptable file selection was a good idea?

OK, don't let me dynamically set it with a value so I can't leach files from a user's OS, but let me clear an invalid selection without resetting an entire form.

It's not like 'accept' does anything other than a filter anyhow and in IE10, it doesn't even understand MS Word mime types, it's a joke!

查看更多
皆成旧梦
4楼-- · 2018-12-31 03:31

Quick answer: replace it.

In the code below I use the replaceWith jQuery method to replace the control with a clone of itself. In the event you have any handlers bound to events on this control, we'll want to preserve those as well. To do this we pass in true as the first parameter of the clone method.

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

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

Fiddle: http://jsfiddle.net/jonathansampson/dAQVM/

If cloning, while preserving event handlers, presents any issues you could consider using event delegation to handle clicks on this control from a parent element:

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

This prevents the need for any handlers to be cloned along with the element when the control is being refreshed.

查看更多
孤独寂梦人
5楼-- · 2018-12-31 03:31

The value of file inputs is read only (for security reasons). You can't blank it programatically (other than by calling the reset() method of the form, which has a broader scope than just that field).

查看更多
人气声优
6楼-- · 2018-12-31 03:32

You can replace it with its clone like so

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

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

But this clones with its value too so you had better like so

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

$('#control').replacewith(clone);
查看更多
人气声优
7楼-- · 2018-12-31 03:33

The .clone() thing does not work in Opera (and possibly others). It keeps the content.

The closest method here for me was Jonathan's earlier, however ensuring that the field preserved its name, classes, etc made for messy code in my case.

Something like this might work well (thanks to Quentin too):

function clearInput($source) {
    var $form = $('<form>')
    var $targ = $source.clone().appendTo($form)
    $form[0].reset()
    $source.replaceWith($targ)
}
查看更多
登录 后发表回答