tl; dr - вы не можете отслеживать фокус на фрейме, по крайней мере, не напрямую.Но есть и другие источники информации, которые могут быть достаточно полезными.
Поскольку iframe является кросс-источником, это немедленно исключает прямой доступ к его состоянию фокуса, присоединение любых обработчиков событий или публикацию любых сообщений.Однако вы можете использовать document.body.activeElement
, чтобы увидеть, нажал ли пользователь на iframe, а не на другую вкладку / окно.С этим знанием этот взлом возможен:
const handleLeave = () => {
const { activeElement } = document;
const iframeIsActiveElement = activeElement && activeElement.tagName === 'IFRAME';
if (iframeIsActiveElement) {
// timeout necessary to not blur the iframe too quickly
setTimeout(() => activeElement.blur(), 0);
return;
}
doBlurStuff();
};
window.addEventListener('blur', handleLeave);
Так что, когда window
размывает, мы проверяем, нажал ли пользователь на iframe.Если они это сделают, мы собираемся размыть iframe (действие пользователя уже произошло), который возвращает фокус на document.body
.По неизвестным причинам (возможно, из-за того, что это происходит слишком быстро или из-за того, что мы явно не focus
ing document.body
) любые обработчики window
focus
не запускаются.И так как мы return
рано, doBlurStuff
также не срабатывает.
Один компромисс: поскольку мы фокусируем, у него есть проблемы с доступностью и UX.Пользователь не сможет использовать события клавиатуры для iframe, поскольку он никогда не сможет удерживать фокус.Этот компромисс может не стоить того для многих случаев использования.