como disparar evento na seleção de arquivo

95

Eu tenho um formulário como

<form  onSubmit="return disableForm(this);" action="upload.php" method="post" name="f" id="wizecho" enctype="multipart/form-data">
    <input type="file" name="file" />
    <button onClick="return disableForm(this),ajaxUpload(this.form,'wizecho_upload.php', '&lt;br&gt;Uploading image please wait.....&lt;br&gt;'); return false;">
        Upload Image
    </button>
</form>

É para fazer upload de uma imagem.

Aqui preciso clicar no botão para fazer o upload da imagem e usar o onClickevento. Quero remover o botão de upload e assim que o arquivo for selecionado na entrada, quero disparar o evento. Como faço isso??

ptamzz
fonte
Se você está preocupado em selecionar o mesmo arquivo duas vezes, @applecrusher tem uma solução melhor do que a resposta selecionada stackoverflow.com/a/40581284/1520304
Will Farley

Respostas:

128

Use o evento de mudança na entrada do arquivo.

$("#file").change(function(){
         //submit the form here
 });
Vincent Ramdhanie
fonte
30
e o que acontece quando você envia o formulário de forma assíncrona, não sai da página e tenta carregar o mesmo arquivo novamente? Este código será executado apenas uma vez, na segunda vez, selecionando o mesmo arquivo não executará um evento de alteração
Christopher Thomas
6
A objeção de @ChristopherThomas é exatamente por que estou aqui, e felizmente há uma resposta muito subestimada abaixo que resolve isso, anos depois: stackoverflow.com/a/40581284/4526479
Kyle Baker
1
O evento de mudança não é acionado quando seleciono o mesmo arquivo novamente. Qualquer outra maneira que pode funcionar sempre?
Tᴀʀᴇǫ Mᴀʜᴍᴏᴏᴅ
1
@ Tᴀʀᴇǫ Mᴀʜᴍᴏᴏᴅ Veja o comentário logo acima do seu.
David Lopez
3
O fato de a resposta não usar javascript puro é simplesmente errado
Dimitris Filippou
68

Você pode se inscrever para o evento onchange no campo de entrada:

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

e depois:

document.getElementById('file').onchange = function() {
    // fire the upload here
};
Darin Dimitrov
fonte
49

Esta é uma pergunta mais antiga que precisa de uma resposta mais recente que abordará a preocupação de @Christopher Thomas acima nos comentários da resposta de aceitação. Se você não navegar para fora da página e selecionar o arquivo uma segunda vez, será necessário limpar o valor ao clicar ou fazer um touchstart (para celular). O seguinte funcionará mesmo quando você navegar para fora da página e usar jquery:

//the HTML
<input type="file" id="file" name="file" />



//the JavaScript

/*resets the value to address navigating away from the page 
and choosing to upload the same file */ 

$('#file').on('click touchstart' , function(){
    $(this).val('');
});


//Trigger now when you have selected any file 
$("#file").change(function(e) {
    //do whatever you want here
});
esmagador
fonte
Este navegador é compatível? Parece que está apenas usando val(''), o que não funciona na maioria dos navegadores.
Sean Kendle
Qual navegador que você experimentou não funciona? Tente clonar o objeto com ele mesmo, se ainda for um problema para você.
applecrusher
2
Meu problema era usar element.setAttribute("value", "")Se você não estiver usando jQuery, você precisa usar element.value = ""para fazer com que o elemento de arquivo seja realmente limpo de maneira adequada.
Phil
1

Faça o que quiser depois que o arquivo for carregado com sucesso. Logo após a conclusão do processamento do arquivo, defina o valor do controle de arquivo como string em branco. Portanto, o .change () sempre será chamado, mesmo que o nome do arquivo seja alterado ou não. como por exemplo você pode fazer isso e funcionou para mim como um charme

  $('#myFile').change(function () {
    LoadFile("myFile");//function to do processing of file.
    $('#myFile').val('');// set the value to empty of myfile control.
    });
Mohit Singh
fonte
1

Solução para usuários vue, resolvendo o problema quando você carrega o mesmo arquivo várias vezes e o evento @change não é acionado:

 <input
      ref="fileInput"
      type="file"
      @click="onClick"
    />
  methods: {
    onClick() {
       this.$refs.fileInput.value = ''
       // further logic for file...
    }
  }
Alb Bolush
fonte
<input type = "file" @ change = "onFileChange" class = "input upload-input" ref = "inputFile" /> self. $ refs.inputFile.value = ''
Pragati Dugar
0

<input type = "file" @ change = "onFileChange" class = "input upload-input" ref = "inputFile" />

onFileChange(e) {
//upload file and then delete it from input 
 self.$refs.inputFile.value = ''
}
Pragati Dugar
fonte