Вопрос

Благодаря Совершенство убивает, мы можем использовать следующий JavaScript для обнаружения поддержки событий:

function hasEvent(ev) {
    var elem = document.createElement('a'),
        type = 'on' + ev,
        supported = elem[type] !== undefined;
    if (!supported) {
        elem.setAttribute(type, 'return;');
        supported = typeof elem[type] === 'function';
    }
    elem = null;
    return supported;
}

Это работает примерно в течение единственного раз, когда мне это нужно: обнаружение mouseenter поддерживать; hasEvent('mouseenter') вернется ложным в хроме, Firefox и т. Д., Как и должно.

Но теперь я пытаюсь «исправить» браузеры, которые не поддерживают focusin а также focusout События. Согласно PPK, это в основном просто Firefox. К сожалению, Chrome и Safari указаны как «неполная» поддержка, по следующей причине:

Safari и Chrome стреляют в эти события только с помощью addeventListener; Не с традиционной регистрацией.

В общем, это нормально; Я бы только использовал addEventListener тем не мение. Это делает среднее, однако, что обнаружение поддержки через elem.onfocusin !== undefined не будет работать. Я проверил это, и это правда:

<p>Do I support <a href="#">focusin</a>?</p>

<script>
var elem = document.getElementsByTagName('p')[0];

// hasEvent method defined here
function listener() {
    var response = hasEvent('focusin') ? 'Yes!' : 'No...';
    alert(response);
}

elem.addEventListener('focusin', listener, false);
</script>

Вышеупомянутые оповещения No... в хроме !! Есть ли способ обнаружить, поддерживает ли браузер focusin, без использования браузера, нюхая?

Это было полезно?

Решение

Это использует тот факт, что вызов focus() триггеры focusin: http://jsfiddle.net/pimvdb/yxed3/.

Элемент должен быть видимым и вставить в DOM, в противном случае focusin не уволен по какой -то причине.

var result = (function() {
    var hasIt = false;

    function swap() {
        hasIt = true; // when fired, set hasIt to true
    }

    var a = document.createElement('a'); // create test element
    a.href = "#"; // to make it focusable
    a.addEventListener('focusin', swap, false); // bind focusin

    document.body.appendChild(a); // append
    a.focus(); // focus
    document.body.removeChild(a); // remove again

    return hasIt; // should be true if focusin is fired
})();

Другие советы

FocusIn & Focusout должен быть запущен до того, как целевой элемент получит фокус, порядок событий также кажется глюми

http://www.w3.org/tr/dom-level-3-events/#events-focusevent-event-onder

В настоящее время только IE работает в соответствии со спецификацией:

Chrome/Safari:
focus
focusin
DOMFocusIn
blur
focusout
DOMFocusOut
focus
focusin
DOMFocusIn

Opera 12:
focus
DOMFocusIn
focusin
blur
DOMFocusOut
focusout
focus
DOMFocusIn
focusin

IE 8:
focusin
focus
focusout
focusin
blur
focus

Firefox 14:
focus
blur
focus

Вы можете проверить на ("onfocusin" in document).

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

Вы можете использовать следующий код, чтобы получить то же поведение, что и focusin Событие во всех браузерах (IE9+, Chrome, Firefox, Edge):

var eventName, useCapture;
if ("onfocusin" in document) {
  eventName = "focusin";
  useCapture = false;
} else {      
  eventName = "focus";
  useCapture = true;
}

document.body.addEventListener(eventName, function( event ) {
    event.target.style.background = "pink";    
  }, useCapture);

JS скрипка здесь: https://jsfiddle.net/d306qm92/2/

Более подробная информация о обходном пути Firefox здесь: https://developer.mozilla.org/en-us/docs/web/events/focus#event_delegation

ОБНОВИТЬ: Как сказано выше, тест ошибочно скажет «ложь» на Chrome, тем не менее, образец кода будет работать так же, как Chrome поддерживает оба метода (focusin а также focus с useCapture).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top