Я не нашел встроенного решения или обходного пути для закрытия элемента html5, щелкнув по его фону (:: backdrop), хотя это явно базовая функциональность.
Как закрыть новый тег html <dialog>, щелкнув по его фону:: backdrop
Ответ 1
Фоновые клики могут быть обнаружены с помощью ограничивающего диалога.
var dialog = document.getElementByTagName('dialog');
dialog.showModal();
dialog.addEventListener('click', function (event) {
var rect = dialog.getBoundingClientRect();
var isInDialog=(rect.top <= event.clientY && event.clientY <= rect.top + rect.height
&& rect.left <= event.clientX && event.clientX <= rect.left + rect.width);
if (!isInDialog) {
dialog.close();
}
});
Ответ 2
Другим более эффективным решением является обертка dialog
-content в div
с помощью padding: 0
. Таким образом, вы можете проверить event.target
события click-event, который ссылается на диалог в случае фона и любого другого элемента в div
в случае фактического модального.
Не проверяя фактические размеры, мы можем предотвратить циклы компоновки.
Ответ 3
Для тех, кто наткнулся на этот вопрос и хочет следовать решению, рекомендованному @meaku, вот как я решил использовать a для инкапсуляции элемента и не работать с вычислением getBoundingClientRect():
const popup = document.getElementById('popup');
const popupDialog = document.getElementById('popup-dialog');
popup.addEventListener('click', function(e){
console.info(e.target.tagName);
if (e.target.tagName === 'DIALOG') popupDialog.close()
});
<div id="popup" style="padding: 0">
<dialog id="popup-dialog" style="display:none;">
<h4>Dialog Title</h4>
<footer class="modal-footer">
<button id="popup-close" type="button">close</button>
<button id="popup-ok" type="button">ok</button>
</footer>
</dialog>
</div>
Ответ 4
Я разобрался с очень простым решением этой проблемы. Добавьте контейнер div внутри <dialog>
. Затем проверьте, является ли это родителем всего этого. Если нет, то это сам диалог, и он может быть закрыт.
HTML
<dialog id="favDialog">
<div class="test">
Hello
</div>
</dialog>
JS
document.querySelector('dialog').addEventListener('click', function(e) {
if(!e.target.closest('div')) {
e.target.close();
}
});
Ответ 5
Другой простой метод, похожий на метод div, упомянутый другими, заключается в предоставлении самого диалога padding: 0
(как, например, Chrome, как правило, дает заполнение диалогового окна) и добавление события click в диалог. Элемент form
в любом случае улавливает разницу, поэтому нет необходимости в дополнительном div.
Я заметил, что форма не использовалась ни в одном из приведенных выше примеров, поэтому я подумал, что ее стоит добавить, поскольку она является частью стандарта при работе с кнопками в диалоговом окне.
<dialog style="padding: 0; border: 0;">
<form method="dialog">
<button>Click here</button>
</form>
</dialog>
<script>
onClick(event) {
if (event.target === dialog) {
dialog.close();
}
}
const dialog = document.querySelector('dialog');
dialog.addEventHandler('click', onClick);
dialog.showModal();
</script>