I've created a simple modal that is allowed to be closed when you click outside of the content area. This is by design but it has an unintended side-effect. If I click anywhere in the content area (for example in a text field) and drag the mouse to beyond the content area and then release the click it will close the modal. I often have a habit of doing this and I can see how average users will perceive this as a bug so I'm trying to nip it prior to release.
var modal = document.getElementById("modal-container");
function openModal() { modal.classList.add("active"); }
function closeModal() { modal.classList.remove("active"); }
window.onclick = function (event) {
if (event.target == modal)
closeModal();
}
html, body {
margin: 0;
height: 100%;
}
.modal-container.active { top: 0; }
.modal-container {
position: absolute;
top: -500vh;
left: 0;
width: 100%;
height: 100%;
display: grid;
background-color: rgba(0, 0, 0, 0.75);
}
.modal-content {
height: 50%;
width: 50%;
margin: auto;
background-color: #fff;
display: flex;
align-items: center;
justify-content: center;
}
<button onclick="openModal();">Open the Modal</button>
<div id="modal-container" class="modal-container">
<div class="modal-content">
<input type="text" />
</div>
</div>
To test it properly:
The modal should now be closed.
Is there a way to prevent this without tracking the coordinates of the mouse?
onmousedown
instead of click?
When the Button is clicked, the HTML DIV is referenced using jQuery and its modal function is called along with properties data-backdrop: "static" and data-keyboard: false which disables the closing of the Bootstrap Modal Popup when clicked outside.
By default, dialog can be closed by pressing Esc key and clicking the close icon on the right of dialog header. It can also be closed by clicking outside of the dialog using hide method. Set the closeOnEscape property value to false to prevent closing of the dialog when pressing Esc key.
Modal Header You have two options to close this modal: Click on the "x" or click anywhere outside of the modal!
Click the button to launch the modal. Then click on the backdrop, close icon or close button to close the modal.
Before you answer yourself with a valid cause (as noted in your Question Edit) - take in consideration:
onmousedown
might not always be the desired UX. (Sometimes experienced users to undo a mousedown not being registered as a click
they on purpose move the mouse over another element for the mouseup event just to retain the current state.)Element.addEventListener()
to any button having the data-modal
attributedata-modal="#some_modal_id"
even no the container elementif (evt.target !== this) return;
const el_dataModal = document.querySelectorAll('[data-modal]');
function toggleModal(evt) {
if (evt.target !== this) return; // Do nothing if the element that propagated the event is not the `this` button which has the event attached.
const id = evt.currentTarget.getAttribute('data-modal');
document.querySelector(id).classList.toggle('active');
}
el_dataModal.forEach(el => el.addEventListener('click', toggleModal));
html, body {
margin: 0;
height: 100%;
}
.modal-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: grid;
background-color: rgba(0, 0, 0, 0.75);
opacity: 0; /* ADDED */
transition: 0.26s; /* ADDED */
visibility: hidden; /* ADDED */
}
.modal-container.active {
opacity: 1; /* ADDED */
visibility: visible; /* ADDED */
}
.modal-content {
height: 50%;
width: 50%;
margin: auto;
background-color: #fff;
display: flex;
align-items: center;
justify-content: center;
}
<button data-modal="#modal-container">Open the Modal</button>
<div id="modal-container" class="modal-container" data-modal="#modal-container">
<div class="modal-content">
<input type="text">
<br><br>
<button data-modal="#modal-container">CLOSE MODAL TEST</button>
</div>
</div>
This is working example. Think, it matches that one you need))
var clickTarget = null;
var modal = document.getElementById("modal-container");
function openModal() {
modal.classList.add("active");
document.body.addEventListener('mousedown', onModalMouseDown, false);
document.body.addEventListener('mouseup', onModalMouseUp, false);
}
function closeModal() {
modal.classList.remove("active");
document.body.removeEventListener('mousedown', onModalMouseDown);
document.body.removeEventListener('mouseup', onModalMouseUp);
}
function onModalMouseDown(event) {
clickTarget = event.target;
}
function onModalMouseUp() {
if (clickTarget === modal) {
closeModal();
}
}
html, body {
margin: 0;
height: 100%;
}
.modal-container.active { top: 0; }
.modal-container {
position: absolute;
top: -500vh;
left: 0;
width: 100%;
height: 100%;
display: grid;
background-color: rgba(0, 0, 0, 0.75);
}
.modal-content {
height: 50%;
width: 50%;
margin: auto;
background-color: #fff;
display: flex;
align-items: center;
justify-content: center;
}
.modal-trigger-btn {
margin: 20px;
font-size: 16px;
}
<button onmousedown="openModal();" class="modal-trigger-btn">Open the Modal</button>
<div id="modal-container" class="modal-container">
<div class="modal-content">
<input type="text" placeholder="Start to drag outside..."/>
</div>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With