$ (": focus") не возвращает элемента для <input type = "file" /> в Firefox - PullRequest
3 голосов
/ 16 февраля 2012

Я не могу получить текущий фокусированный / активный элемент как объект jQuery в Firefox , если это <input type="file" />.Он работает с другими типами ввода (текст, пароль, отправить, другие) и с другими типами элементов (<select>, <textarea>, другие).

HTML

<input type="file" />

Javascript

// Cannot find input type file elements with :focus,
// $focused.length is always 0 in Firefox (tested using FF 10.0.1)
var $focusedTest1 = $(':focus');

// This line throws for Firefox (tested using FF 10.0.1)
// Permission denied to access property 'nodeType'
// @ http://code.jquery.com/jquery-1.7.1.js:108
// in jQuery.fn.init, below "Handle $(DOMElement)"
var $focusedTest2 = $(document.activeElement);

Шаги для воспроизведения

  1. Используйте Firefox.
  2. Сфокусируйте поле файла:
    • нажимайте вкладку, пока не дойдете до нее
    • или щелкните по нему.
  3. Во время фокусировки на окне файла попробуйте получить результат из $(':focus').

См. Демонстрацию jsFiddleполучения идентификатора сфокусированного элемента - протестируйте его с помощью Firefox.

У кого-нибудь есть решение для получения сфокусированного / активного элемента в виде объекта jQuery, который работает для <input type="file" />?

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

Ответы [ 3 ]

3 голосов
/ 16 февраля 2012

Редактировать: Это решение было реализовано, когда проблема была впервые обнаружена , в EmulateTab . См. getFocusedElement () .


Нашел решение сам, после перерыва в кодировании - но это не очень чистое решение. Это в основном то же решение , которое было предложено @ Neil , когда я впервые писал этот пост.

Попробуйте обновленную версию jsFiddle с фокус-слушателями и логикой try-catch в Firefox. Он объединяет :focus, document.activeElement и слушателей фокуса уровня документа, которые отслеживают последний «известный» сфокусированный элемент.

Функция поиска сфокусированного элемента

// Comined function to get the focused element trying as long as possible.
// Extra work done trying to avoid problems with security features around
// <input type="file" /> in Firefox (tested using 10.0.1).
function getFocused() {
    // Try the well-known, recommended method first.
    var $focused = $(':focus');

    if ($focused.size() === 0) {
        try {
            // Fall back to a fast method that might fail.
            // Known to fail for Firefox (tested using 10.0.1) with
            // Permission denied to access property 'nodeType'.
            $focused = $(document.activeElement)
        }
        catch (error1) {
                warnToConsole("Could not use document.activeElement", document.activeElement, error1);

            if (lastFocusedElement !== null) {
                try {
                    // As a last resort, use the last known focused element.
                    // Has not been tested enough to be sure it works as expected.
                    $focused = $(lastFocusedElement);
                } catch (error3) {
                    warnToConsole("Could not use lastFocusedElement ", lastFocusedElement, error3);
                }
            }
        }
    }

    return $focused;
}

Фокус слушателей

// Keep a reference to the last focused element, use as a last resort.
var lastFocusedElement = null;

function focusInElement(event) {
    lastFocusedElement = event.target;
}

function focusOutElement(event) {
    lastFocusedElement = null;
}

// Start listeners.
$(function() {
    // Start listeners that keep track of the last focused element.
    $(document).on("focusin", focusInElement);
    $(document).on("focusout", focusOutElement);
});

Мне не очень нравится это решение, поскольку оно далеко не такое чистое, как одна строка $(':focus'). Другие ответы приветствуются!

1 голос
/ 16 февраля 2012

Единственный способ, о котором я могу подумать, - это добавить прослушиватель захвата фокуса на уровне окна, в котором вы обновляете глобальную переменную с целью события.(В Firefox целевым событием для события фокуса при вводе файла является сам ввод файла, даже если document.activeElement возвращает кнопку «анонимно».)

0 голосов
/ 16 февраля 2012

Попробуйте - протестировано в Firefox 10.0.1

$(document).ready(function () {
        var crtFocus;
        $("#id1").focus(function () {
            crtFocus = $(this);
        });
        $("#id2").focus(function () {
            crtFocus = $(this);
        });
        $("#id3").focus(function () {
            crtFocus = $(this);
        });

        $("#click").click(function () {
            // $(crtFocus) contains the currently focused element
            //alert($(crtFocus));
        });
    });


...



<input type="file" id="id1" />
<input type="file" id="id2" />
<input type="file" id="id3" />    
<input type="button" id="click"/>

EDIT - мы можем использовать только один селектор для всех входных элементов [type = file] вместо одного селектора на элемент

$(':input[type=file]').focus(function () {
            crtFocus = $(this);
        });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...