Jquery: изменить событие для входного файла в IE - PullRequest
36 голосов
/ 05 марта 2010

У меня есть форма для загрузки файлов, и она должна запустить отправку после выбора файла.

В FireFox / Chrome все идет хорошо, и отправляет форму после выбора файла, но я не могу сделатьэто в Internet Explorer.

Уже пробовал с click / propertychange, но ничего не происходит.Некоторый код, который я уже пробовал:

$("#attach").attr("onChange", "alert('I changed')");
$("#attach").live($.browser.msie? 'propertychange': 'change', function(e) { ... });

Этот входной файл создается на лету;из-за этого я использую .live(), чтобы связать событие.

Есть предложения?

Ответы [ 15 ]

41 голосов
/ 20 мая 2010

Я знаю, что это на несколько месяцев позже, но я столкнулся с точно таким же поведением в IE7; во всех других браузерах событие изменения для ввода файлов происходит после выбора файла. В IE7 это происходит только при повторном запуске выбора файла или при размытии.

Вот как я все исправил:

var $input = $('#your-file-input-element');

var someFunction = function()
{
    // what you actually want to do
};

if ($.browser.msie)
{
    // IE suspends timeouts until after the file dialog closes
    $input.click(function(event)
    {
        setTimeout(function()
        {
            if($input.val().length > 0) {
              someFunction();
            }
        }, 0);
    });
}
else
{
    // All other browsers behave
    $input.change(someFunction);
}

Технически вы могли / должны фильтровать условие взлома только для IE7, так как IE8 ведет себя правильно при событии изменения, но он также ведет себя так же, как IE7 при приостановке тайм-аутов, когда виден связанный с браузером хром (я думаю, он учитывает это блокирует ввод / вывод), поэтому он работает как есть.

11 голосов
/ 21 декабря 2012

Это действительно поздно, но у меня возникла та же проблема, и я решил ее, используя стилизованный тег <label> с небольшим обходным решением для Firefox.

http://jsfiddle.net/djibouti33/uP7A9/

Цели:

  1. позволяет пользователю загружать файл с помощью стандартного элемента управления вводом html-файла
  2. скрыть стандартный элемент управления вводом html-файлов и применить собственный стиль
  3. после того, как пользователь выберет файл для загрузки, автоматически отправьте форму

Браузеры:

  • Firefox, Chrome, IE8 / 9, Safari
  • IE7 не работал, но он мог бы, если вы добавите этот браузер в обходной путь, подробно описанный внизу

Исходное решение:

  1. Скрыть ввод файла, расположив его за кадром. Важно не отображать: нет, так как некоторым браузерам это не понравится.
  2. Добавить еще один стилизованный элемент на страницу (ссылка, кнопка).
  3. Прослушайте щелчок по этому элементу, а затем программно отправьте щелчок по входу файла, чтобы вызвать собственный «проводник»
  4. Прослушивание события onchange ввода файла (происходит после того, как пользователь выбирает свой файл)
  5. Отправить форму

Проблема:

  1. IE: если вы программно отправляете щелчок на ввод файла для его активации (2), программная отправка формы (5) приведет к ошибке безопасности

Обходное решение:

  1. То же, что и выше
  2. Воспользуйтесь преимуществами специальных возможностей, встроенных в тег (нажатие на метку активирует связанный с ней элемент управления) с помощью стиля тег вместо ссылки / кнопки
  3. Прослушивание события onchange ввода файла
  4. Отправить форму
  5. По какой-то причине браузеры Mozilla не активируют ввод файла, нажав на него.
  6. Для Mozilla прослушайте щелчок на ярлыке и отправьте событие щелчка на вход файла, чтобы активировать его.

Надеюсь, это поможет! Проверьте jsfiddle для получения подробных сведений о html / js / css, который использовался, чтобы все это работало.

10 голосов
/ 05 марта 2010

Отформатируйте это так:

$("#attach").change(function() { 
  alert('I Changed');
});

Обновление: После ответа на другой вопрос по этому ранее мы поняли, что это было исправлено как часть переписывания события jQuery 1.4.2 , просто обновите до последней версии, чтобы устранить проблему события change с <input type="file" /> в IE.

3 голосов
/ 18 сентября 2011

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

(function($) {
    if ($.browser.msie == false)
        return;

    $('input[type=file]').live('click', function(e) {
        var self = this;
        var blur = function() {
            $(self).blur();
        }
        setTimeout(blur, 0);
    });

})(jQuery);
2 голосов
/ 01 апреля 2012

Я нашел это решение В HTML скрыть элемент файла (не использовать display: none, не будет работать в IE), подготовить событие onchange IE:

<div style="width: 0px; height: 0px; overflow: hidden;">
  <input id="ifile_template" type="file" onchange="this.focus(); this.blur();"/>
</div>

В javascript для функции связывания IE с размытием, а для FF изменение функции связывания CH ():

$(iFile).blur(
  function () {
    ...some code...
  }
);

// FF, CH
$(iFile).change(
  function () {
  ...some code...
  }
);
2 голосов
/ 16 ноября 2011

У меня была такая же проблема с IE (включая IE 9).Логика пользовательского интерфейса:

  1. нажатие на элемент div вызывает событие click на file-input-element, так что пользователь нажимает на div диалоговое окно открытия триггерного файла
  2. привязать обработчик событий change к file-input-element, чтобы обеспечить отправку form при закрытии диалогового окна открытия файла

Приложение (работающее внутри iframe) работает как Charm в Chrome иFF.Но вскоре я обнаружил, что он не работает в IE, так как когда пользователь выбирает файл и закрывает диалоговое окно, форма не отправляется.

Окончательное решение - сбросить логику # 1 ", нажмите на divЭлемент запускает click событие на элементе ввода файла "и позволяет пользователю щелкнуть file input element напрямую, и тогда он работает.

Кстати, причина, по которой у нас есть элемент div, заключается в том, что мы хотим скрытьбраузер отображал элементы управления, потому что у нас есть все на фоновом изображении.Однако установка display в none делает элемент управления не способным отвечать на события взаимодействия с пользователем.Поэтому мы перемещаем file-input-element за пределы порта просмотра и используем элемент div для его замены.Так как в IE это не работает, в итоге мы возвращаем file-input-element и устанавливаем его opacity в 0. В IE 8 или менее, который не поддерживает opacity, мы используем фильтр, чтобы сделать его прозрачным:

#browse {
    filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
    filter: alpha(opacity=0);
    -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
}
2 голосов
/ 15 мая 2010

Вероятно, это проблема с условием гонки с полями ввода в IE. Используя setTimeout, выполняемая функция затем регистрирует изменение. Когда код пользовательского интерфейса выполняется в onChangeEvent, это событие еще не сработало, как кажется IE.

Я решил похожую ситуацию, выполнив в обработчике изменений следующее:

if (jQuery.browser.msie) { setTimeout(DoSomeUIChange, 0); } else { DoSomeUIChange(); }

DoSomeUIChange выполняется после текущего кода в очереди событий и поэтому удаляет условие гонки.

2 голосов
/ 05 марта 2010

Это всегда работало для меня в IE6 и IE7.

$('#id-of-input-type-file').change(function(){});
1 голос
/ 19 августа 2011

Мое решение:

setInterval(function()
{
    if ($.browser.msie) $("input[type=file]").blur();
},500);

Не красиво, но работает. ; D

1 голос
/ 23 апреля 2011

Для IE. Вы можете использовать событие "onfocus", чтобы отследить изменение загружаемого файла. После закрытия диалогового окна просмотра файла запускается событие onfocus. Вы можете проверить это, добавив эту строку на свою страницу:

<input type="file" onfocus="javascript:alert('test');" />

После закрытия диалогового окна отображается предупреждающее сообщение.

Это решение предназначено только для IE, а не для FF или Chrome.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...