Otwórz okno dialogowe pliku w JavaScript

109

Potrzebuję rozwiązania, aby wyświetlić okno dialogowe otwierania pliku w formacie HTML podczas klikania pliku div. Okno dialogowe otwierania pliku musi zostać otwarte po divkliknięciu.

Nie chcę wyświetlać pola pliku wejściowego jako części strony HTML. Musi być wyświetlany w osobnym oknie dialogowym, które nie jest częścią strony internetowej.

Arka
źródło
4
Alert nie jest oknem dialogowym pliku? - Czy możesz wyjaśnić, o co prosisz?
LiamB,
3
Myślę, że mówi, że chce standardowego wyskakującego okienka „otwartego pliku”
Valentin Rocher
1
Potrzebuję okna dialogowego otwierania pliku po kliknięciu elementu DIV. musi być jak alert, który nie jest częścią strony internetowej
ArK

Odpowiedzi:

52

Oto ładny

Fine Uploader demo

To <input type='file' />sama kontrola. Ale nad nim jest umieszczony element div, a style CSS są stosowane, aby uzyskać ten efekt. Przezroczystość elementu sterującego pliku jest ustawiona na 0, więc po kliknięciu elementu div wydaje się, że okno dialogowe jest otwierane.

rahul
źródło
1
czy istnieje sposób na kontrolowanie wyświetlanych plików przez javascript ... powiedzmy, że chciałem otworzyć okno dialogowe pliku i chciałem tylko wyświetlić rozszerzenie pliku z .pdf ..
Ajax3.14
1
@ Ajax3.14 nowe przeglądarki mają obiekt FileReader, stare przeglądarki musisz użyć wartości i poszukać rozszerzenia pliku.
Vicary,
2
@ Ajax3.14 Nie ma potrzeby używania FileReader lub analizowania rozszerzeń. Wiele przeglądarek obsługuje atrybut accept w plikach wejściowych. Umożliwia to ograniczenie typów plików wyświetlanych w oknie dialogowym przeglądarki plików. Fine Uploader zapewnia dostęp do tej funkcji za pośrednictwem właściwości acceptFiles opcji walidacji. Więcej informacji można znaleźć w sekcji dotyczącej walidacji w dokumentacji opcji . Należy pamiętać, że atrybut accept nie jest obsługiwany w przeglądarce IE9 lub starszej.
Ray Nicholus,
1
jak to jest dobre? to w ogóle jest dobra praktyka? nie powinno wyglądać tak: stackoverflow.com/a/18659941/915865 ?
Kat Lim Ruiz
1
@KatLimRuiz Nie, odpowiedź, z którą się łączysz, nie jest dobrym rozwiązaniem. Spowoduje to, że IE zgłosi błąd, jeśli w końcu wyślesz powiązany formularz również w sposób programowy.
Ray Nicholus
77

    $("#logo").css('opacity','0');
    
    $("#select_logo").click(function(e){
       e.preventDefault();
       $("#logo").trigger('click');
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#" id="select_logo">Select Logo</a> <input type="file" id="logo">

dla IE dodaj to:

$("#logo").css('filter','alpha(opacity = 0');
Somwang Souksavatd
źródło
3
Dlaczego zwracasz wartość false w module obsługi kliknięć #select_logo?
Sethish
4
Nie spowodowałoby to błędu 404, po prostu spróbowałoby przejść do bieżącej strony, z dodanym # na końcu. Co sprawiłoby, że strona wskoczyłaby na górę. Więc dobrze jest tam być, tylko z innego powodu :)
manavo
3
Chociaż nie przetestowałem tego wystarczająco, „widoczność: ukryta”; wydaje się bardziej kompatybilny. Ponadto, pomimo nieprzezroczystości: 0, zdarzenie kliknięcia zostanie wywołane, jeśli kliknięty zostanie element „niewidoczny”, natomiast visibility: hidden nie.
Aron,
MDN wskazuje, że document.getElementById("logo").click()wystarczy. Pokazują również inny sposób „Przeciągnij i upuść”. developer.mozilla.org/en-US/docs/Web/API/File/…
Eric
2
Powinieneś przekonwertować to na normalny Javascript, JQuery nie jest logiczne do użycia w tak małym projekcie ^ _ ^
Mister SirCode
57

Nie wiem, dlaczego nikt tego nie wskazał, ale oto sposób na zrobienie tego bez Javascript i jest również kompatybilny z każdą przeglądarką.


EDYCJA: W Safari inputzostaje wyłączone, gdy jest ukryte za pomocą display: none. Lepszym podejściem byłoby użycie position: fixed; top: -100em.


<label>
  Open file dialog
  <input type="file" style="position: fixed; top: -100em">
</label>

Jeśli wolisz, możesz iść na „właściwą drogę” , używając forw labelskierowaną do idwejścia w ten sposób:

<label for="inputId">file dialog</label>
<input id="inputId" type="file" style="position: fixed; top: -100em">
JP de la Torre
źródło
4
to działa jak urok, jednak oto kilka zaleceń: 1. <input>tag powinien mieć nameatrybut; 2. Jeśli forokreślono atrybut, <input>znacznik pliku będzie wymagał rozszerzenia id.
Raptor
5
Simplicity is the ultimate sophistication
ncubica
2
świetny! działa jak urok, nawet z obrazem w tle lub powodując, że etykieta otrzymuje kliknięcie uruchamiane javascript. Dzięki!
Leo Nomdedeu
2
Swoją drogą, ktoś wskazał na jeden haczyk tym rozwiązaniem, w Safari wejścia ukryte display: nonesą wyłączone. Obejście polega na zastosowaniu innego podejścia do ukrycia danych wejściowych. Zaktualizuję odpowiedź, aby to odzwierciedlić.
JP de la Torre
1
@JPdelaTorre Byłoby znacznie lepiej, gdybyś zamiast tego użył krycia: 0 do ukrycia danych wejściowych.
Adrian,
39

Właściwie nie potrzebujesz tego wszystkiego z kryciem, widocznością, <input>stylem itp. Po prostu spójrz:

<a href="#">Just click me.</a>
<script type="text/javascript">
    $("a").click(function() {
        // creating input on-the-fly
        var input = $(document.createElement("input"));
        input.attr("type", "file");
        // add onchange handler if you wish to get the file :)
        input.trigger("click"); // opening dialog
        return false; // avoiding navigation
    });
</script>

Demo na jsFiddle . Przetestowano w Chrome 30.0 i Firefox 24.0. Jednak nie działał w Operze 12.16.

Tigran Saluev
źródło
3
To powinna być prawidłowa odpowiedź. W przypadku czystej implementacji Javascript nie trzeba modyfikować żadnego kodu HTML.
Zhang Buzz
21
Głupie pytanie, ale jak możesz później uzyskać wybrany plik?
Jay Wick
2
To niebezpieczne rozwiązanie, które może skutkować nieoczekiwanymi problemami. Na przykład niektóre przeglądarki (takie jak IE) mogą uniemożliwić przesyłanie formularzy programistycznych, jeśli plik wejściowy jest również programowo otwarty. Najlepszym sposobem rozwiązania tego problemu jest użycie CSS, a nie JavaScript.
Ray Nicholus,
3
@Charleston Niestety nie działa w niektórych przeglądarkach. Powinni jednak to zadziałać :)
Tigran Saluev
3
Od 2020 roku to rozwiązanie wydaje się najładniejsze. Przetestowałem to na BrowserStack w Edge, Safari, Opera, Firefox i Chrome. Działa we wszystkich.
V. Rubinetti
14

To właśnie działało najlepiej dla mnie (testowane na IE8, FF, Chrome, Safari).

#file-input {
  cursor: pointer;
  outline: none;
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  overflow: hidden;
  filter: alpha(opacity=0); /* IE < 9 */
  opacity: 0;
}
.input-label {
  cursor: pointer;
  position: relative;
  display: inline-block;
}
<label for="file-input" class="input-label">
  Click Me <!-- Replace with whatever text or icon you wish to use -->
  <input type="file" id="file-input">
</label>

Wyjaśnienie: Umieściłem plik wejściowy bezpośrednio nad elementem, który ma być kliknięty, więc wszelkie kliknięcia trafiałyby albo do niego, albo do jego etykiety (co powoduje wyświetlenie okna dialogowego przesyłania, tak jakbyś kliknął samą etykietę). Miałem pewne problemy z częścią przycisku domyślnego wejścia wystającą z boku etykiety, więc overflow: hiddenna wejściu i display: inline-blockna etykiecie były konieczne.

Chris
źródło
1
Zmaksymalizuj dane wejściowe i ustaw krycie na zero. To działa świetnie!
Kinorsi,
13

Co się stanie, jeśli javascript jest wyłączony na komputerze klienta? Użyj następującego rozwiązania dla wszystkich scenariuszy. Nie potrzebujesz nawet javascript / jQuery. :

HTML

<label for="fileInput"><img src="File_upload_Img"><label>
<input type="file" id="fileInput"></label>

CSS

#fileInput{opacity:0}  
body{
    background:cadetblue;
}

Objaśnienie: for="Your input Id". Zdarzenie kliknięcia wyzwalaczy domyślnie przez HTML. Więc domyślnie uruchamia zdarzenie kliknięcia, nie ma potrzeby używania jQuery / javascript. Jeśli jest to po prostu zrobione przez HTML, dlaczego używać jQuery / jScript? I nie możesz powiedzieć, czy klient wyłączył JS. Twoja funkcja powinna działać, nawet jeśli JS jest wyłączony.

Working jsFiddle (nie potrzebujesz JS, jquery)

Pratik
źródło
3
Dlaczego tło?
Solomon Ucko
12

Najpierw dodaj w nagłówku tagi:

<script>
   function showDialog(openFileDialog) {
       document.getElementById(openFileDialog).click();
   }
   function fileName(openFileDialog) {
       return document.getElementById(openFileDialog).value;
   }
   function hasFile(openFileDialog) {
       return document.getElementById(openFileDialog).value != "";
   }
   function fileNameWithoutFakePath(openFileDialog) {
       var fileName = document.getElementById(openFileDialog).value;
       return fileName.substr(fileName.lastIndexOf('\\') + 1);
   }
   function fakePathWithoutFileName(openFileDialog) {
       var fileName = document.getElementById(openFileDialog).value;
       return fileName.substr(0, fileName.lastIndexOf('\\'));
   }
</script>

jeśli masz już skrypt tagi , po prostu dodaj te funkcje powyżej.

W treści lub tagach formularza dodawanie:

<input type="file" style="display:none" id="yourDesiredOrFavoriteNameForTheNewOpenFileDialogInstance"/>

Bez względu na to, gdzie w html, jest tak , jakbyś utworzył nową instancję klasy OpenFileDialog jako zmienną globalną , której nazwa jest identyfikatorem elementu, bez względu na to, gdzie w kodzie lub xaml, ale w skrypcie lub kodzie , nie możesz wpisać jego imienia, a następnie odczytać właściwości lub wywołać funkcji, ponieważ istnieją funkcje globalne, które wykonują te, które nie są zdefiniowane w elemencie input type = "file". Wystarczy nadać tym funkcjom identyfikator ukrytego typu danych wejściowych = "plik", który jest nazwą instancji OpenFileDialog w postaci łańcucha.

Aby ułatwić sobie życie w tworzeniu wystąpień otwartych plików dialogowych do kodu HTML, możesz utworzyć funkcję, która to robi:

function createAndAddNewOpenFileDialog(name) {
     document.getElementById("yourBodyOrFormId").innerHtml += "<input type='file' style='display:none' id='" + name + "'/>"
}

a jeśli chcesz usunąć okno dialogowe otwierania pliku, możesz wykonać i użyć następującej funkcji:

function removeOpenFileDialog(name) {
    var html = document.getElementById("yourBodyOrFormId").innerHtml;
    html = html.replace("<input type='file' style='display:none' id='" + name + "'/>", "");
    document.getElementById("yourBodyOrFormId").innerHtml = html;
}

ale zanim usuniesz okno dialogowe otwierania pliku, upewnij się, że istnieje, tworząc i używając następującej funkcji:

function doesOpenFileDialogExist(name) {
    return document.getElementById("yourBodyOrFormId").innerHtml.indexOf("<input type='file' style='display:none' id='" + name + "'/>") != -1
}

a jeśli nie chcesz tworzyć i dodawać okien dialogowych otwierania plików w treści lub tagów formularza w html, ponieważ jest to dodawanie ukrytego typu input = "file" s, możesz to zrobić w skrypcie używając powyższej funkcji tworzenia :

function yourBodyOrFormId_onload() {
    createAndAddNewOpenFileDialog("openFileDialog1");
    createAndAddNewOpenFileDialog("openFileDialog2");
    createAndAddNewOpenFileDialog("openFileDialog3");
    createAndAddNewOpenFileDialog("File Upload");
    createAndAddNewOpenFileDialog("Image Upload");
    createAndAddNewOpenFileDialog("bla");
    //etc and rest of your code
}

Upewnij się, że w pobliżu tagu body lub formularza dodano:

onload="yourBodyOrFormId_onload()"

Nie musisz robić tego wiersza powyżej, jeśli już to zrobiłeś.

WSKAZÓWKA: Możesz dodać do swojego projektu lub witryny nowy plik JScript, jeśli jeszcze go nie masz, aw tym pliku możesz umieścić wszystkie funkcje okna dialogowego otwierania pliku z dala od tagów skryptu i strony HTML lub formularza internetowego i użyć je w swoim html lub stronie formularza internetowego z tego pliku JScript, ale nie zapomnij wcześniej połączyć html lub strony formularza internetowego z plikiem JScript oczywiście. Możesz to zrobić po prostu przeciągając plik JScript na swoją stronę HTML w formacie głowietagi. Jeśli Twoja strona jest formularzem internetowym, a nie prostym html, i nie masz tagów head, umieść ją w dowolnym miejscu, aby działała. Nie zapomnij zdefiniować zmiennej globalnej w tym pliku JScript, której wartością będzie treść lub identyfikator formularza jako ciąg. Po połączeniu pliku JScript ze stroną html lub formularzem internetowym możesz załadować zdarzenie treści formularza, ustawić wartość tej zmiennej na swój identyfikator treści lub formularza. Następnie w pliku JScript nie musisz już podawać dokumentowi identyfikatora treści lub formy jednej strony, po prostu nadaj mu wartość tej zmiennej. Możesz wywołać tę zmienną bodyId lub formId lub bodyOrFormId lub dowolną inną nazwę.

Powodzenia!


źródło
1
Najlepiej nie modyfikować bezpośrednio innerHTML.
Solomon Ucko
9

Najprostszy sposób:

#file-input {
  display: none;
}
<label for="file-input">
  <div>Click this div and select a file</div>
</label>
<input type="file" id="file-input"/>

Co ważne, użycie display: nonezapewnia, że ​​żadne miejsce nie zostanie zajęte przez ukryte wejście pliku (co się dzieje przy użyciu opacity: 0).

Karol Selak
źródło
3

AFAIK nadal potrzebujesz <input type="file">elementu, wtedy możesz użyć niektórych rzeczy z dziwnego trybu, aby go nadać stylowi

Dan F
źródło
2

Jedynym bez <input type="file">jest osadzenie przezroczystego filmu flash na div. Następnie można użyć zdarzenia kliknięcia wygenerowanego przez użytkownika (zgodnego z nowymi regułami bezpieczeństwa Flash 10), aby wywołać wywołanie Flash FileReference.browse .

Oferuje dodatkową zależność w porównaniu z dziwacznym sposobem, ale w zamian otrzymujesz znacznie więcej zdarzeń (takich jak wbudowane zdarzenia postępu).

Martijn Laarman
źródło
-1

Może wykorzystać

$('<input type="file" />').click()
Hamed Zakery Miab
źródło
w moim przypadku powoduje to automatyczne przekierowanie na tę samą stronę, na której nastąpiło pierwotne kliknięcie - powodując przeładowanie całej strony i utratę wszystkich danych wprowadzonych wcześniej na stronie.
Muntasir