Programowo uruchom okno dialogowe „wybierz plik”


100

Mam ukryty element wejściowy pliku. Czy możliwe jest wywołanie okna dialogowego wyboru pliku ze zdarzenia kliknięcia przycisku?

Odpowiedzi:


146

Jeśli chcesz mieć własny przycisk do przesyłania pliku zamiast używania go <input type="file" />, możesz zrobić coś takiego:

<input id="myInput" type="file" style="visibility:hidden" />
<input type="button" value="Show Dialog" onclick="$('#myInput').click();" />

Zauważ, że użyłem visibility: hiddenzamiast display: none. Nie można wywołać zdarzenia kliknięcia w przypadku niewidocznego pliku wejściowego.


Prosty w podstawowych przypadkach, ale nie jest kompatybilny z wieloma przeglądarkami. Należy pamiętać, że znacznie lepszym pomysłem jest połączenie tego rozwiązania z nałożeniem elementu wejściowego pliku na przycisk przy kryciu: 0, jak wspomniano w odpowiedzi Xeon06.
— SquareCat

10
Aktualizacja: w nowoczesnych przeglądarkach możesz kliknąć wejście, którego nie ma nawet w DOM. Niesamowite!
— Adria

7
Próbowałem tylko click()na display:nonewejściu i to działało
— Daniel Cheung

15
Tak, tutaj w 2015 roku, click()żywioł z display: nonedziełami! ;) Jak wiele się zmieniło w ciągu ostatnich czterech lat.
— ffxsam

Możesz hiddenzamiast tego użyć atrybutu style="visibility:hidden": <input id="myInput" type="file" hidden>( w3schools.com/tags/att_global_hidden.asp )
— cespon

114

W większości odpowiedzi brakuje tu przydatnych informacji:

Tak, możesz programowo kliknąć element wejściowy za pomocą jQuery / JavaScript, ale tylko wtedy, gdy robisz to w module obsługi zdarzeń należącym do zdarzenia, które ZACZĘŁO UŻYTKOWNIK!

Na przykład nic się nie stanie, jeśli ty, skrypt, programowo klikniesz przycisk w wywołaniu zwrotnym Ajax, ale jeśli umieścisz tę samą linię kodu w module obsługi zdarzeń, który został wywołany przez użytkownika, zadziała.

PS debugger;Słowo kluczowe zakłóca okno przeglądarki, jeśli znajduje się przed programowym kliknięciem ... przynajmniej w chrome 33 ...


jak słusznie wspomina @LouisBataillard: nie tylko oryginalny program obsługi zdarzeń musi być zainicjowany przez użytkownika; musi to być konkretnie zdarzenie kliknięcia. Oto skrzypce, które przedstawił, demonstrując to: link
— Souhaieb Besbes

1
możesz kliknąć coś, co jest generowane dynamicznie. w jquery, czyli$(staticElementParent).on("click", "dynamicChild", function(){})
— Daniel Cheung

1
DZIĘKUJĘ CI!!!! Testowałem wszystkie te odpowiedzi w konsoli javascript i oszalałem!
— jdkealy

8
Przez pół godziny walczyłem z programowym monitowaniem o okno wprowadzania pliku. NIKT INNY stwierdził, że to niemożliwe, jeśli wydarzenie nie zostanie rozpoczęte przez użytkownika ... zasługujesz na dużo +1.
— Umagon

1
Od Chrome 62 debugger;słowo kluczowe nie zakłóca już automatycznego klikania
— Chris W.,

62

Dla przypomnienia, istnieje alternatywne rozwiązanie, które nie wymaga javascript. To trochę hack, wykorzystując fakt, że kliknięcie etykiety powoduje skupienie się na powiązanych danych wejściowych.

Potrzebujesz a <label>z odpowiednim foratrybutem (wskazuje na wejście), opcjonalnie stylizowanym na przycisk (z bootstrapem, użyj btn btn-default). Gdy użytkownik kliknie etykietę, zostanie otwarte okno dialogowe, na przykład:

<!-- optionnal, to add a bit of style -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>

<!-- minimal setup -->
<label for="exampleInput" class="btn btn-default">
  Click me
</label>
<input type="file" id="exampleInput" style="display: none" />


2
Podoba mi się ten, nie chcę włączać pełnego jQuery do mojego projektu Angulara, działa dobrze :)
— Starscream1984

1
czy to zachowanie jest niezawodne we wszystkich nowoczesnych przeglądarkach?
— JoshuaDavid,

Działa to bez żadnego JS, używając natywnego zachowania przeglądarki. W połączeniu ze zdarzeniami onDrop implementacja bogatego w funkcje przesyłania plików działa świetnie!
— Yanick Rochon

Musiałem majstrować przy CSS, ale potem zadziałało - mianowicie widoczność pliku wejściowego z "display: none" nie jest w porządku we wszystkich przeglądarkach. (Ale krycie
— równe

13

Nie jestem pewien, jak przeglądarki radzą sobie z kliknięciami type="file"elementów (względy bezpieczeństwa i wszystko inne), ale to powinno działać:

$('input[type="file"]').click();

Przetestowałem to JSFiddle w Chrome, Firefox i Opera i wszystkie pokazują okno dialogowe przeglądania plików.


5
Wydaje się, że działa to tylko wtedy, gdy zdarzenie „dzwonienie” samo jest zdarzeniem kliknięcia. Na przykład wydaje się, że nie można otworzyć okna dialogowego pliku na podstawie hoverzdarzenia: jsfiddle.net/UQfaZ/1
— Louis B.

Czy wiesz, jak można to przetestować za pomocą Selenium, jeśli wejście nie znajduje się w DOM?
— Sebastien Lorber

4

Zawijam input[type=file]etykietę, stylizuję ją labelwedług własnych upodobań i ukrywam input.

<label class="btn btn-default fileLabel" data-toggle="tooltip" data-placement="top" title="Upload">
    <input type="file">
    <span><i class="fa fa-upload"></i></span>
</label>

<style>
    .fileLabel input[type="file"] {
        position: fixed;
        top: -1000px;
    }
</style>

Rozwiązanie czysto CSS.


Po prostu ustaw, <input type="file" hidden>aby usunąć potrzebę stosowania stylu CSS.
— Sylvain Lesage

3

Niestety, jedynym sposobem jest utworzenie <input type="file">elementu, a następnie zasymulowanie kliknięcia.

Jest mała wtyczka (bezwstydna wtyczka), która wyeliminuje ból związany z koniecznością robienia tego przez cały czas: file-dialog

fileDialog()
    .then(file => {
        const data = new FormData()
        data.append('file', file[0])
        data.append('imageName', 'flower')

        // Post to server
        fetch('/uploadImage', {
            method: 'POST',
            body: data
        })
    })

3

Najlepsze rozwiązanie, działa we wszystkich przeglądarkach ... nawet na urządzeniach mobilnych.

<div class="btn" id="s_photo">Upload</div>

<input type="file" name="s_file" id="s_file" style="opacity: 0;">';

<!--jquery-->

<script>
    $("#s_photo").click(function() {
        $("#s_file").trigger("click");
    });
</script>

Ukrywanie typu pliku wejściowego powoduje problemy z przeglądarkami, krycie jest najlepszym rozwiązaniem, ponieważ nie jest ukrywany, po prostu się nie wyświetla. :)


1
powinieneś wspomnieć, że wymaga to odwołania do jQuery.
— Brino

Nieprzezroczystość wiąże się z zupełnie niepowiązaną koncepcją - masz po prostu szczęście, jeśli nie wpływa na Twój układ z elementem „przezroczystym”. Element powinien tam być, ale niewidoczny, więc visibility:hiddenpowinien być lepszym wyborem.
— conny

visibility: hiddennadal wpływa na układ. display: nonejest tym, czego chcesz.
— stommestack

1

Ze względów bezpieczeństwa nie można tego zrobić w różnych przeglądarkach. To, co zwykle robią ludzie, to nakładanie pliku wejściowego na coś innego i ustawianie jego widoczności na ukrytą, aby był uruchamiany samodzielnie. Więcej informacji tutaj.


2
OP mówi <input type="file">, a nie <select>.
— Bojangles

Żaden problem. Sam to robiłem wcześniej. W odpowiedzi na Twoją zmianę jest na to sposób; wyzwalając zdarzenie click elementu za pomocą jQuery $.click().
— Bojangles

1
@JamWaffles okay, to dziwne. Wyraźnie pamiętam, że kilka tygodni temu spędziłem nad tym cały dzień. To nie działało w Firefox i IE. Ciekawe, o co chodziło ...
— Alex Turpin,

Ciekawy. W mojej odpowiedzi mam JSFiddle, który działa z FF. Nie mogę testować w IE (jestem na Linuksie), więc nie wiem, czy to nadal będzie wymiotować.
— Bojangles

2
Dobry wysiłek badawczy! Gdybym wziął ani grosza za każdym razem, gdy twórcy stron internetowych musieli włamać się do jakiegoś całkiem normalnego zachowania, byłbym obrzydliwie bogaty.
— Bojangles

1

Upewnij się, że używasz wiązania, aby uzyskać właściwości komponentów w REACT

class FileUploader extends Component {
  constructor (props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
   onChange=(e,props)=>{
    const files = e.target.files;
    const selectedFile = files[0];
    ProcessFileUpload(selectedFile,props.ProgressCallBack,props.ErrorCallBack,props.CompleatedCallBack,props.BaseURL,props.Location,props.FilesAllowed);
  }
   handleClick = () => {
    this.refs.fileUploader.click();
  }
  render()
  {
  return(
      <div>
        <button type="button" onClick={this.handleClick}>Select File</button>  
        <input type='file' onChange={(e)=>this.onChange(e,this.props)} ref="fileUploader" style={{display:"none"}} />
      </div>)
  }
}



0

Dla tych, którzy chcą tego samego, ale używają React

openFileInput = () => {
    this.fileInput.click()
}

<a href="#" onClick={this.openFileInput}>
    <p>Carregue sua foto de perfil</p>
    <img src={img} />
</a>
<input style={{display:'none'}} ref={(input) => { this.fileInput = input; }} type="file"/>

0
<div id="uploadButton">UPLOAD</div>
<form action="[FILE_HANDLER_URL]" style="display:none">
     <input id="myInput" type="file" />
</form>
<script>
  const uploadButton = document.getElementById('uploadButton');
  const myInput = document.getElementById('myInput');

  uploadButton.addEventListener('click', () => {
    myInput.click();
  });
</script>
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.