Открыть диалог ввода файлов и загрузить его можно в IE? - PullRequest
16 голосов
/ 01 мая 2011

Это в основном и упрощено то, что я имею сейчас:

<style>
form.noshow { height: 0; overflow: hidden; }
</style>

<form class=noshow target="SomeIframeThatExists">
  <input type=file id=uf>
</form>

<a id=uflink href="/user/photo">Upload photo</a>

<script>
$('uf').addEvent('change', function(e) {
  // alert('oele'); // this would work fine
  this.form.submit(); // auch in IE > "Access denied" exception
});
$('uflink').addEvent('click', function(e) {
  $('uf').click(); // opens file dialog in all browsers inc IE
  return false;
});
</script>

Что он делает (отлично) в Chrome 11 и FF 4:

  1. Форма скрыта.
  2. Вы нажимаете на ссылку
  3. Откроется диалоговое окно выбора файла
  4. Вы выбираете файл
  5. Диалог закрывается
  6. Форма отправлена ​​
  7. Выполнен скрипт в iframe и заменена фотография

Очень высокотехнологичный и сладкий.

В IE все это работает, кроме [6]. Форма не отправлена. Ошибка JavaScript: «Доступ запрещен». Неважно, как форма невидима, если диалог был открыт с input.click(), форма не может быть отправлена ​​при изменении. (Функция onchange выполняется нормально. Ошибка возникает только при вызове form.submit().)

Теперь все это я могу принять. IE отстой. Я живу с этим.

Мое решение до сих пор заключалось в проверке navigator для «MSIE» и затем при нажатии на ссылку вместо открытия диалогового окна, показывая форму (с вводом файла). Затем пользователь должен нажать на фактический, уродливый файл ввода, и тогда все работает нормально. Но некрасиво.

Вопрос двоякий:

  1. Есть ли способ сделать это в IE так же круто, как в Chrome? БЕЗ противного флеша / ява хрень. Только элементы HTML и JavaScript.
  2. Если нет: есть ли способ проверить поддержку form.submit () после открытия диалога по ссылке (кроме !navigator.contains("MSIE"))?

[2] может перехватывать исключение «Отказано в доступе», сгенерированное в IE, но тогда уже слишком поздно: пользователь уже открыл диалоговое окно и перешел к фотографии. Ты не хочешь заставить его сделать это снова. (Даже пользователи IE не заслуживают этого.)

PS. Меня интересуют только Chrome 10+, Firefox 3.6+ и IE8 +.

PS. Может быть важно: элемент ввода файла не может находиться рядом со ссылкой, потому что ссылка находится внутри формы, и эта форма (должна быть) отделена от формы загрузки файла.

UPDATE
Второе лучшее: обнаружение поддержки этого высокотехнологичного поведения, которое не работает только в IE. Я не хочу использовать navigator.appName.contains('MSIE'), потому что это не гибко и не обязательно верно.

Ответы [ 5 ]

12 голосов
/ 19 декабря 2012

@ Руди, здесь - Спасибо за этот код! Он отлично работает в IE и Chrome, но не в FireFox.

Мне удалось взять мой старый код (который работает в FF и Chrome) и объединить ваш код для MSIE.

Проверьте это здесь:

ИСПРАВЛЕНИЕ ДЛЯ IE, CHROME И FIREFOX

https://gist.github.com/4337047

ПРОБЛЕМА: Когда ввод файла открывается через сценарий, принудительное событие click (), IE не позволит вам отправить форму. Если вы нажмете на ввод файла с помощью собственной мыши (чего мы не хотим), IE разрешит вам отправить форму.

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

Решение (частично благодаря Rudie @ Stackoverflow, https://stackoverflow.com/users/247372/rudie, http://hotblocks.nl/):

Сделать метку для ввода в IE. Если вы щелкнете по нему, это вызовет щелчок в поле ввода - и IE примет это (тупой IE думает, что пользователь щелкнул по полю ввода, ха)

Так что на этом лейбле мы разместим наш собственный стиль DIV.

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

Решение прямо здесь. Проверено в:

  • Win 7 x64
  • FireFox 13.01
  • Хром 23.0.1271.97 м
  • IE9 в обычном режиме IE9

Больше тестов / дополнений в коде БОЛЬШЕ, чем приветствуется!

EDIT:

Цитировать Рой МакКензи

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

8 голосов
/ 14 сентября 2011

Я сделал это !!

http://jsfiddle.net/rudiedirkx/8hzjP/show/

<label for="picture">Upload picture</label>
<input type="file" id="picture" style="position: absolute; visibility: hidden" />

IE8 работает. Меня не волнуют другие.

Так просто =)

2 голосов
/ 06 августа 2011

Ну, это ТОЧНАЯ та же проблема, что у меня сейчас. И единственный (отвратительный) хак, который все-таки решил, - это сделать input [type = file] достаточно большим с CSS, сделать его alpha = 0 и поместить его поверх желаемого элемента пользовательского интерфейса.

Короче говоря, вы заставляете пользователя нажимать на некрасивую кнопку «просмотр», не осознавая этого.

2 голосов
/ 02 мая 2011

Как ни странно, IE8 блокирует отправку, только если в форме есть enctype="multipart/form-data".

Один из обходных путей, который работал для меня локально, - добавление «реальной» кнопки отправки, например,

<input type="submit" id="btnSubmit" value="Submit" />

Затем введите такой код:

$('btnSubmit').click();

Если это работает, вы можете скрыть кнопку с помощью CSS, чтобы сделать ее прозрачной для пользователя.

0 голосов
/ 12 мая 2011

Попробуйте добавить тег enctype="multipart/form-data" к элементу form.

...