Now I am not a star really with Javascript, but i seem to encounter the all known problem with mobile devices and the onclick function. Onclick requires a mouse action where off course on the phone that doesnt apply. Now in Jquery, you can use "on" .. but how does this work with regular javascript?
// Get the modal
var modal = document.getElementById('reserveer-modal');
// Get the button that opens the modal
var btn = document.getElementById("reserveer-knop");
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks the button, open the modal
btn.onclick = function() {
var x = window.innerWidth;
if (x > 768) {
//event.preventDefault();
modal.style.display = "block";
} else {
//event.preventDefault();
}
}
// When the user clicks on <span> (x), close the modal
span.onclick = function() {
modal.style.display = "none";
}
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
Try to change onclick to addEventListener and see if that helps you..
// When the user clicks the button, open the modal
btn.addEventListener('click', function () {
var x = window.innerWidth;
if (x > 768) {
//event.preventDefault();
modal.style.display = "block";
} else {
//event.preventDefault();
}
});
You can also pass named function to addEventListener
Binding the click event listener to the element should fix the problem you've been having.
btn.addEventListener("click", function() {
var x = window.innerWidth;
if (x > 768) {
//event.preventDefault();
modal.style.display = "block";
} else {
//event.preventDefault();
}
});
Alternatively, you could try using the touchstart event, which works just like the "mousedown" event, just for mobile.
elem.addEventListener("touchstart", handler);
Your code would look like this:
btn.addEventListener("touchstart", function() {
var x = window.innerWidth;
if (x > 768) {
//event.preventDefault();
modal.style.display = "block";
} else {
//event.preventDefault();
}
});
Had the same issue, after setting z-index to 100 it worked.
Seems like in my case there was a z-index issue.
Make sure you don't have any async/await functions in your code or any arrow functions () => {}. Mobile browsers seem to use older versions of JavaScript before async/await or arrow function were introduced.
Related
I am attempting to display a modal with results of a php query, after a button is submitted, but the modal flashes onto the screen, instead of remaining until it is manually closed, due to the fact that submitting a form refreshes the page.
<script>
var modal = document.getElementById("myModal");
var btn = document.getElementById("submitForm");
var span = document.getElementsByClassName("close")[0];
var form = document.getElementsByClassName("myForm")[0];
btn.addEventListener('click', openModal);
function openModal() {
form.submit();
modal.style.display = "block";
console.log("shiet");
}
span.addEventListener('click', closeModal);
function closeModal(){
modal.style.display = "none";
}
window.addEventListener('click', function(event){
if (event.target == modal) {
modal.style.display = "none";
}
});
</script>
On clicking the button id=submitForm, I want a modal to pop up, containing the results of a php script. This modal can then be closed by clicking off the screen or by activating closeModal, by clicking a span element.
Try this:
window.addEventListener('click', function(event){
if (event.target != modal) {
modal.style.display = "none";
} else {
modal.style.display = "block";
}
});
Here I meant that if the user is clicking on the window but not on the modal, then hide that; else keep the modal visible...
I think the modal flashes because of this reason!
I hope this works!
I'm trying to delay the load of a pop-up on a grid of images but want to prevent the ability to click on other images when this happens. Howver if I turn off onclick 'item.onclick = false', I don't seem to be able to turn it back on when the pop-up is turned back on? see line 'item.onclick = true'. Have also tried disabled = true/false but to no avail. Any suggestions?
var caseStudies = document.querySelectorAll('.posterImage');
var caseHover = document.querySelectorAll('.caseHover');
var modal = document.querySelectorAll('.modal');
caseStudies.forEach((button, index) => {
if ((isMobile == true) || (isTablet == true)) {
button.onclick = function(event) {
caseStudies.forEach((item) => {
item.onclick = false;
console.log(item);
});
caseHover.forEach((item) => {
item.classList.add('eventsNone');
console.log(item);
});
setTimeout(function(){
console.log("loading");
modal[index].style.display = "block";
// When the user clicks anywhere outside of the modal, close it (needs to live inside the button.onclick)
window.onclick = function(event) {
if (event.target == modal[index]) {
modal.forEach((item) => {
item.style.display = "none";
});
caseStudies.forEach((item) => {
item.onclick = true;
});
}
}
}, 500);
}
}
else
{
button.onclick = function(event) {
console.log("route2");
modal[index].style.display = "block";
caseStudies.forEach((item) => {
item.classList.add('eventsNone')
});
// When the user clicks anywhere outside of the modal, close it (needs to live inside the button.onclick)
window.onclick = function(event) {
if (event.target == modal[index]) {
modal.forEach((item) => {
item.style.display = "none";
});
caseStudies.forEach((item) => {
item.classList.remove('eventsNone')
});
};
};
};
};
});
Use an inline onclick = "function()" to set your onclick.
When disabling your onlick do it with element.onclick = null.
And enable it again with element.onclick = "function()"
Sorry for getting it wrong before I miss read it and thought you were doing it with buttons.
Also here is a duplicate question how to disable or enable all onClick for images on a page
The Issue
I'm looking to implement a flexible javascript solution to opening and closing multiple modal windows on the same page.
I have found way to open multiple modal windows in such a manner, but I can't for the life of me figure out how to close them by the click of a button or by clicking outside of the modal window itself.
Here is my javascript code:
var openModal = document.getElementsByClassName("open-modal");
for (var i = 0; i < openModal.length; i++) {
var thisOpenModal = openModal[i];
thisOpenModal.addEventListener("click", function() {
var modal = document.getElementById(this.dataset.modal);
modal.style.display = "block";
}, false);
}
(I didn't write this code myself, it's an edited copy of "pgk's" answer over on this page: Opening multiple modal boxes on one page)
I trigger the modal windows by adding the 'open-modal' class to my "buttons" and I use 'data-modal' in relation to the id's of the modal windows:
<div class="featurette-wrap featurette--anchor open-modal" data-modal="modal-microsoft-account">
Opprett konto
</div>
The button above triggers the modal window with the id of modal-microsoft-account:
<div class="modal" id="modal-microsoft-account">
Microsoft-konto
</div>
So my question is:How can I implement a way to close a modal window once it's opened?
I've tried doing this, but I can't get it to work (from W3schools):
// When the user clicks on <span> (x), close the modal
closeModal.onclick = function() {
modal.style.display = "none";
}
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
It's better to use event listeners to track actions on elements as I've done below;
also, making use of the setAttribute function when setting styles with Javascript ensures that every other style assigned to that element is overridden and the style you are setting always applies (except in cases where another style is set to be important)
var openModal = document.getElementsByClassName("open-modal");
for (var i = 0; i < openModal.length; i++) {
var thisOpenModal = openModal[i];
var targetModal = thisOpenModal.getAttribute('data-modal')
//get the id of the modal to open based on thisOpenModal
var thisTargetModal = document.getElementById(targetModal)
//get element
thisOpenModal.addEventListener("click", function(event) {
thisTargetModal.setAttribute('style', "display:block;")
//code to open modal on click of div with id=""
}, false);
// When the user clicks on <span> (x), close the modal
var closeModal = document.querySelector('#' + thisTargetModal.id, "span");
//code to listen to click event and change block style attribute to none on click
closeModal.addEventListener("click", function() {
thisTargetModal.setAttribute('style', "display:none;")
}, false)
// When the user clicks anywhere on the modal div, close it
window.addEventListener("click", function(event) {
//code to listen to click event on window and change block style attribute to none
if (event.target == targetModal) {
thisTargetModal.setAttribute('style', "display:none;")
}
})
}
<div class="featurette-wrap featurette--anchor open-modal" data-modal="modal-microsoft-account">
Opprett konto
</div>
<div class="modal" id="modal-microsoft-account" style="display:none;">
<p>Microsoft-konto </p>
<p>
<span id="close-modal">
x
</span>
</p>
</div>
So I actually ended up finding a solution that did exactly what I was looking for over at W3Schools forum: http://w3schools.invisionzone.com/topic/55976-multiple-modal-boxes-on-webpage/
This did the trick 🙌:
// Get the modal
var modal = document.getElementsByClassName("modal");
// Get the button that opens the modal
var openModal = document.getElementsByClassName("open-modal");
// Get the <span> element that closes the modal
var closeModal = document.getElementsByClassName("modal__close");
// When the user clicks the button, open the modal
function setDataIndex() {
for (i = 0; i < openModal.length; i++) {
openModal[i].setAttribute('data-index', i);
modal[i].setAttribute('data-index', i);
closeModal[i].setAttribute('data-index', i);
}
}
for (i = 0; i < openModal.length; i++) {
openModal[i].onclick = function() {
var ElementIndex = this.getAttribute('data-index');
modal[ElementIndex].style.display = "block";
};
// When the user clicks on <span> (x), close the modal
closeModal[i].onclick = function() {
var ElementIndex = this.getAttribute('data-index');
modal[ElementIndex].style.display = "none";
};
}
window.onload = function() {
setDataIndex();
};
window.onclick = function(event) {
if (event.target === modal[event.target.getAttribute('data-index')]) {
modal[event.target.getAttribute('data-index')].style.display = "none";
}
};
I have created a modal in my html file. I open it by clicking in a button and then I execute a method
This js method is the following:
openModal() {
var modal = document.getElementById('myModal');
modal.style.display = "block";
}
and it works. Now what I want to do is to close it by clicking in the body of my website so I have added 3 lines:
openModal() {
var modal = document.getElementById('myModal');
modal.style.display = "block";
$(document).on('click', 'body *', function () {
modal.style.display = "none";
});
}
The problem seems to be that one click on my mouse is more than one to the computer so it always executes:
modal.style.display = "block";
and then with the same click he calls also the click of:
$(document).on('click', 'body *', function () {
modal.style.display = "none";
});
and it executes it`
I have also created a listener:
openModal() {
var modal = document.getElementById('myModal');
modal.style.display = "block";
modal.addEventListener('click', function () {
$(document).on('click', 'body *', function () {
modal.style.display = "none";
});
});
}
and it works for the first time but after closing it the listener keeps working so I can not do anything else (it always executes the listener line)
UPDATE
I have tried also:
openModal() {
console.log("OpenModal")
var modal = document.getElementById('myModal');
modal.style.display = "block";
modal.addEventListener('click', function () {
console.log("EventListener")
$(document).on('click', 'body *', function () {
modal.style.display = "none";
modal.removeEventListener('mousemove', function () { console.log("NoEventListener") });
});
});
}
the behavior is the following:
I click on one button, and I call to openModal (console.log("OpenModal") is working). The modal appears, I click on body and the event is triggered (console.log("EventListener") is displayed). After it, it does not appear console.log("NoEventListener") so removeEventListener is not working.
Then, when I click again to the button, I call again to addEventListener directly.
What I need is to finish the eventListener
You need to detect where is clicked into. Is the click is into .modal.
$(document).on('click', function (e) {
if (!$(e.target).parents('.modal').length || ! $(e.target).is('.modal')) {
modal.style.display = "none";
}
});
In your modal function, you can get the current display style and change display
according to its value :
openModal() {
var modal = document.getElementById('myModal');
var statut = modal.style.display;
if (x === "block" {
modal.style.display = "none";
}
else {
modal.style.display = "none";
}
}
I'm using JS modal (no jquery), since I have some issues with that approach...
Everything works good except that on mobile user can't close it.
var modal = document.getElementById('myModal');
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
};
It is probably related to that touch that I'm missing...
I tried with jquery like this:
$(document).ready(function(){
$(modal).on('click touchstart', function() {
modal.style.display = "none";
});
});
The problem here is that if user clicks inside the modal, it will also disappear...
What I need is that when user clicks only outside, modal should disappear...
Any ideas how can I solve this issue?
Thanks.
instead of registering click on the target, register on the document and then check to see that the mouse wasn't inside of the target
$(document).on ('mouseup touchstart', function (e)
{
var container = $("#myModal");
if (!container.is(e.target) // if the target of the click isn't the container...
&& container.has(e.target).length === 0) // ... nor a descendant of the container
{
container.hide();
}
});
You can listen for the 'mousedown' event on the document, then check if the modal is in the event path. If it's not, then hide the modal. If it is, then do nothing.
var myModal = document.getElementById('myModal');
document.addEventListener('mousedown', function(e)
{
if (e.path.indexOf(myModal) == -1)
myModal.hidden = true;
});
Have you tried to use contains ?
I just tested it on iOS safari and chrome, it works correctly
please check out the demo,
when you click the yellow part, it still exists
however, when you click the pink part, the whole modal will hide
JS Bin
code in JS Bin
var pa = document.querySelector('#modal-overlay');
var ch = document.querySelector('#modal-container');
pa.addEventListener('click', function(e) {
if (!ch.contains(e.target)) {
pa.style.display = 'none';
}
});