#javascript #html #iframe
Вопрос:
Я пытаюсь решить проблему с вкладками внутри моего модала, когда присутствует перекрестное происхождение <iframe>
.
Что я замечаю:
- Если iFrame не является первым или последним фокусируемым элементом в модале, нет необходимости устанавливать
.focus()
его с помощью javascript. - Если iFrame является первым или последним фокусируемым элементом в модальном, мне нужно установить
.focus()
его с помощью javascript для обеспечения доступности клавиатуры.
.focus()
ограничено в этом использовании. И поскольку я не могу установить фокус, ловушка для вкладок на модальной клавиатуре нарушена.
Кто-нибудь добился успеха в этой области?
Примеры HTML:
Работает (мне не нужно устанавливать фокус с помощью javascript на iframe)
<input type="text" />
<iframe />
<input type="text" />
Если iframe является первым или последним фокусируемым элементом, мне нужно будет использовать javascript для установки фокуса, чтобы поддерживать модальную ловушку клавиатуры
<input type="text" />
<iframe />
или
<iframe />
<input type="text" />
язык JavaScript:
var KEY = {
TAB: 9,
},
allowedFocusableElements =
'a[href], area[href], input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]';
function openDialog(e) {
// Get focusable elements.
dialogFocusableElements = dialog.querySelectorAll(allowedFocusableElements);
dialogFirstElement = dialogFocusableElements[0];
dialogLastElement = dialogFocusableElements[dialogFocusableElements.length - 1];
document.addEventListener("keydown", processKeys);
}
function processKeys(event) {
if (event.keyCode === KEY.TAB amp;amp; !event.shiftKey) {
if (document.activeElement === dialogLastElement) {
event.preventDefault();
dialogFirstElement.focus();
}
} else if (event.keyCode === KEY.TAB amp;amp; event.shiftKey) {
if (document.activeElement === dialogFirstElement) {
event.preventDefault();
dialogLastElement.focus();
}
}
}
Ответ №1:
Все это свелось к попытке использовать .focus()
iFrame с перекрестным происхождением. Поскольку, похоже, нет никакого способа обойти это (учитывая управление порядком табуляции и фокусировку с помощью javascript), я (не так идеально) реализовал некоторые дополнительные элементы табуляции либо до, либо после iFrame в зависимости от того, где он находится в модальном режиме.
Если iFrame является первым фокусируемым элементом, мы помещаем перед ним «псевдо» вкладываемый элемент, и аналогично, если это последний фокусируемый элемент, мы помещаем после него элемент с вкладками.
Вот этот конкретный фрагмент кода:
var KEY = {
TAB: 9,
},
allowedFocusableElements =
'a[href], area[href], input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]';
function openDialog(e) {
// Get focusable elements.
dialogFocusableElements = dialog.querySelectorAll(allowedFocusableElements);
dialogFirstElement = dialogFocusableElements[0];
dialogLastElement = dialogFocusableElements[dialogFocusableElements.length - 1];
// Tab helpers for iFrames.
if (dialogFirstElement.tagName amp;amp; dialogFirstElement.tagName === "IFRAME") {
iframeTabHelper = document.createElement("div");
iframeTabHelper.setAttribute("tabindex", "0");
iframeTabHelper.classList.add("iframe-helper-button");
dialogFirstElement.parentNode.insertBefore(iframeTabHelper, dialogFirstElement);
// Re-get focusable elements.
dialogFocusableElements = dialog.querySelectorAll(
allowedFocusableElements
);
dialogFirstElement = dialogFocusableElements[0];
}
if (dialogLastElement.tagName amp;amp; dialogLastElement.tagName === "IFRAME") {
iframeTabHelper = document.createElement("div");
iframeTabHelper.setAttribute("tabindex", "0");
iframeTabHelper.classList.add("iframe-helper-button");
dialogLastElement.parentNode.insertBefore(iframeTabHelper, dialogLastElement.nextSibling);
// Re-get focusable elements.
dialogFocusableElements = dialog.querySelectorAll(
allowedFocusableElements
);
dialogLastElement = dialogFocusableElements[dialogFocusableElements.length - 1];
}
document.addEventListener("keydown", processKeys);
}
function processKeys(event) {
if (event.keyCode === KEY.TAB amp;amp; !event.shiftKey) {
if (document.activeElement === dialogLastElement) {
event.preventDefault();
dialogFirstElement.focus();
}
} else if (event.keyCode === KEY.TAB amp;amp; event.shiftKey) {
if (document.activeElement === dialogFirstElement) {
event.preventDefault();
dialogLastElement.focus();
}
}
}
Не идеально, но поддерживает работу клавиатуры и функцию ловушки.
Вероятно, можно было бы добавить некоторые проверки, чтобы проверить , действительно ли iFrame имеет перекрестное происхождение, или, что еще лучше, переписать, чтобы проверить, есть ли какой-либо элемент, который ограничивает применение .focus()
, а не только iFrames.