Ответ 1
Нет, это единственный способ.
- Найдите все элементы, у которых
tabIndex
больше, чем-1
& dagger; и не принадлежат вашему модальному. - Создайте массив & ddagger; и заполните его ссылками на каждый элемент вместе с его оригинальным
tabIndex
. - Установите каждый элемент
tabIndex
на-1
, чтобы он больше не мог получать фокус с клавиатуры. - Когда модальное диалоговое окно закрывается, перебирайте массив и восстанавливайте исходный
tabIndex
.
Вот быстрая демонстрация:
function isDescendant(ancestor, descendant) {
do {
if (descendant === ancestor) return true;
} while (descendant = descendant.parentNode);
return false;
}
var tabIndexRestoreFunctions;
var lastFocused;
document.getElementById("btn-show-modal").addEventListener("click", function(e) {
lastFocused = document.activeElement;
var modal = document.querySelector(".modal");
tabIndexRestoreFunctions = Array.prototype
// get tabable items which aren't children of our modal
.filter.call(document.all, o => o.tabIndex > -1 && !isDescendant(modal, o))
// iterate over those items, set the tabIndex to -1, and
// return a function to restore tabIndex
.map(o => {
var oldTabIndex = o.tabIndex;
o.tabIndex = -1;
return () => o.tabIndex = oldTabIndex;
});
// show modal
modal.classList.add("shown");
// focus modal autofocus
modal.querySelector("[autofocus]").focus();
});
document.getElementById("btn-close-modal").addEventListener("click", function(e) {
// restore tabs
tabIndexRestoreFunctions && tabIndexRestoreFunctions.forEach(f => f());
tabIndexRestoreFunctions = null;
// hide modal
document.querySelector(".modal").classList.remove("shown");
// restore focus
lastFocused && lastFocused.focus();
});
.modal {
display: none;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(128, 128, 128, .75);
}
.modal.shown {
display: flex;
}
.modal-content {
margin: auto;
width: 500px;
padding: 30px;
border: 1px solid #333;
background-color: #fdfdfd;
}
<label>test
<input autofocus />
</label>
<button>dummy button</button>
<hr/>
<button id="btn-show-modal">open modal</button>
<div class="modal">
<div class="modal-content">
<label>test
<input autofocus />
</label>
<button id="btn-close-modal">close modal</button>
</div>
</div>