Отключить автофокусировку showModal с использованием атрибутов HTML - PullRequest
4 голосов
/ 05 августа 2020

Насколько мне известно, метод showModal() выполняет следующие шаги, которые приводят к фокусировке элементов в диалоговом окне HTML (выделено мной):

  1. Пусть subject будет элементом диалога, для которого был вызван метод.

  2. Если subject уже имеет открытый атрибут, тогда выбросить "InvalidStateError" DOMException .

  3. Если субъект не подключен , тогда выбросить "InvalidStateError" DOMException `.

  4. Добавить открытый атрибут к субъекту, значением которого является пустая строка.

  5. Установите диалоговое окно в режим выравнивания по центру.

  6. Пусть тема s документ узла блокируется модальный диалог тема .

  7. If тема s документ узла s верхний уровень еще не содержит su bject , затем добавьте subject к subject s документ узла s верхний уровень .

  8. Запуск диалогового окна , шаги фокусировки для объекта .

Таким образом, последний шаг, 8, запустит следующие шаги фокусировки диалога в диалоге. Насколько я понимаю (что может быть совершенно неверным), эти три шага из раздела шагов фокусировки диалога в spe c указывают, что элемент должен быть сфокусирован только в том случае, если элемент не является инертным и имеет автофокусировку:

  1. Если субъект инертный , вернуть.

  2. Пусть control будет первым дочерним элементом субъекта в порядок дерева , это не инертный и для него указан атрибут автофокуса.

    Если его нет, то пусть control будет первым неинертным дочерним элементом subject , в древовидном порядке.

    Если ни одного из них нет, пусть управление будет предметом.

  3. Запустите шаги фокусировки для управления.

    ...

Итак, мне кажется, что моя кнопка ниже (см. фрагмент) имеет атрибут inert или не имеет автоматической фокусировки, тогда он не должен фокусироваться при открытии диалогового окна. Однако, когда я пытаюсь применить оба атрибута, он все равно оказывается сфокусированным.

Попытка с логическим атрибутом inert (который, как я думал, заставил бы шаги фокусировки диалога вернуть выше, следовательно, фокусировка не выполняется):

const dialog = document.querySelector("#dialog");
document.querySelector("#open-btn").addEventListener('click', () => {
  dialog.showModal();
});

document.querySelector("#close-btn").addEventListener('click', () => {
  dialog.close();
});
#close-btn:focus {
  background: red;
}
<button id="open-btn">Open</button>
<dialog id="dialog">
  <button id="close-btn" inert="inert">&times;</button>
</dialog>

Попытка с логическим атрибутом autofocus, установленным на false (я считаю, что именно так вы устанавливаете его на false, Я также пробовал autofocus="false", который тоже не работал):

const dialog = document.querySelector("#dialog");
document.querySelector("#open-btn").addEventListener('click', () => {
  dialog.showModal();
});

document.querySelector("#close-btn").addEventListener('click', () => {
  dialog.close();
});
#close-btn:focus {
  background: red;
}
<button id="open-btn">Open</button>
<dialog id="dialog">
  <button id="close-btn" autofocus="">&times;</button>
</dialog>

Поскольку оба из них не работают, я искал SO и нашел этот ответ , который предполагал, что я также могу использовать tabindex="-1", что тоже не сработало.

Я знаю, что могу размыть кнопку, когда она сфокусирована с помощью .blur(), но мой вопрос в частности:

  1. Почему две приведенные выше скрипты не отключают автоматическую фокусировку кнопки?
  2. Есть ли какой-то атрибут HTML, который я могу использовать для остановки моей кнопки сосредоточены?

1 Ответ

0 голосов
/ 11 августа 2020

Отключенные элементы не могут быть сфокусированы. Вы можете добавить атрибут disabled к close-btn.

Но отключенные элементы нельзя щелкнуть. Добавьте атрибут onclick в open-btn. Установите onclick на это: setTimeout(function(){document.getElementById('close-btn').disabled = false}). Это просто активирует кнопку через 1 миллисекунду после нажатия кнопки. Тайм-аут необходим, чтобы он не активировал close-btn до открытия диалогового окна.

Если диалоговое окно открывается повторно, кнопка автоматически фокусируется. Мы могли бы добавить еще один атрибут onclick к close-btn. Установите onclick на close.btn на это: this.disabled = true. Это отключает close-btn при нажатии.

Конечный результат:

const dialog = document.querySelector("#dialog");
document.querySelector("#open-btn").addEventListener('click', () => {
  dialog.showModal();
});

document.querySelector("#close-btn").addEventListener('click', () => {
  dialog.close();
});
#close-btn:focus {
  background: red;
}
<button id="open-btn" onclick='setTimeout(function(){document.getElementById("close-btn").disabled = false})'>Open</button>
<dialog id="dialog">
  <button disabled id="close-btn" inert="inert" onclick='this.disabled = true'>&times;</button>
</dialog>
...