Как обнаружить поддержку фокусировки?
-
27-10-2019 - |
Вопрос
Благодаря Совершенство убивает, мы можем использовать следующий 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
).