JQuery триггер файла ввода


163

Я пытаюсь вызвать окно загрузки (кнопка просмотра), используя jQuery.
Метод, который я попробовал сейчас:

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

Но это не похоже на работу. Пожалуйста помоги. Спасибо.


Вместо этого вы можете попробовать что-то подобное .
Киртан

19
Там нет способа сделать это? Как угнетающе.
Маркус Даунинг

Действительно удручает, и это вызвано «щелчком», серьезно? Я очень предпочитаю Flash / AS3 с его тесным API и надежной моделью безопасности, которая позволяет вызывать FileReference.browse только из обработчика событий ввода, инициированного пользователем. Кроме того, ввод HTML-файла является уродливым и не стилевым (это просто тег ввода, так много для разделения контента и стиля), поэтому вам нужно создать новую кнопку «просмотр», которая также активируется событием click ... который вы должны перенаправить на вход файла в виде щелчка ... что может привести к бесконечной рекурсии в зависимости от размещения элемента и специфики делегирования события.
Triynko

К сожалению, использование Flash становится все менее и менее жизнеспособным, учитывая его постоянные проблемы с безопасностью и рост числа блокировщиков контента.
Тим

Ответы:


195

Это связано с ограничением безопасности.

Я обнаружил, что ограничение безопасности действует только тогда, когда для <input type="file"/>него установлено значение display:none;или установлено visbilty:hidden.

Таким образом , я пытался позиционировать его вне области просмотра, установив position:absoluteи top:-100px;и вуаля она работает.

см. http://jsfiddle.net/DSARd/1/

Назовите это взломать.

Надеюсь, что это работает для вас.


4
не работает в ff 3.6. работает в хроме и даже в т.е. 8, хотя :)
AyKarsi

4
Есть ли на msdn документация об ограничении безопасности?
eomeroff

2
Прекрасно работает. В любом случае я думаю, что безопаснее установить left: -100px;. Вы никогда не знаете, как долго может быть страница
Alter Lagos

+1 Это реальный ответ (и хорошее решение). Будет ли у кого-нибудь ссылка на документацию, где это прямо указано?
Контур

9
Вы также можете просто установить непрозрачность на 0
Стюарт

109

это сработало для меня:

JS:

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

HTML:

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

CSS:

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

>>> Еще один, который работает кросс-браузер: <<<

Идея состоит в том, что вы накладываете невидимую огромную кнопку «Обзор» поверх своей кнопки. Поэтому, когда пользователь нажимает вашу пользовательскую кнопку, он на самом деле нажимает кнопку «Обзор» собственного поля ввода.

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());
    });
});

Есть один недостаток: если сделать кнопку шире, то в IE9 / 10 невидимая кнопка загрузки состоит из правой кнопки и левого текстового поля. На это вы должны дважды щелкнуть. В этом случае попробуйте установить размер шрифта даже больше, чем 100px;
Юнзен

Это работает даже в Chrome 53. Тем не менее, heightпредлагается изменить наheight: 100%
Raptor

Второй даже работает в Safari на iOS. Очень хорошо!
Яннис

71

Вы можете использовать элемент LABEL ex.

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

Это вызовет входной файл


5
Почему это не принятый ответ? Это самый простой способ, который не требует фанки javascript.
Tomitrescak

@tomitrescak ОП не ждет получения лучшего ответа.
Махи

9
Имейте в виду, что ответ был опубликован через 7 лет после того, как вопрос был задан.

1
Лучший ответ и в 2018 году.
masoomyf

1
Лучший ответ и для 2019 года;)
guillaumepotier

17

У меня это работает (= проверено) в IE8 +, последние FF и Chrome:

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

Клавиша фокусируется перед нажатием кнопки (иначе хром игнорирует ее).

Примечание: вам НЕОБХОДИМО, чтобы ваш вход отображался и отображался (как в, так display:noneи нет visibility:hidden). Я предлагаю (как и многие другие ранее) абсолютно позиционировать вход и выбросить его за пределы экрана.

#uploadInput {
    position: absolute;
    left: -9999px;
}

1
+1 за это. Я также заметил, что вы можете скрыть окружающий элемент, но не кнопку ввода файла, затем показать окружающий элемент, сфокусировать кнопку, активировать ее, а затем скрыть кнопку.
Стево

10

Проверьте мою скрипку.

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>


9

adardesign обнаружил, что элемент ввода файла игнорируется, когда он скрыт. Я также заметил, что многие люди смещают размер элемента до 0 или выталкивают его за пределы с помощью настроек позиционирования и переполнения. Это все прекрасные идеи.
Альтернативный способ, который также, кажется, работает отлично, это просто установить непрозрачность на 0 . Тогда вы всегда можете просто установить положение, чтобы оно не смещало другие элементы, как это делает Hide. Просто кажется немного ненужным смещать элемент почти на 10 тысяч пикселей в любом направлении.

Вот небольшой пример для тех, кто хочет один:

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);
}

7

Ради любопытства вы можете делать что-то, что хотите, динамически создавая форму загрузки и входной файл, не добавляя его в дерево 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();
});

Нет необходимости добавлять uploadForm в DOM.


1
СПАСИБО! Я искал это в течение 20 минут!
Labo

5

Правильный код:

<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>


4

На самом деле, я нашел очень простой способ для этого, а именно:

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

Таким образом, ваше поле входного файла может иметь CSS свойства отображения на ни и еще выиграть сделку :)


на медленном компьютере он может щелкнуть по экрану. Не оптимальное решение
Дмитрий Ефименко

4

Слишком поздно, чтобы ответить, но я думаю, что эта минимальная установка работает лучше всего. Я тоже ищу то же самое.

  <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

демонстрация кнопок ввода файла начальной загрузки


никогда не поздно ответить;)
AGuyCalledGerald

Спустя несколько лет все еще лучше ответить ИМО
DimmuR

4

Это очень старый вопрос, но, к сожалению, этот вопрос все еще актуален и требует решения.

(Удивительно простое) решение, которое я придумала, состоит в том, чтобы «скрыть» поле ввода реального файла и обернуть его тегом LABEL (для улучшения может быть основан на Bootstrap и HTML5).

See here:Пример кода здесь

Таким образом, поле ввода реального файла невидимо, и все, что вы видите, это настраиваемая «кнопка», которая на самом деле является измененным элементом LABEL. Когда вы нажимаете на этот элемент LABEL, появляется окно для выбора файла, и файл, который вы выбираете, перейдет в поле ввода реального файла.

Кроме того, вы можете манипулировать внешним видом и поведением по своему усмотрению (например: получить имя выбранного файла из входного файла файла после выбранного и показать его где-нибудь. Элемент LABEL не делает этого автоматически, конечно. Я обычно просто помещаю это в LABEL, как его текстовое содержание).

Осторожно, хотя! Манипулирование внешним видом и поведением ограничено тем, что вы можете себе представить и придумать. ;-) ;-)


3

Мне удалось с помощью простого $ (...). Click (); с JQuery 1.6.1


1
Хм, любопытно, как вы это сделали, на моем сайте (www.iscriptdesign.com) выполнение $ ('file: input'). Click () ничего не делает, равно как и $ ('file: input'). Trigger (' нажмите ');
Др Джерри

Вот полный пример: <input type = "file" id = "picBrowse" ... и затем $ ('# picBrowse'). Click ();
Валентин Галеа

Я тестировал на cr (не уверен, какая версия) на Mac OS, хотя работает на FF 4 на XP. Спасибо!
Д-р Джерри


2

У меня были проблемы с пользовательской проверкой на стороне клиента, <input type="file"/>когда я использовал поддельную кнопку для ее запуска, и решение @Guillaume Bodi сработало для меня (также с opacity: 0;Chrome)

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

и стиль CSS для загрузки ввода

#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;
}

1

Попробуйте это, это взломать. Положение: абсолютное значение для Chrome, а триггер («изменение») для 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');
});

Обратите внимание, что $.browserне рекомендуется в более новых версиях jQuery
Кевин Бил

1

Моя проблема была немного другой на iOS 7. Оказалось, что FastClick вызывал проблемы. Все, что мне нужно было сделать, это добавить class="needsclick"в мою кнопку.


0

Это, вероятно, лучший ответ, принимая во внимание проблемы кроссбраузерности.

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">

0

Я думаю, я понимаю вашу проблему, потому что у меня есть подобное. Таким образом, у тега <label>есть атрибут для, вы можете использовать этот атрибут, чтобы связать ваш ввод с type = "file". Но если вы не хотите активировать это с помощью этого ярлыка, потому что какое-то правило вашего макета, вы можете сделать так.

$(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>

Конечно, вы адаптируете это для своих собственных целей и макета, но я знаю, что это более простой способ заставить его работать !!


-1

Основываясь на ответе Гийома Боди, я сделал это:

$('.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();
});

это означает, что он скрыт для начала и затем отображается для триггера, а затем снова скрыт сразу.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.