Очистка <input type='file'/"> с помощью jQuery

Можно ли очистить контрольное значение <input type='file' /> с помощью jQuery? Я пробовал следующее:

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

Но он не работает.

Ответ 1

Легко: вы оборачиваете <form> вокруг элемента, вызываете сброс формы, а затем удаляете форму, используя .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>

Ответ 2

Быстрый ответ: замените его.

В приведенном ниже коде я использую метод 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 ) );
});

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

Если клонирование при сохранении обработчиков событий представляет собой любые проблемы, которые вы могли бы рассмотреть при использовании делегирования делегирования для обработки кликов на этом элементе управления из родительского элемента:

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

Это предотвращает клонирование любых обработчиков вместе с элементом при обновлении элемента управления.

Ответ 3

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 (если они будут считайте его таковым), чтобы он фиксировался в любой более новой версии)

Как упоминается в другом ответе, сообщение на форуме 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);

Вкл 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 vanilla, это как 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

По очевидным причинам безопасности вы не можете установить значение входного файла, даже пустую строку.

Все, что вам нужно сделать, это reset форма, в которой поле или если вы хотите только reset вводить файл формы, содержащей другие поля, используйте это:

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

Вот пример: http://jsfiddle.net/v2SZJ/1/

Ответ 6

В IE8 они сделали поле "Загрузка файла" доступным только для чтения. См. сообщение в блоге команды IE:

Исторически, элемент управления загрузкой файлов HTML() был источником значительного числа уязвимостей, связанных с раскрытием информации. Чтобы решить эти проблемы, были внесены два изменения в поведение элемента управления.

Чтобы блокировать атаки, которые полагаются на "кражи" нажатий клавиш, чтобы тайно подтолкнуть пользователя к вводу локального пути к файлу в элементе управления, поле редактирования пути к файлу теперь доступно только для чтения. Пользователь должен явно выбрать файл для загрузки в диалоговом окне "Просмотр файлов".

Кроме того, для параметра "Включение локального каталога при загрузке файлов" URLAction установлено значение "Отключить" для интернет-зоны. Это изменение предотвращает утечку потенциально чувствительной локальной файловой системы в Интернет. Например, вместо отправки полного пути C:\users\ericlaw\documents\secret\image.png, Internet Explorer 8 теперь будет отправлять только имя файла image.png.

Ответ 7

$("#control").val('') - это все, что вам нужно! Протестировано на Chrome с использованием JQuery 1.11

Другие пользователи также протестировали в Firefox.

Ответ 8

Я застрял со всеми вариантами здесь. Вот хак, который я сделал, который работал:

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

и вы можете вызвать reset с помощью jQuery с кодом, подобным этому:

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

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

Ответ 9

Я закончил с этим:

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

может быть не самым элегантным решением, но оно работает, насколько я могу судить.

Ответ 10

Я использовал 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 = '';
        }
    });
};

Ответ 11

Значение входных файлов считывается только (из соображений безопасности). Вы не можете пропустить его программно (кроме вызова метода reset() формы, который имеет более широкую область действия, чем только это поле).

Ответ 12

Мне удалось запустить мою работу со следующим кодом:

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

Ответ 13

Я искал простой и понятный способ очистки ввода HTML файла, приведенные выше ответы великолепны, но ни один из них действительно не отвечает на то, что я ищу, пока я не наткнулся в Интернете на простой и элегантный способ сделать это:

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

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

все заслуги идут к Крису Койеру.

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

Ответ 14

В <<20 > работает не в Opera (и, возможно, другие). Он сохраняет содержимое.

Ближайшим методом для меня был Джонатан ранее, однако, гарантируя, что поле сохранит его имя, классы и т.д., сделанные для грязного кода в моем случае.

Что-то вроде этого может работать хорошо (спасибо Квентину тоже):

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

Ответ 15

Мне удалось заставить это работать, используя следующие...

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, если вы обновляете страницу, элемент файла будет заново заполнен выбранным файлом. Где он получает эту информацию, выходит за меня. Что еще может быть связано с элементом ввода файла?

  • Не забудьте использовать делегирование для любых событий, которые вы подключили к элементу ввода файла, поэтому они все еще работают, когда выполняется клонирование.

То, что я не понимаю, - это то, кто на земле думал, что не позволяет вам очистить поле ввода от недопустимого неприемлемого выбора файла, была хорошая идея?

ОК, не позволяйте мне динамически устанавливать его со значением, чтобы я не мог выщелачивать файлы из пользовательской ОС, но позвольте мне очистить недопустимый выбор без сброса всей формы.

Не похоже, что "accept" делает что-либо, кроме фильтра, в любом случае и в IE10, он даже не понимает типы mime MS Word, это шутка!

Ответ 16

В моем Firefox 40.0.3 работает только с этим

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

Ответ 17

его работы для меня в каждом браузере.

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

Ответ 18

Я попытался использовать большинство техник, о которых упоминали пользователи, но ни один из них не работал во всех браузерах. i.e: 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);

Ответ 19


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

Ответ 20

Сделайте его асинхронным и reset после выполнения кнопки.

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

Ответ 21

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

Работал для меня....

Ответ 22

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

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

Ответ 23

у меня не работает:

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

поэтому в asp mvc я использую бритвенные функции для замены файлового ввода. сначала создайте переменную для входной строки с Id и Name, а затем используйте ее для отображения на странице и замены при нажатии кнопки сброса:

@{
    var attachmentInput = Html.TextBoxFor(c => c.Attachment, new { type = "file" });
}

@attachmentInput

<button type="button" onclick="$('#@(Html.IdFor(p => p.Attachment))').replaceWith('@(attachmentInput)');">--</button>

Ответ 24

Самый простой способ - изменить тип ввода и снова изменить его.

Примерно так:

var input = $('#attachments');
input.prop('type', 'text');
input.prop('type', 'file')

Ответ 25

Это работает с Chrome, FF и Safari

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

Может не работать с IE или Opera

Ответ 26

Вы можете заменить его своим клоном так

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

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

Но это тоже клонирует с его значением, так что вам было бы лучше так

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

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

Ответ 27

Просто используйте,

 $("#fileUploaderID").val(''); 

Ответ 28

Легко lol (работает во всех браузерах [кроме оперы]):

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

JS Fiddle: http://jsfiddle.net/cw84x/1/

Ответ 29

Что? В своей функции проверки просто поставьте

document.onlyform.upload.value="";

Предполагая, что выгрузка - это имя:

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

Я использую JSP, не уверен, что это имеет значение...

Работает для меня, и я думаю, что это проще.