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

518

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

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

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

Теги:
file-io
html-form

26 ответов

536

Легко: вы обертываете <form> вокруг элемента, вызываете reset в форме, а затем удаляете форму с помощью функции deploy(). В отличие от решений 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();
}

Как отмечает Тимо, ниже, если у вас есть кнопки для запуска reset поля внутри <form>, вы должны вызвать preventDefault для события, чтобы предотвратить <button> от запуска отправки.

Изменить

Не работает в IE 11 из-за нефиксированной ошибки. Текст (имя файла) очищается на входе, но его список File остается заполненным.

  • 13
    Победитель! Работает в любом браузере и избегает клонирования поля ввода. Но если кнопки очистки находятся внутри формы, переименуйте reset() в eg. reset2() , потому что по крайней мере в Chrome все поля очищаются, если он reset() . И добавьте event.preventDefault () после очистки вызова, чтобы предотвратить отправку. Таким образом: <button onclick="reset2($('#file'));event.preventDefault()">Reset file</button> . Рабочий пример: jsfiddle.net/rPaZQ/23 .
  • 1
    @Timo, я переименовал функцию resetFormElement и добавил к сведению , что вы должны preventDefault () на кнопке onclick .
Показать ещё 17 комментариев
405

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

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

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

  • 1
    В этом решении раздражает то, что в вашем коде должен быть элемент дважды, поэтому, если кто-то изменит, например, имя, вам придется дважды изменить код (что очень легко забыть)
  • 50
    Вы также можете использовать метод .clone () в поле $ ('# clone'). ReplaceWith ($ (this) .clone ());
Показать ещё 23 комментария
98

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 и другие библиотеки имеют все другие методы поддержки, необходимые для ведения такого списка, это всего лишь демонстрация.

  • 0
    Это работает! (ну, по крайней мере, немного ванили JS в начале этого ответа). Я проверял это в последних версиях Chrome, Firefox и IE (11).
  • 4
    Я собирался добавить некоторые из тех же самых ответов, но в основном это .val('') . Разве это не проще, чем клонирование элемента загрузки или добавление вложенной формы? +1.
Показать ещё 2 комментария
48

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

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

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

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

  • 6
    Не правильно работает в IE. Визуально значение сбрасывается, но el.value по-прежнему сообщает предыдущую версию. Это помогает сбросить el.value, но только в IE10 +. jsfiddle.net/9uPh5/2
  • 2
    То же решение, что и выше
Показать ещё 1 комментарий
43

Это работает для меня.

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

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

Надеюсь, что это поможет.

  • 1
    Работает для меня! Стоит отметить, что если у вас есть какие-либо прослушиватели событий, вызванные изменением входного файла, вам необходимо переназначить их после замены ввода.
21

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

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

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

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

12

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

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

  • 3
    хорошо, но это очистит всю форму .. не конкретный файл ввода
10

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

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

  • 2
    Как объясняют многие другие посты, это не подходит для разных браузеров.
  • 0
    Насколько я понимаю, в каких браузерах это происходит?
Показать ещё 3 комментария
8

Я использовал 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 = '';
        }
    });
};
  • 0
    Я не понимаю, почему этот ответ не более проголосовал ?!
  • 1
    @AlexB: потому что, как объяснил Тимо, просто очищать одно поле ввода файла.
Показать ещё 2 комментария
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'); 
}

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

  • 0
    stackoverflow.com/questions/8378563/...
  • 0
    не работает в Chrome 34 (Linux). Метод replaceWith () работает в обоих браузерах (chrome, firefox)
Показать ещё 1 комментарий
5

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

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

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

  • 16
    Я в замешательстве - я пытался $ ("# inputControl"). Val (""), и это действительно пустое поле. Я что-то пропустил?
  • 1
    @ Джонатан, у меня тоже работает, но если вы установите его на что-то другое, это ошибка безопасности. Проверено в FF4.
Показать ещё 2 комментария
4

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

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, это шутка!

  • 0
    Это почти работает. Единственное, что вам нужно сделать, чтобы заставить эту работу работать в Firefox, - это использовать .pop() для массива файлов вместо того, чтобы устанавливать его в null. похоже, это правильно очищает файл.
4

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

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

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

function clearInput($source) {
    var $form = $('<form>')
    var $targ = $source.clone().appendTo($form)
    $form[0].reset()
    $source.replaceWith($targ)
}
  • 0
    Это было проверено во всех основных браузерах?
  • 0
    Кажется, он отлично работает в последней версии Chrome / FF / Opera и IE8. Я не вижу никакой причины, по которой это ни на что не сработает - опция сброса на формах существует уже давно.
3

Я искал простой и чистый способ очистки ввода 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>
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);
        }
2

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

 $('input[type=file]').val('');
 $('input[type=file]').replaceWith($('input[type=file]').clone(true));
  • 1
    . $ ( 'Ввода [тип = файл]') ReplaceWith (. $ ( 'Ввода [тип = файл]') клон (истина) .val ( ''));
1

Я попытался использовать большинство техник, о которых упоминали пользователи, но ни один из них не работал во всех браузерах. 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);
  • 0
    У меня тоже работает, большое спасибо!
0
function clear() {
    var input = document.createElement("input");
    input.setAttribute('type', 'file');
    input.setAttribute('value', '');
    input.setAttribute('id', 'email_attach');

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

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

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

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

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

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

$('#control').replacewith(clone);
0
$("#control").val("");

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

0

Сделайте его асинхронным и 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>
0

$("input[type=file]").wrap("<div id='fileWrapper'/>");
$("#fileWrapper").append("<div id='duplicateFile'   style='display:none'>"+$("#fileWrapper").html()+"</div>");
$("#fileWrapper").html($("#duplicateFile").html());
  • 1
    Привет, Нирадж. Добро пожаловать. Этот ответ вполне может быть правильным, но он может использовать некоторые объяснения.
-2

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

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

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

  • 0
    Это не будет работать в IE или Opera
  • 1
    Выглядит почти идентично самой проблеме в ОП
Показать ещё 1 комментарий
-3

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

document.onlyform.upload.value="";

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

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

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

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

  • 1
    Это не будет работать в IE
-4

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

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

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

  • 0
    Это не работает в Опере, поэтому не совсем идеально.
  • 0
    Мне наплевать на оперу. Просто заверните его в форму, если вам все равно. Мне лично все равно, и я буду использовать свой метод.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню