Обходной путь для клика по метке ввода файла (Firefox) - PullRequest
10 голосов
/ 12 октября 2011
<label for="input">Label</label><input type="file" id="input"/>

В Firefox 7 невозможно открыть диалоговое окно открытия файла, нажав на метку.

Этот вопрос SO очень похож, но зеленый отмечен с это ошибка в FF . Я ищу обходной путь.

Есть идеи?

Ответы [ 9 ]

23 голосов
/ 07 апреля 2012

спасибо за это вопросы и ответы ... помогли мне.

мой вариант решения @ marten-wikstrom:

if($.browser.mozilla) {
  $(document).on('click', 'label', function(e) {
    if(e.currentTarget === this && e.target.nodeName !== 'INPUT') {
      $(this.control).click();
    }
  });
}

примечания

  • с использованиемdocument.ready ($(function() {...});) не требуется ни в одном из решений.jQuery.fn.live позаботится об этом в случае @ marten-wikstrom;в моем примере явно выполняется привязка к document.
  • с использованием jQuery.fn.on ... текущей рекомендуемой техники привязки.
  • добавлена ​​проверка !== 'INPUT', чтобы гарантировать, что выполнение не получитздесь в цикле:

    <label>
      <input type="file">
    </label>
    

    (поскольку щелчок по полю файла вернется к метке)

  • изменить event.target проверить на event.currentTarget, позволяя при первоначальном щелчке <em> in:

    <label for="field">click <em>here</em></label>
    
  • с помощью атрибута control элемента label для более чистой, простой ассоциации полей формы базы данных.
3 голосов
/ 12 октября 2011

Я придумал возможный обходной путь:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript">
    $(function () {
        $("label").click(function () {
            $("#input").click();
        });
    });
</script>
<label for="input">Label</label><input type="file" id="input"/>

Довольно странно, что FF позволяет имитировать щелчок на вводе файла.Я думал, что это считается угрозой безопасности ...

ОБНОВЛЕНИЕ: Это общий обходной путь:

<script type="text/javascript">
    $(function () {
        if ($.browser.mozilla) {
            $("label").live("click", function (event) {
                if (event.target == this) {
                    $("#" + $(this).attr("for")).extend($("input", this)).first().click();
                }
            });
        }
    });
</script>
1 голос
/ 05 сентября 2013

Кажется, это исправлено в FF 23, поэтому обнаружение в браузере становится опасным и приводит к двойным системным диалогам; (

Вы можете добавить еще один тест, чтобы ограничить исправление версией FF до версии 23:

if(parseInt(navigator.buildID,10) < 20130714000000){
  //DO THE FIX
}

Это довольно уродливо, но это исправление будет удалено, как только исчезнет старая версия FF.

1 голос
/ 19 марта 2013

Диалог выбора файла может быть запущен во всех браузерах с помощью события click() .Ненавязчивое решение этой проблемы может выглядеть так:

$('label')
    .attr('for', null)
    .click(function() {
        $('#input').click();
    });

Удаление атрибута for важно, так как другие браузеры (например, Chrome, IE) все равно ратифицируют его и дважды отобразят диалоговое окно.

Я протестировал его в Chrome 25, Firefox 19 и IE 9 и работает как шарм.

1 голос
/ 21 февраля 2013

При использовании обнаружения браузером jQuery возникает пара проблем, в частности, анти-паттерн использования обнаружения браузера, а не обнаружения функций, в дополнение к тому факту, что 1.9+ не обеспечивает эту функцию.

Возможно, тогда решение, к которому я пришел, немного лицемерно, но оно сработало хорошо и, похоже, соответствует большинству лучших практик сегодня.

Сначала убедитесь, что вы используете условные классы Пола Айриша . Затем используйте что-то вроде:

  if($("html").hasClass("ie")) {
    $("label").click();
  } else {
    $("input").click();
  }

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

0 голосов
/ 07 марта 2015

Обходной путь, когда вам не нужно / не нужно иметь поле ввода (например, загрузка изображений), заключается в использовании opacity: 0 в элементе и pointer-events: none; в метке.Решение действительно зависит от дизайна, но, возможно, должно работать для тех, кто приходит к этому.(до сих пор ошибка не была исправлена)

http://codepen.io/octavioamu/pen/ByOQBE

0 голосов
/ 07 июля 2014

вы можете отправить событие из любого события во входной файл type =, если хотите сделать отображение ввода: нет и видимость: скрытым, а затем отправить событие из, скажем, щелчок | прикосновение к изображению ...

<img id="customImg" src="file.ext"/>
<input id="fileLoader" type="file" style="display:none;visibility:hidden"/>

<script>
    customImg.addEventListener(customImg.ontouchstart?'touchstart':'click', function(e){
        var evt = document.createEvent('HTMLEvents');
        evt.initEvent('click',false,true);
        fileLoader.dispatchEvent(evt);
    },false);
</script>
0 голосов
/ 22 мая 2014

Попробуйте этот код

<img id="uploadPreview" style="width: 100px; height: 100px;" 
onclick="document.getElementById('uploadImage').click(event);" />
<input id="uploadImage" type="file" name="myPhoto" onchange="PreviewImage();" />
<script type="text/javascript">
    function PreviewImage() {
        var oFReader = new FileReader();
        oFReader.readAsDataURL(document.getElementById("uploadImage").files[0]);
        oFReader.onload = function (oFREvent) {
            document.getElementById("uploadPreview").src = oFREvent.target.result;
        };
    };
</script>
0 голосов
/ 13 октября 2011

Обратный порядок метки и элементов ввода. iow, поместите элемент метки после элемента ввода.

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