Как определить поддержку `focusin`? - PullRequest
13 голосов
/ 07 сентября 2011

Благодаря Perfection Kills мы можем использовать следующий 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') вернет false в Chrome, 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... в Chrome !! Есть ли способ определить, поддерживает ли браузер focusin, без использования сниффера браузера?

Ответы [ 3 ]

4 голосов
/ 30 июля 2012

focusin & focusout должен быть запущен ДО того, как целевой элемент получит фокус, порядок событий также кажется ошибочным

http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order

в настоящее время, только 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
3 голосов
/ 07 сентября 2011

При этом используется тот факт, что вызов 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
})();
0 голосов
/ 29 апреля 2016

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

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

Вы можете использовать следующий код, чтобы получить то же поведение, что и событие 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 ошибочно будет указано «false», тем не менее пример кода будет работать так, как задумано, поскольку Chrome поддерживает оба метода (focusin и focus с useCapture).

...