Como posso limpar uma entrada de arquivo HTML com JavaScript?


154

Quero limpar a entrada do arquivo no meu formulário.

Eu sei sobre como definir as fontes para o mesmo método ... Mas esse método não apaga o caminho do arquivo selecionado.

Nota : Gostaria de evitar a necessidade de recarregar a página, redefinir o formulário ou realizar uma chamada AJAX.

Isso é possível?

Respostas:


-10

Que tal remover esse nó, criar um novo com o mesmo nome?


46
Como assim, me dê um exemplo, por favor.

1
você perderá seus manipuladores, como este: var inputPhoto = document.getElementById ('photoInput'); inputPhoto.addEventListener ('change', handler_file, false);
— Rui Martins

Votado por falta de explicação!
— Jason

211

Existem três maneiras de limpar a entrada de arquivo com javascript:

  1. defina a propriedade value como vazia ou nula.

    Funciona para o IE11 + e outros navegadores modernos.

  2. Crie um novo elemento de entrada de arquivo e substitua o antigo.

    A desvantagem é que você perderá ouvintes de eventos e propriedades de expando.

  3. Redefina o formulário do proprietário pelo método form.reset ().

    Para evitar afetar outros elementos de entrada no mesmo formulário do proprietário, podemos criar um novo formulário vazio e anexar o elemento de entrada do arquivo a esse novo formulário e redefini-lo. Dessa forma, funciona para todos os navegadores.

Eu escrevi uma função javascript. demo: http://jsbin.com/muhipoye/1/

function clearInputFile(f){
    if(f.value){
        try{
            f.value = ''; //for IE11, latest Chrome/Firefox/Opera...
        }catch(err){ }
        if(f.value){ //for IE5 ~ IE10
            var form = document.createElement('form'),
                parentNode = f.parentNode, ref = f.nextSibling;
            form.appendChild(f);
            form.reset();
            parentNode.insertBefore(f,ref);
        }
    }
}

1
Não devemos remover também o formulário criado posteriormente?
— Andrey

1
Não, você não precisa. o elemento do formulário não foi anexado à árvore de documentos da página.
— cuixiping

5
Apenas uma palavra de aviso, o uso das abordagens 2. ou 3. pode ter implicações para você, se você deseja preservar eventos e outros atributos que foram adicionados a um elemento programaticamente. No meu caso, adicionei um evento onclick a um elemento do formulário que desapareceu após a redefinição do formulário. Nesse caso, a abordagem 1. é melhor. (Isso foi observado para 2., mas também pode acontecer por 3.)
— Wolfie Inu

85

tl; dr : para navegadores modernos, basta usar

input.value = '';

Resposta antiga:

E se:

input.type = "text";
input.type = "file";

Ainda preciso entender por que isso não funciona com o webkit .

De qualquer forma, isso funciona com o IE9>, Firefox e Opera.
A situação com o webkit é que parece que não consigo alterá-lo novamente para o arquivo.
Com o IE8, a situação é que ele lança uma exceção de segurança.

Edit: Para webkit, Opera e firefox, isso funciona, no entanto:

input.value = '';

(verifique a resposta acima com esta proposta)

Vou ver se consigo encontrar uma maneira mais limpa de fazer esse navegador cruzado sem a necessidade do GC.

Edit2:

try{
    inputs[i].value = '';
    if(inputs[i].value){
        inputs[i].type = "text";
        inputs[i].type = "file";
    }
}catch(e){}

Funciona com a maioria dos navegadores. Não funciona com o IE <9, isso é tudo.
Testado no firefox 20, chrome 24, opera 12, IE7, IE8, IE9 e IE10.


35

Definir o valor para ''não funciona em todos os navegadores.

Em vez disso, tente definir o valor da seguinte nullforma:

document.getElementById('your_input_id').value= null;

EDIT: Eu recebo os motivos de segurança muito válidos para não permitir que o JS defina a entrada do arquivo, no entanto, parece razoável fornecer um mecanismo simples para limpar a seleção de saída já selecionada. Tentei usar uma string vazia, mas ela não funcionou em todos os navegadores, NULLfuncionou em todos os navegadores que experimentei (Opera, Chrome, FF, IE11 + e Safari).

EDIT: Observe que a configuração para NULLfunciona em todos os navegadores enquanto a configuração para uma string vazia não.


6
Infelizmente não estou vendo isso em all browsers... ele não funciona no IE8, IE9 ou IE10 (mas funciona no IE11).
— freefaller

Bem, caramba. Não testei versões mais antigas do navegador IE. Desculpe.
— BigMac66

31

Infelizmente, nenhuma das respostas acima parece cobrir todas as bases - pelo menos não nos meus testes com javascript vanilla.

  • .value = nullparece funcionar no FireFox, Chome, Opera e IE11 (mas não no IE8 / 9/10)

  • .cloneNode(e .clone()no jQuery) no FireFox parece copiar o .valueexcesso, tornando o clone inútil.

Então, aqui está a função javascript vanilla que eu escrevi que funciona no FireFox (27 e 28), Chrome (33), IE (8, 9, 10, 11), Opera (17) ... esses são os únicos navegadores disponíveis atualmente para eu testar.

function clearFileInput(ctrl) {
  try {
    ctrl.value = null;
  } catch(ex) { }
  if (ctrl.value) {
    ctrl.parentNode.replaceChild(ctrl.cloneNode(true), ctrl);
  }
}

O ctrlparâmetro é a própria entrada do arquivo, portanto a função seria chamada como ...

clearFileInput(document.getElementById("myFileInput"));

1
Essa é a resposta. Um dos problemas com tantas respostas para esta pergunta - não apenas nesta página, mas também em outros fóruns, é que você pode limpar o texto "3 arquivos selecionados", mas na verdade não limpa os arquivos http fila. O que acontece é que na próxima vez que você tentar fazer o upload, você poderá selecionar apenas um arquivo e, pior ainda, ele será salvo na pasta anterior. Essa resposta limpará os dois, e você poderá retomar o upload do próximo conjunto de arquivos com a mesma facilidade com que carregou o primeiro conjunto de arquivos.
— TARKUS 28/04

A ifdeclaração não deve ser colocada dentro do catchbloco?
— Fahmi

@Fahmi - não, não deveria
— freefaller

Ah, eu pensei que o IE8 / 9/10 lançaria uma exceção ao tentar definir o valor para null. Importa-se de explicar qual é o sentido de colocar ctrl.value = null;dentro de um try...catchbloco então? Desculpe pela nova pergunta.
— Fahmi

1
ctrl.parentNode.replaceChild(ctrl.cloneNode(true), ctrl);- em que ponto, na verdade, limpamos o valor, já que cloneNodetambém o copia?
— Fahmi


11

Você precisa substituí-lo por uma nova entrada de arquivo. Aqui está como isso pode ser feito com o jQuery:

var inputFile = $('input[type=field]');
inputFile.wrap('<div />');

e use esta linha quando precisar limpar o campo de entrada (em algum evento, por exemplo):

inputFile.parent().html( inputFile.parent().html() );

Para substituir o elemento original, este parece melhor: stackoverflow.com/questions/1043957/...
— Mengdi Gao

9
document.getElementById('your_input_id').value=''

Edit:
Este não funciona no IE e na ópera, mas parece funcionar para o Firefox, Safari e Chrome.


7
Isso funciona para mim, embora eu sempre me pergunte por quanto tempo.
— 586 Pekka

isso não funcionará, apenas em alguns navegadores, e também definir o valor de uma entrada de arquivo é uma violação de segurança ... não é uma boa escolha.

5

Eu estava tendo o mesmo problema e eu vim com isso.

var file = document.querySelector('input');
var emptyFile = document.createElement('input');
emptyFile.type = 'file';

document.querySelector('button').onclick = function(){
  file.files = emptyFile.files;
}
<input type='file'>
<button>clear</button>


4

Isso é realmente muito fácil.

document.querySelector('#input-field').value = '';

3

Eu tenho procurado uma maneira simples e limpa de limpar a entrada de arquivos HTML, as respostas acima são ótimas, mas nenhuma delas realmente responde ao que estou procurando, até que me deparei com a Web com uma maneira simples e elegante de fazer isso:

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

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

todo o crédito é para 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>


..e para você, isso me ajudou a verificar e exibir erros em um possível upload de arquivo. Isso é redefinido por erro e permite que o usuário reenvie o mesmo arquivo, caso alguém esteja procurando algo parecido com isto.
— Clinton Dobbs

1

As respostas acima oferecem soluções um pouco desajeitadas pelos seguintes motivos:

  1. Eu não gosto de ter que fazer wrapo inputprimeiro e, em seguida, obter o html, é muito envolvido e sujo.

  2. O JS entre navegadores é útil e parece que, neste caso, há muitas incógnitas para usar a typecomutação de maneira confiável (que, novamente, é um pouco suja) e definir valuecomo''

Então, ofereço minha solução baseada em jQuery:

$('#myinput').replaceWith($('#myinput').clone())

Ele faz o que diz, substitui a entrada por um clone de si mesmo. O clone não terá o arquivo selecionado.

Vantagens:

  1. Código simples e compreensível
  2. Sem embalagem desajeitada ou troca de tipo
  3. Compatibilidade entre navegadores (corrija-me se estiver errado aqui)

Resultado: programador feliz


3
Cross browser compatibility... meus testes mostram que o Firefox cópias sobre o .valuecomo parte do .clone(), portanto, tornando-o inútil
— freefaller

@ freefaller porque não mudar o valor antes de ligar replaceWith? Eu estou usando clone()a mim mesmo e ele está bem no firefox de trabalho (eu não sei se este é ainda o caso para você, um ano depois =))
— Abdo

@ Abdo - se você olhar para a minha resposta, verá que sim
— freefaller

A questão não está perguntando sobre jQuery; está perguntando sobre javascript.
— Arel

1

Aqui estão meus dois centavos, os arquivos de entrada são armazenados como matriz, então aqui está como anulá-lo

document.getElementById('selector').value = []

isso retorna uma matriz vazia e funciona em todos os navegadores


0

O que me ajudou é que tentei buscar e fazer upload do último arquivo selecionado usando um loop, em vez de limpar a fila, e funcionou. Aqui está o código.

for (int i = 0; i <= Request.Files.Count-1; i++)
{
 HttpPostedFileBase uploadfile = files[i];
 Stream fs = uploadfile.InputStream;
 BinaryReader br = new BinaryReader(fs);
 Byte[] imageBytes = br.ReadBytes((Int32)fs.Length);
}

Espero que isso possa ajudar alguns.


0

Tentei a maioria das soluções, mas parecia que ninguém funcionava. No entanto, eu encontrei um passeio por ele abaixo.

A estrutura do formulário é: form=> label, inpute submit button. Depois de escolher um arquivo, o nome do arquivo será mostrado pelo rótulo, manualmente, em JavaScript.

Portanto, minha estratégia é: inicialmente o envio buttoné desativado, depois que um arquivo é escolhido, o disabledatributo do botão enviar será removido para que eu possa enviar o arquivo. Depois do envio, limpo o labelque faz com que pareça limpar o arquivo, inputmas na verdade não. Depois, desabilitarei o botão Enviar novamente para impedir o envio do formulário.

Ao definir o envio button disableou não, interrompo o envio do arquivo várias vezes, a menos que escolha outro arquivo.


0

Mudei para digitar texto e voltei a digitar para arquivo usando setAttribute

'<input file-model="thefilePic" style="width:95%;" type="file" name="file" id="filepicture" accept="image/jpeg" />'

'var input=document.querySelector('#filepicture');'

if(input != null)
{
    input.setAttribute("type", "text");
    input.setAttribute("type", "file");
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.