Prevent horizontal scrolling on javascript modal open using css - javascript

my website is basically a horizontal scrolling website, i have a modal inside it, so when the modal is open, the user is able to scroll horizontally with the scroller button in mouse, i tried the following css to stop it but it doesnt work:
body.modal-open {
overflow: hidden;
position: fixed;
}
my modal javascript is like below:
var modal = document.getElementById("myModals");
var btn = document.getElementById("myBtns");
var span = document.getElementsByClassName("closes")[0];
btn.onclick = function() {
modal.style.display = "block";
}
span.onclick = function() {
modal.style.display = "none";
}
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
can anyone tell me how to accomplish this, thanks in advance

You can prevent horizontal scrolling on a JavaScript modal by adding the following CSS to your modal's container element:
overflow-x: hidden;
body.modal-open {
overflow: hidden;
}
html.modal-open {
overflow: hidden;
}
.modal {
position: fixed;
}

Related

How to remove all scrolling and click events when displaying Overlay in CSS

I have an Overlay that I display on a webpage while some SQL is performed in the background, this SQL can take a good few seconds, so I set this Overlay to be on the screen for 10 seconds using JavaScript. What I want to do, is prevent the user from clicking, and scrolling altogether while this Overlay is visible.
I have the pointer events set to 'none' which doesn't seem to work, even with a high z-index, and displaying as 'block'. For some reason, when the Overlay is displayed, the user can still scroll, click, and highlight text just like the overlay is not even there.
This is my Overlay in CSS:
#overlay {
position:fixed;
display: block;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(120, 120, 120, 0.9);
pointer-events: none;
z-index:100000;
}
My JavaScript:
//The function to start displaying the overlay
function start()
{
document.getElementById("overlay").style.display = "block";
}
//The function to stop displaying the overlay
function end()
{
alert("Finished!");
document.getElementById("overlay").style.display = "none";
}
setTimeout(function() { start(); }, 1); //starting the Overlay
setTimeout(function() { end(); }, 10000); //ending the Overlay after 10 seconds
You should disable scrolling by add overflow: hidden to body
function start()
{
document.getElementById("overlay").style.display = "block";
document.getElementsByTagName("body")[0].style.overflow = "hidden";
}
//The function to stop displaying the overlay
function end()
{
alert("Finished!");
document.getElementById("overlay").style.display = "none";
document.getElementsByTagName("body")[0].style.overflow = null;
}
Remove pointer-events: none to allow the user to click on the overlay, and add user-select:none; instead.
This way, the user can not select anything on the overlay. The user will only be able to resume selection on the other parts of the page once the overlay is hidden.
function start() {
document.getElementById("overlay").style.display = "block";
}
//The function to stop displaying the overlay
function end() {
document.getElementById("overlay").style.display = "none";
console.log('Finished');
}
setTimeout(function() {
start();
}, 1); //starting the Overlay
setTimeout(function() {
end();
}, 10000); //ending the Overlay after 10 seconds
#overlay {
position: fixed;
display: block;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(120, 120, 120, 0.9);
z-index: 100000;
user-select: none;
overflow: hidden;
/* not really needed, but this prevents scroll bars from appearing */
}
#main {
background-color: #bada55;
display: inline-block;
padding: 5em;
margin: auto;
}
<div id="overlay">
<p>
This is part of the overlay inner HTML
</p>
</div>
<div id="main">
This is something not inside the overlay
</div>

Transition effect isn't working on div toggle

Why my menu toggle is not smooth transition? I've added transition 200ms and it doesn't work at all. How can I fix this?
#sidebar-container2
min-height: 100vh
width: 80px
display: none
transition: 200ms
#sidebar-container
min-height: 100vh
methods: {
sidebar() {
var menu = document.querySelector('#sidebar-container');
var menuSmall = document.querySelector('#sidebar-container2');
menuSmall.style.display = "block";
menu.style.display = "none";
},
openbar() {
var menu = document.querySelector('#sidebar-container');
var menuSmall = document.querySelector('#sidebar-container2');
menuSmall.style.display = "none";
menu.style.display = "block";
}
You can't do transitions with display, however you can do so with opacity and visibility: Transitions on the CSS display property

div loses focus, when clicked on a child which has focus

So, I am making a modal which has focus on it when it is shown.
And if the user clicks outside, I want to hide it.
I have implemented this with the help of focus events.
In cases, where the modal itself has a child which is focusable, modal loses the focus, I have also handled it in the below code. These cases are correctly handled by onFocusLoss but not by onFocusLoss2.
function onClickButton() {
var modal = document.getElementById('modal');
modal.style.visibility = 'visible';
modal.focus();
}
function onFocusLoss() {
var modal = document.getElementById('modal');
setTimeout(function() {
var activeEl = document.activeElement;
if (modal !== activeEl && !modal.contains(activeEl)) {
modal.style.visibility = 'hidden';
}
}, 0);
}
function onFocusLoss2() {
var modal = document.getElementById('modal');
var activeEl = document.activeElement;
if (modal !== activeEl && !modal.contains(activeEl)) {
modal.style.visibility = 'hidden';
}
}
#modal {
position: fixed;
visibility: hidden;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 1px solid red;
}
#modal > div {
padding: 16px;
}
<button onclick='onClickButton()'>Show Modal</button>
<div id='modal' tabindex='-1' onfocusout='onFocusLoss()'>
<div>Focus Test</div>
<div>
<input>
</div>
</div>
This is how I assume focus events are going, when the modal is focused and then I click inside input,
then first the modal loses focus, the body is the active element, and then the input element becomes the active element, and body loses focus.
Thus, the reason maybe that onFocusLoss2 is not handling the case because activeEl at that time is the body, while in onFocusLoss, the activeEl is the input.
My question is, why one approach is working and the other is not? I want a good technical reason. If your answer is that it gives enough time so that input element gains focus, I want to know how can you say that the time is enough and will always work?
My solution is based on this answer, though.
May wish to change your mind. When the modal is focused, add a click event to the element below it to close the modal.
<body>
<button onclick='onClickButton()'>Show Modal</button>
<div id='modal' tabindex='-1'>
<div>Focus Test</div>
<div>
<input>
</div>
</div>
</body>
function onClickButton() {
const modal = document.getElementById('modal');
modal.style.visibility = 'visible';
modal.focus();
document.body.addEventListener('click', ()=>{
modal.style.visiable = 'hidden'
})
}
Don't forget to adjust modal's z-index to make sure it's above the body.
Just like #RiverTwilight, I'm removing the focus need and simply adding an onClick event.
I placed a <div> inside your #modal and made #modal fill the whole screen, this way you can use different animations and other techniques to also animate your content as long as #modal doesn't have padding.
I hope you get your answer. ✌️
function onClickButton() {
var modal = document.getElementById('modal');
modal.style.visibility = 'visible';
modal.focus();
}
function onModalBGClick(e) {
var modal = document.getElementById('modal');
var activeEl = e.target;
if (activeEl === modal) {
modal.style.visibility = 'hidden';
}
}
#modal {
position: fixed;
visibility: hidden;
top: 0;
bottom: 0;
right: 0;
left: 0;
}
.modal-inner {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 1px solid red;
}
#modal > div {
padding: 16px;
}
<button onclick='onClickButton()'>Show Modal</button>
<div id='modal' onclick='onModalBGClick(event)'>
<div class="modal-inner">
<div>Focus Test</div>
<div>
<input>
</div>
</div>
</div>

Why is my JavaScript code ruining my styling?

I am making a login modal and want the content to be centered horizontally and vertically. My CSS has it centered how I want it, but when I added the JavaScript, it is only centered horizontally. What's wrong with my code? thanks!
I tried flexbox and every other centering method I know. It just doesnt make sense because if I comment out the JavaScript, the modal content is where I want it to be!
// Get the modal
var modal = document.getElementById('login-modal');
// Get the button that opens the modal
var btn = document.getElementById("login");
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks on the button, open the modal
btn.onclick = function() {
modal.style.display = "block";
}
// 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";}
}
#login-modal{
width:100%;
height:100%;
background-color:rgba(0, 0, 0, 0.5);
position:absolute;
top:0;
left:0;
display:flex;
justify-content: center;
align-items: center;
text-align:center;
}
.login-content{
border: 10 px solid black;
height:12%;
width:20%;
background-color:white;
display:block;
text-align:center;
}
input[type=text], input[type=password]{
display:block;
margin: 0 auto;
}
When you want to initially hide something without regard to its display type in CSS, you can create the element with an inline display attribute of style="display: none;" in its HTML tag or, if creating the element in JavaScript, with element.style.display="none".
After that, you can display an element by deleting its element.style.display property. The element reverts to whatever display type was given to it in CSS.
To hide it, add back element.style.display="none";
Using this approach, the modal should always appear as styled in CSS. However, don't try to change its display type to anything except none anywhere else in JavaSript!
To specifically answer the question, inline style attribute values have absolute priority over rules provided in CSS.

Can't close popup with touch without a specific button in ios

I am learning now how to create popups in mobile devices, and I created a popup that closes when I touch any part of the screen, but it doesn't work on ios (maybe on all touch devices, haven't checked), only on the computer.
Now based on the information I read here:
jQuery click events not working in iOS
Make onclick work on iphone
How to bind 'touchstart' and 'click' events but not respond to both?
Cannot close popup() window in iPhone Safari
The popup opens fine because you press a link attribute <a> to open it up, however upon closing I can press any part of the screen.
Here is the code:
var modal = document.getElementById('myModal'); // Get the popup
var btn = document.getElementById("myBtn"); // Get the button that opens the popup
btn.onclick = function() { // Open the popup
modal.style.display = "block";
}
window.onclick = function(event) { // Closes the popup
if (event.target == modal) {
modal.style.display = "none";
}
}
I tried adding cursor: pointer; in CSS, changing the script in javascript to onmouseover instead of click, changing the script, changing window.click to div.click and adding the following code to the javascript script:
let touchEvent = 'ontouchstart' in window ? 'touchstart' : 'click';
window.on(touchEvent, function(event){...});
Nothing worked...
I guess I don't quite get how to use the touch event listener, if it's connected.
You need to add event listeners for touchstart and/or touchend for this to work on mobile devices, check out the snippet below:
// JavaScript
var modal = document.getElementById('myModal'); // Get the popup
var btn = document.getElementById("myBtn"); // Get the button that opens the popup
btn.onclick = function() { // Open the popup
modal.style.display = "block";
}
let eventsArray = ["click","touchstart", "touchend"];
eventsArray.forEach( function(event) {
window.addEventListener(event, function(e) {
if (e.target === modal) {
modal.style.display = "none";
}
}, false);
});
/*CSS*/
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
#myModal {
display: none;
position: fixed;
top: 0;
left: 50%;
transform: translateX(-50%);
background-color: rgba(0, 0, 0, 0.25);
width: 100%;
height: 100%;
text-align: center;
}
#myModal span {
position: fixed;
top: 50%;
left: 50%;
padding: 10px;
background-color: #a600a6;
color: #fff;
transform: translate(-50%, -50%);
}
<!--HTML-->
<body class="overlay">
<div >
<button id="myBtn">
Open Modal
</button>
</div>
<div id="myModal">
<span>Hello World!</span>
</div>
</body>
Tested on jsfiddle with an iPad and it works.

Categories

Resources