Диалоговое окно открытия файла в JavaScript


109

Мне нужно решение для отображения диалогового окна открытия файла в HTML при нажатии div. Диалоговое окно открытия файла должно открываться при divнажатии.

Я не хочу отображать поле входного файла как часть HTML-страницы. Он должен отображаться в отдельном диалоге, который не является частью веб-страницы.


4
Предупреждение - это не файл-диалог? - Можете уточнить, о чем спрашиваете?
LiamB

3
я думаю, он говорит, что хочет стандартное всплывающее окно с открытыми файлами
Валентин Роше

1
Мне нужно открыть диалоговое окно с файлом при нажатии на div. это должно быть похоже на предупреждение, которое не является частью веб-страницы
ArK

Ответы:


52

Вот хороший

Демо Fine Uploader

Это <input type='file' />сам по себе контроль. Но поверх него помещается div, и для этого применяются стили css. Непрозрачность файлового элемента управления установлена ​​на 0, поэтому кажется, что диалоговое окно открывается при нажатии на div.


1
есть ли способ управлять отображаемыми файлами с помощью javascript ... скажем, я хотел открыть диалоговое окно с файлом и просто хотел отобразить расширение файла с .pdf ..
Ajax3.14,

1
@ Ajax3.14 в новых браузерах есть объект FileReader, в старых браузерах вы должны использовать это значение и искать расширение файла.
Vicary

2
@ Ajax3.14 Нет необходимости использовать FileReader или расширения синтаксического анализа. Многие браузеры поддерживают атрибут accept при вводе файлов. Это позволяет ограничить типы файлов, отображаемые в диалоговом окне браузера файлов. Fine Uploader предоставляет доступ к этой функции через свойство acceptFiles параметра проверки. Дополнительные сведения см. В разделе проверки документации по параметрам . Обратите внимание, что атрибут accept не поддерживается в IE9 или более ранних версиях.
Ray Nicholus

1
почему это хорошо? это вообще хорошая практика? не должно быть что-то вроде этого: stackoverflow.com/a/18659941/915865 ?
Кэт Лим Руис,

1
@KatLimRuiz Нет, ответ, на который вы указали, не является хорошим решением. Это приведет к тому, что IE выдаст ошибку, если вы также отправите связанную форму программно.
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">

для IE добавьте это:

$("#logo").css('filter','alpha(opacity = 0');

3
Почему вы возвращаете false в обработчике кликов #select_logo?
Сетиш

4
Это не приведет к ошибке 404, а просто попытается перейти на текущую страницу с добавленным # в конце. Это заставит страницу прыгнуть вверх. Так что хорошо быть там, только по другой причине :)
манаво

3
Хотя я еще не проверил его достаточно, "видимость: скрытый;" кажется более совместимым. Кроме того, несмотря на opacity: 0, событие click сработает, если щелкнет «невидимый» элемент, а visibility: hidden - нет.
Aron

MDN указывает, что этого document.getElementById("logo").click()достаточно. Также они показывают другой способ «перетащить и оставить». developer.mozilla.org/en-US/docs/Web/API/File/…
Эрик,

2
Вам следует преобразовать это в обычный Javascript, JQuery не логично использовать в таком маленьком проекте ^ _ ^
Mister SirCode

57

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


РЕДАКТИРОВАТЬ: в Safari inputотключается при скрытии с помощью display: none. Лучше было бы использовать position: fixed; top: -100em.


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

При желании вы можете идти «правильный путь» , используя forв labelуказывающей на idвходных данных , как это:

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

4
это работает как шарм, однако вот несколько рекомендаций: 1. <input>тег должен иметь nameатрибут; 2. Если forатрибут указан, <input>для тега файла потребуется расширение id.
Raptor

5
Simplicity is the ultimate sophistication
ncubica

2
здорово! он работает как шарм даже с фоновым изображением или заставляет метку получать запускаемый javascript щелчок. Спасибо!
Лео Номдеду,

2
Кстати, кто-то указал на одну уловку с этим решением: в Safari входы, скрытые с помощью display: none, отключены. Обходной путь заключается в использовании другого подхода, чтобы скрыть ввод. Я обновлю ответ, чтобы отразить это.
JP de la Torre

1
@JPdelaTorre Было бы лучше, если бы вы использовали opacity: 0 вместо того, чтобы скрыть ввод.
Адриан

40

На самом деле вам не нужно все это с непрозрачностью, видимостью, <input>стилем и т. Д. Просто взгляните:

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

Демо на jsFiddle . Протестировано в Chrome 30.0 и Firefox 24.0. Однако не работал в Opera 12.16.


3
Это должен быть правильный ответ. Для реализации на чистом Javascript не нужно изменять HTML-код.
Чжан Базз

21
Глупый вопрос, а как потом получить выбранный файл?
Jay Wick

2
Это опасное решение, которое может привести к неожиданным проблемам. Например, некоторые браузеры (такие как IE) могут препятствовать программной отправке формы, если входной файл также открывается программно. Лучший способ решить эту проблему - использовать CSS, а не JavaScript.
Ray Nicholus

3
@Charleston К сожалению, в некоторых браузерах это не работает. Но они должны заставить это работать :)
Тигран Салуев

3
По состоянию на 2020 год это решение кажется самым хорошим. Протестировал его на BrowserStack в Edge, Safari, Opera, Firefox и Chrome. Работает во всех.
В. Рубинетти,

14

Это то, что у меня сработало лучше всего (протестировано в 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>

Объяснение: я разместил ввод файла непосредственно над элементом, на который нужно щелкнуть, поэтому любые щелчки будут либо на нем, либо на его метке (которая вызывает диалоговое окно загрузки, как если бы вы щелкнули саму метку). У меня были некоторые проблемы с тем, что часть кнопок ввода по умолчанию торчала из стороны метки, поэтому overflow: hiddenна входе и display: inline-blockна этикетке были необходимы.


1
Увеличьте вход и установите непрозрачность на ноль. Это прекрасно работает!
Kinorsi

13

Что делать, если на клиентском компьютере отключен javascript? Используйте следующее решение для всех сценариев. Вам даже не нужен 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;
}

Объяснение: for="Your input Id". По умолчанию запускает событие щелчка по HTML. Таким образом, он по умолчанию запускает событие щелчка, нет необходимости в jQuery / javascript. Если это просто делается с помощью HTML, зачем использовать jQuery / jScript? И вы не можете сказать, отключил ли клиент JS. Ваша функция должна работать, даже если JS отключен.

Рабочий jsFiddle (вам не нужны JS, jquery)


3
Почему фон?
Соломон Учко

12

Сначала добавьте в заголовок теги:

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

если у вас уже есть сценарий теги , просто добавьте эти функции выше.

В теги тела или формы добавление:

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

Независимо от того, где в вашем html, это похоже на то, что вы создали новый экземпляр класса типа OpenFileDialog как глобальную переменную, имя которой является идентификатором элемента, независимо от того, где в вашем коде или xaml, но в вашем скрипте или коде , вы не можете ввести его имя, а затем прочитать свойство или вызвать функцию, потому что существуют глобальные функции, которые выполняют те функции, которые не определены в элементе input type = "file". Вам просто нужно дать этим функциям идентификатор скрытого ввода type = "file", который является именем экземпляра OpenFileDialog в виде строки.

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

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

и если вы хотите удалить диалог открытия файла, вы можете создать и использовать следующую функцию:

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

но перед тем, как удалить диалоговое окно открытия файла, убедитесь, что он существует, выполнив и используя следующую функцию:

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

и если вы не хотите создавать и добавлять диалоговые окна открытия файлов в теги body или form в html, потому что это добавляет скрытый input type = "file" s, то вы можете сделать это в сценарии, используя функцию создания выше :

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

Убедитесь, что рядом с тегами тела или формы вы добавили:

onload="yourBodyOrFormId_onload()"

Вам не нужно делать эту строку выше, если вы это уже сделали.

СОВЕТ: вы можете добавить в свой проект или веб-сайт новый файл JScript, если у вас его еще нет, и в этом файле вы можете поместить все функции диалога открытия файла подальше от тегов скрипта и страницы HTML или веб-формы и использовать их на странице html или веб-формы из этого файла JScript, но не забудьте перед этим связать страницу html или веб-формы с файлом JScript. Вы можете сделать это, просто перетащив файл JScript на свою html-страницу в голове.теги. Если ваша страница представляет собой веб-форму, а не простой html, и у вас нет тегов заголовков, поместите ее в любое место, чтобы она могла работать. Не забудьте определить глобальную переменную в этом файле JScript, значением которой будет ваше тело или идентификатор формы в виде строки. После того, как вы связали файл JScript со страницей html или веб-формы, вы можете загрузить событие тела формы, установить значение этой переменной для вашего тела или идентификатора формы. Затем в файле JScript вам больше не нужно указывать документу идентификатор тела или формы одной страницы, просто укажите значение этой переменной. Можно назвать эту переменную bodyId или FormID или bodyOrFormId или любое другое имя , которое вы хотите.

Удачи чувак!


1
Лучше не изменять напрямую innerHTML.
Соломон Учко,

9

Самый простой способ:

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

Что важно, использование display: noneгарантирует, что не будет места для ввода скрытого файла (что происходит при использовании opacity: 0).



2

Единственный недостаток <input type="file">- это встраивание прозрачного флеш-ролика поверх div. Затем вы можете использовать событие щелчка, созданное пользователем (соответствующее новым правилам безопасности Flash 10), чтобы инициировать вызов файла FileReference.browse из Flash .

Он предлагает дополнительную зависимость от способа quirksmode, но взамен вы получаете гораздо больше событий (например, встроенных событий выполнения).


-1

Может использовать

$('<input type="file" />').click()

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