Wejście pliku wyzwalacza jQuery

163

Próbuję wywołać okno przesyłania (przycisk przeglądania) za pomocą jQuery.
Metoda, którą teraz wypróbowałem, to:

$('#fileinput').trigger('click');   

Ale to nie działa. Proszę pomóż. Dziękuję Ci.

Alec Smart
źródło
Można spróbować czegoś podobnego to zamiast.
Kirtan
19
Nie da się tego zrobić? Jakie to przygnębiające.
Marcus Downing
Rzeczywiście przygnębiające i wywoływane przez „kliknięcie”, poważnie? Zdecydowanie wolę Flash / AS3, z jego ścisłym API i silnym modelem bezpieczeństwa, który umożliwia wywoływanie FileReference.browse tylko z modułu obsługi zdarzeń wejściowych zainicjowanego przez użytkownika. Co więcej, dane wejściowe w pliku HTML są brzydkie i nie można ich napisać (to tylko znacznik wejściowy, tyle dla oddzielenia treści i stylu), więc musisz utworzyć nowy przycisk `` przeglądaj '', który jest również aktywowany przez zdarzenie kliknięcia ... które musisz przekazać do pliku wejściowego jako kliknięcie ... co może prowadzić do nieskończonej rekurencji w zależności od umiejscowienia elementu i specyfiki delegowania zdarzenia.
Triynko
Niestety, używanie Flasha staje się coraz mniej opłacalne, biorąc pod uwagę jego ciągłe problemy z bezpieczeństwem i wzrost liczby blokerów treści.
Tim

Odpowiedzi:

195

Wynika to z ograniczeń bezpieczeństwa.

Dowiedziałem się, że ograniczenie bezpieczeństwa występuje tylko wtedy, gdy <input type="file"/>jest ustawione display:none;lub jest visbilty:hidden.

Spróbowałem więc umieszczenie go na zewnątrz przez ustawienie rzutni position:absolutei top:-100px;i voilà to działa.

zobacz http://jsfiddle.net/DSARd/1/

nazwij to hackem.

Mam nadzieję, że to działa dla Ciebie.

adardesign
źródło
4
nie działa w ff 3.6. działa w chrome a nawet w np. 8 :)
AyKarsi
4
Czy w witrynie msdn jest dostępna dokumentacja dotycząca ograniczenia zabezpieczeń?
eomeroff
2
Działa świetnie. W każdym razie myślę, że bezpieczniej jest ustawić left: -100px;. Nigdy nie wiadomo, jak długo może być stroną
Alter Lagos
+1 To jest prawdziwa odpowiedź (i dobre rozwiązanie). Czy ktoś miałby link do dokumentacji, w której jest to wyraźnie określone?
kontur
9
możesz również ustawić krycie na 0
Stuart
109

to zadziałało dla mnie:

JS:

$('#fileinput').trigger('click'); 

HTML:

<div class="hiddenfile">
  <input name="upload" type="file" id="fileinput"/>
</div>

CSS:

.hiddenfile {
 width: 0px;
 height: 0px;
 overflow: hidden;
}

>>> Kolejny, który działa w różnych przeglądarkach: <<<

Chodzi o to, aby nałożyć niewidoczny ogromny przycisk „Przeglądaj” na przycisk niestandardowy. Kiedy więc użytkownik kliknie przycisk niestandardowy, w rzeczywistości klika przycisk „Przeglądaj” w natywnym polu wejściowym.

JS Fiddle: http://jsfiddle.net/5Rh7b/

HTML:

<div id="mybutton">
  <input type="file" id="myfile" name="upload"/>
  Click Me!
</div>

CSS:

div#mybutton {

  /* IMPORTANT STUFF */
  overflow: hidden;
  position: relative;   

  /* SOME STYLING */
  width:  50px;
  height: 28px;
  border: 1px solid green;
  font-weight: bold
  background: red;
}

div#mybutton:hover {
  background: green;
}

input#myfile {
  height: 30px;
  cursor: pointer;
  position: absolute;
  top: 0px;
  right: 0px;
  font-size: 100px;
  z-index: 2;

  opacity: 0.0; /* Standard: FF gt 1.5, Opera, Safari */
  filter: alpha(opacity=0); /* IE lt 8 */
  -ms-filter: "alpha(opacity=0)"; /* IE 8 */
  -khtml-opacity: 0.0; /* Safari 1.x */
  -moz-opacity: 0.0; /* FF lt 1.5, Netscape */
}

JavaScript:

$(document).ready(function() {
    $('#myfile').change(function(evt) {
        alert($(this).val());
    });
});
sanki
źródło
Jest jedna wada, jeśli rozszerzysz przycisk, to w IE9 / 10 niewidoczny przycisk przesyłania składa się z prawego przycisku i lewego pola tekstowego. Na to musisz dwukrotnie kliknąć. W takim przypadku spróbuj ustawić rozmiar czcionki nawet większy niż 100px;
yunzen
Działa to nawet w Chrome 53. Jednak heightsugeruje się zmianę naheight: 100%
Raptor
Drugi działa nawet w Safari na iOS. Bardzo dobrze!
Jannis
71

Możesz użyć elementu LABEL np.

<div>
    <label for="browse">Click Me</label>
    <input type="file" id="browse" name="browse" style="display: none">//
</div>

Spowoduje to uruchomienie pliku wejściowego

Jhon Rey
źródło
5
Dlaczego nie jest to akceptowana odpowiedź? To najprostszy sposób, który nie wymaga funky JavaScript.
tomitrescak
@tomitrescak OP nie czeka na uzyskanie najlepszej odpowiedzi.
Mahi,
9
Pamiętaj, że odpowiedź została opublikowana 7 lat po zadaniu pytania.
1
Najlepsza odpowiedź również w 2018 roku.
masoomyf
1
Najlepsza odpowiedź również na 2019 rok;)
guillaumepotier
17

Mam to działające (= testowane) w IE8 +, najnowsze FF i chrome:

$('#uploadInput').focus().trigger('click');

Klawisz ustawia ostrość przed kliknięciem (w przeciwnym razie chrome go ignoruje).

Uwaga: MUSISZ mieć wyświetlane i widoczne dane wejściowe (tak jak w, nie display:nonei nie visibility:hidden). Proponuję (jak wielu innych wcześniej), aby bezwzględnie ustawić wejście i wyrzucić je z ekranu.

#uploadInput {
    position: absolute;
    left: -9999px;
}
Potężna gumowa kaczka
źródło
1
+1 za to. Zauważyłem również, że można ukryć otaczający element, ale nie przycisk wprowadzania pliku, a następnie pokazać otaczający element, wyostrzyć przycisk, aktywować go, a następnie ukryć przycisk.
Stevo
10

Sprawdź moje skrzypce.

http://jsfiddle.net/mohany2712/vaw8k/

.uploadFile {
  visibility: hidden;
}

#uploadIcon {
  cursor: pointer;
}
<body>
  <div class="uploadBox">
    <label for="uploadFile" id="uploadIcon">
      <img src="http://upload.wikimedia.org/wikipedia/commons/thumb/3/34/Icon_-_upload_photo_2.svg/512px-Icon_-_upload_photo_2.svg.png"  width="20px" height="20px"/>
    </label>
    <input type="file" value="upload" id="uploadFile" class="uploadFile" />
  </div>
</body>

Mohan
źródło
9

adardesign przyłapał go na ignorowaniu elementu wejściowego pliku, gdy jest on ukryty. Zauważyłem również, że wiele osób zmienia rozmiar elementu na 0 lub wypycha go poza granice za pomocą regulacji pozycjonowania i przepełnienia. To wszystko są świetne pomysły.
Alternatywnym sposobem, który wydaje się działać doskonale, jest po prostu ustawienie krycia na 0 . Wtedy zawsze możesz po prostu ustawić pozycję, aby nie przesuwać innych elementów, tak jak robi to hide. Przesunięcie elementu o prawie 10 000 pikseli w dowolnym kierunku wydaje się po prostu trochę niepotrzebne.

Oto mały przykład dla tych, którzy go chcą:

input[type='file']{
    position:absolute;
    opacity:0;
    /* For IE8 "Keep the IE opacity settings in this order for max compatibility" */
    -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
    /* For IE5 - 7 */
    filter: alpha(opacity=0);
}
eyegropram
źródło
7

Z ciekawości możesz zrobić coś takiego, jak chcesz, dynamicznie tworząc formularz przesyłania i plik wejściowy, bez dodawania ich do drzewa DOM:

$('.your-button').on('click', function() {
    var uploadForm = document.createElement('form');
    var fileInput = uploadForm.appendChild(document.createElement('input'));

    fileInput.type = 'file';
    fileInput.name = 'images';
    fileInput.multiple = true;

    fileInput.click();
});

Nie ma potrzeby dodawania uploadForm do DOM.

jairhumberto
źródło
1
DZIĘKUJĘ CI! Szukałem tego od 20 minut!
Labo,
5

Prawidłowy kod:

<style>
    .upload input[type='file']{
        position: absolute;
        float: left;
        opacity: 0; /* For IE8 "Keep the IE opacity settings in this order for max compatibility" */
        -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; /* For IE5 - 7 */
        filter: alpha(opacity=0);
        width: 100px; height: 30px; z-index: 51
    }
    .upload input[type='button']{
        width: 100px;
        height: 30px;
        z-index: 50;
    }
    .upload input[type='submit']{
        display: none;
    }
    .upload{
        width: 100px; height: 30px
    }
</style>
<div class="upload">
    <input type='file' ID="flArquivo" onchange="upload();" />
    <input type="button" value="Selecionar" onchange="open();" />
    <input type='submit' ID="btnEnviarImagem"  />
</div>

<script type="text/javascript">
    function open() {
        $('#flArquivo').click();
    }
    function upload() {
        $('#btnEnviarImagem').click();
    }
</script>
E9 Sistemas
źródło
4

To celowo i zgodnie z projektem. To kwestia bezpieczeństwa.

Chad Grant
źródło
4

Właściwie znalazłem na to naprawdę prostą metodę:

$('#fileinput').show().trigger('click').hide();   

W ten sposób twoje pole wejściowe pliku może mieć właściwość css wyświetlaną na none i nadal wygrywać transakcję :)

skywlkr
źródło
na wolniejszej maszynie może to być migotanie na ekranie. Nie jest to optymalne rozwiązanie
Dmitry Efimenko
4

Jest za późno na odpowiedź, ale myślę, że ta minimalna konfiguracja działa najlepiej. Ja też szukam tego samego.

  <div class="btn-file">
     <input type="file" class="hidden-input">
     Select your new picture
  </div>

// css

.btn-file {
  display: inline-block;
  padding: 8px 12px;
  cursor: pointer;
  background: #89f;
  color: #345;
  position: relative;
  overflow: hidden;
}

.btn-file input[type=file] {
  position: absolute;
  top: 0;
  right: 0;
  min-width: 100%;
  min-height: 100%;
  filter: alpha(opacity=0);
  opacity: 0;
  cursor: inherit;
  display: block;
}

jsbin

demo przycisków wprowadzania pliku bootstrap

Natwar Singh
źródło
nigdy nie jest za późno na odpowiedź;)
AGuyCalledGerald
Kilka lat później nadal najlepsza odpowiedź IMO
DimmuR
4

To bardzo stara kwestia, ale niestety ta kwestia jest nadal aktualna i wymaga rozwiązania.

(Zaskakująco proste) rozwiązanie, które wymyśliłem, polega na „ukryciu” rzeczywistego pola wejściowego pliku i zawinięciu go w znacznik LABEL (może być oparty na Bootstrap i HTML5, w celu ulepszenia).

See here:Przykładowy kod tutaj

W ten sposób rzeczywiste pole wejściowe pliku jest niewidoczne, a wszystko, co widzisz, to dostosowany „przycisk”, który w rzeczywistości jest zmodyfikowanym elementem LABEL. Po kliknięciu tego elementu ETYKIETA pojawi się okno wyboru pliku, a wybrany plik przejdzie do pola wejściowego rzeczywistego pliku.

Ponadto możesz dowolnie manipulować wyglądem i zachowaniem (na przykład: pobrać nazwę wybranego pliku z pliku wejściowego pliku, po jego wybraniu i pokazać go gdzieś. Element LABEL nie robi tego automatycznie, oczywiście. Zwykle po prostu umieszczam go wewnątrz LABEL, jako jego treść tekstową).

Uważaj jednak! Manipulacja wyglądem i zachowaniem jest ograniczona do wszystkiego, co możesz sobie wyobrazić i o czym pomyśleć. ;-) ;-)

TheCuBeMan
źródło
3

Udało mi się za pomocą prostego $ (...). Click (); z JQuery 1.6.1

Valentin Galea
źródło
1
Hmm ciekawy, jak to zrobiłeś, na mojej stronie (www.iscriptdesign.com) wykonując $ ('file: input'). Click () nic nie robi, ani $ ('file: input'). Trigger (' Kliknij');
dr jerry
Oto pełny przykład: <input type = "file" id = "picBrowse" ... a następnie $ ('# picBrowse'). Click ();
Valentin Galea
Testowałem na cr (nie wiem, która wersja) na Mac OS, działa jednak na FF 4 na XP. Dzięki!
dr jerry
3

albo po prostu

$(':input[type="file"]').show().click().hide();
Otvazhnii
źródło
2

miałem problemy z niestandardową walidacją po stronie klienta <input type="file"/>podczas używania fałszywego przycisku, aby go uruchomić, a rozwiązanie @Guillaume Bodi działało dla mnie (również opacity: 0;na Chrome)

$("#MyForm").on("click", "#fake-button", function () {
        $("#uploadInput").focus().trigger("click");
    });

i styl CSS do przesyłania danych

#uploadInput {
opacity: 0.0; 
filter: alpha(opacity=0); /* IE lt 8 */
-ms-filter: "alpha(opacity=0)"; /* IE 8 */
-khtml-opacity: 0.0; /* Safari 1.x */
-moz-opacity: 0.0;
}
Amin K.
źródło
1

Spróbuj tego, to hack. pozycja: bezwzględna dotyczy przeglądarki Chrome, a wyzwalacz („zmiana”) dotyczy przeglądarki IE.

var hiddenFile = $("<input type=\"file\" name=\"file\" id=\"file1\" style=\"position:absolute;left:-9999px\" />");
$('body').append(hiddenFile);

$('#aPhotoUpload').click(function () {
    hiddenFile.trigger('click');
    if ($.browser.msie)
        hiddenFile.trigger('change');
});

hiddenFile.change(function (e) {
    alert('TODO');
});
thinpiglin
źródło
Zwróć na to uwagę $.browser jest przestarzały w nowszych wersjach jQuery
Kevin Beal
1

Mój problem był trochę inny na iOS 7. Okazuje się, że FastClick powodował problemy. Wszystko, co musiałem zrobić, to dodać class="needsclick"do mojego przycisku.

Dex
źródło
0

To prawdopodobnie najlepsza odpowiedź, biorąc pod uwagę problemy z różnymi przeglądarkami.

CSS:

#file {
  opacity: 0;
  width: 1px;
  height: 1px;
}

JS:

$(".file-upload").on('click',function(){
   $("[name='file']").click();
});

HTML:

<a class="file-upload">Upload</a>
<input type="file" name="file">
Eddsters
źródło
0

Myślę, że rozumiem twój problem, bo mam podobny. Więc tag <label>ma atrybut dla, możesz użyć tego atrybutu, aby połączyć swoje wejście z type = "file". Ale jeśli nie chcesz aktywować tego za pomocą tej etykiety, ponieważ jakaś reguła twojego układu, możesz zrobić w ten sposób.

$(document).ready(function(){
  var reference = $(document).find("#main");
  reference.find(".js-btn-upload").attr({
     formenctype: 'multipart/form-data'
  });
  
  reference.find(".js-btn-upload").click(function(){
    reference.find("label").trigger("click");
  });
  
});
.hide{
  overflow: hidden;
  visibility: hidden;
  /*Style for hide the elements, don't put the element "out" of the screen*/
}

.btn{
  /*button style*/
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<div id="main">
<form enctype"multipart/formdata" id="form-id" class="hide" method="post" action="your-action">
  <label for="input-id" class="hide"></label>
  <input type="file" id="input-id" class="hide"/>
</form>

<button class="btn js-btn-upload">click me</button>
</div>

Oczywiście dostosujesz to do własnego celu i układu, ale to jest łatwiejszy sposób, w jaki wiem, aby to działało !!

Leonardo Lindroth
źródło
-1

Na podstawie odpowiedzi Guillaume Bodi zrobiłem to:

$('.fileinputbar-button').on('click', function() {
    $('article.project_files > header, article.upload').show();
    $('article.project_files > header, article.upload header').addClass('active');
    $('.file_content, article.upload .content').show();
    $('.fileinput-button input').focus().click();
    $('.fileinput-button').hide();
});

co oznacza, że ​​jest ukryty na początku, a następnie wyświetlany dla wyzwalacza, a następnie natychmiast ponownie ukryty.

Stevo
źródło