Відкрийте діалогове вікно файлу в JavaScript


109

Мені потрібно рішення, щоб відобразити діалогове вікно відкритого файлу в HTML, натискаючи кнопку a div. Діалогове вікно відкритого файлу повинно відкриватися при divнатисканні кнопки .

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


4
Попередження не є діалоговим вікном файлів? - Чи можете ви уточнити, про що ви питаєте?
LiamB

3
Я думаю, він говорить, що хоче стандартного "відкритого файлу" спливаючого вікна
Валентин Рочер

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

Відповіді:


52

Ось приємний

Демонстраційний файл завантажувача

Це <input type='file' />сам контроль. Але над цим розміщується div і для цього відчувається стиль css. Непрозорість керування файлом встановлюється на 0, так що виявляється, що діалогове вікно відкривається при натисканні на діл.


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

1
@ Ajax3.14 у нових браузерах є об'єкт FileReader, у старих браузерах потрібно використовувати ці значення та шукати розширення файлу.
Вікарій

2
@ Ajax3.14 Не потрібно використовувати розширення FileReader або розбору. Багато браузерів підтримують атрибут accept на файлових входах. Це дозволяє обмежити типи файлів, що відображаються в діалоговому вікні браузера файлів. Fine Uploader забезпечує доступ до цієї функції через властивість acceptFiles опції перевірки. Детальнішу інформацію див. У розділі перевірки документації щодо опцій . Зауважте, що атрибут accept не підтримується в IE9 або раніше.
Рей Ніколус

1
як це добре? це взагалі хороша практика? не повинно бути щось подібне: stackoverflow.com/a/18659941/915865 ?
Kat Lim Ruiz

1
@KatLimRuiz Ні, відповідь, з якою ви пов’язані, не є гарним рішенням. Це призведе до помилки IE, якщо ви в кінцевому підсумку подаєте відповідну форму програмно.
Рей Ніколус

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
Чому ви повертаєте помилку в #select_logo обробник кліків?
Сетіш

4
Це не призведе до помилки 404, вона просто спробує перейти на поточну сторінку з додаванням # в кінці. Що б змусило сторінку скокнути на верх. Тож добре бути там, лише з іншої причини :)
manavo

3
Хоча я її ще не перевірив, "видимість: приховано;" здається більш сумісним. Крім того, незважаючи на непрозорість: 0 подія натискання запуститься, якщо натиснений елемент "невидимий", а видимість: прихований не буде.
Арон

MDN вказує, що document.getElementById("logo").click()цього достатньо. Вони також показують інший спосіб "Перетягування". developer.mozilla.org/en-US/docs/Web/API/File/…
Ерік

2
Ви повинні перетворити це у звичайний Javascript, JQuery не логічно використовувати для такого невеликого проекту ^ _ ^
Містер Сіркоде

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.
Раптор

5
Simplicity is the ultimate sophistication
ncubica

2
чудово! він працює як шарм навіть із фоновим зображенням або змушує ярлик отримувати натискання JavaScript. Дякую!
Лев Номдеде

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

1
@JPdelaTorre Було б набагато краще, якби ви використовували непрозорість: 0 замість цього, щоб приховати вхід.
Адріан

39

Насправді вам не потрібно все це з непрозорістю, видимістю, <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
Дурне запитання, але як би ти отримав обраний файл згодом?
Джей Вік

2
Це небезпечне рішення, яке може призвести до несподіваних проблем. Наприклад, деякі браузери (наприклад, IE) можуть перешкоджати надсиланню програмної форми, якщо введення файлу також відкрито програмно. Найкращий спосіб вирішити цю проблему - це CSS, а не JavaScript.
Рей Ніколус

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
Максимізуйте вхід і встановіть непрозорість до нуля. Це чудово працює!
Кінорсі

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". Ви просто повинні надати цим функціям ідентифікатор прихованого типу вводу = "файл", який є ім'ям екземпляра 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
}

і якщо ви не хочете створювати та додавати відкриті діалогові файли в тілі або теги форм у html, оскільки це додавання прихованого типу вводу = "файл", ви можете це зробити у скрипті за допомогою функції створення вище :

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
Краще не змінювати безпосередньо внутрішній HTML.
Соломон Учко

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">- вставити прозорий флеш-фільм над дівом. Потім ви можете використовувати подій, створений користувачем, що натискає (сумісний з новими правилами безпеки Flash 10), щоб викликати виклик у файл FileReference.browse Flash .

Він пропонує додаткову залежність від способу quirksmode, але взамін ви отримуєте багато більше подій (наприклад, вбудованих в хід подій).


-1

Може використовувати

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

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