I have got a video that appears in a light box from you tube, a custom one not a plugin.
On mobile when displayed portrait the video spans the full page width which looks nice and leaves some room at the top and bottom to click out.
The issue is when I go landscape the video fills the full screen and you cannot get back onto the page. My initial reaction was to hit the phones back button but I don't know a way of getting this to simply remove my lightbox. Is there a way in JS of getting a onclick off the phones back button?
The reason it goes full screen is because I am keeping the aspect ratio
var width: number = $('.youtube-video-lightbox').outerWidth();
var height: number = (width / 16) * 9;
$('.youtube-video-lightbox').height(height);
You can try using the following code:
You need to listen to navigation event and state.direction.
$(window).on("navigate", function (event, data) {
var direction = data.state.direction;
if (direction == 'back') {
// close the light box here
}
if (direction == 'forward') {
// do something else
}
});
More details in this link
Tested the above code in my mobile and it works fine. You might need to stop the program flow after closing the light box so that default navigation of the back button is stopped.
Weave: http://kodeweave.sourceforge.net/editor/#e110ed7e89c3a38335739656a02f9850
Have you thought of trying a Pure CSS Based Lightbox?
$('[data-target]').on('click', function() {
$('.page').attr('src', $(this).attr('data-target'));
});
$('#call').on('change', function() {
(this.checked) ? "" : $('.page').attr('src', '');
});
input[id=call] {
display: none;
}
a {
margin: 1em;
}
.bg,
.content {
opacity: 0;
visibility: hidden;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
transition: all ease-in 150ms;
}
.bg {
background: #515151;
background: rgba(0, 0, 0, 0.58);
}
.content {
margin: 2.6352em;
padding: 1em;
background: #fff;
}
input[id=call]:checked ~ .bg,
input[id=call]:checked ~ .content {
visibility: visible;
opacity: 1;
}
.block {
display: block;
}
.pointer {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="call" type="checkbox" />
<p>
<a href="javascript:void(0)" data-target="http://bing.com/" class="pointer block">
<label for="call" class="pointer">Bing</label>
</a>
<a href="javascript:void(0)" data-target="http://duckduckgo.com/" class="pointer block">
<label for="call" class="pointer">DuckDuckGo</label>
</a>
</p>
<label for="call" class="bg pointer"></label>
<div class="content">
<iframe width="100%" height="100%" frameborder="0" class="page"></iframe>
</div>
Related
I'm trying to make a slideshow with smooth transitions on a website a person requested me to make.
For example, when I click next, the current slide (a div with text and buttons) with fade out and the next slide will reveal.
Here is the HTML (edited thanks to a headstarter):
<div id="ssContainer">
<div class="slideshow" id="selected">
<img src="images/slideshow/1.jpg" />
<div class="ssText">
<h1>Welcome to White Grass</h1>
<p>Your complete solution to home building</p>
<button id="portfolioBtn">See Our Portfolio</button>
</div>
</div>
<div class="slideshow">
<img src="images/slideshow/2.jpg" />
<div class="ssText">
<h1>Custom Home Builder</h1>
<p>Customer satisfaction is our top priority</p>
</div>
</div>
<div class="slideshow">
<img src="images/slideshow/3.jpg" />
<div class="ssText">
<h1>Professional & Experienced</h1>
<p>A history of exceptional homes</p>
<button id="contactBtn">Contact Us Now</button>
</div>
</div>
<img id="prev" alt="Previous Slide" onclick="prev();" src="images/slideshow/leftarrow.png"></img>
<img id="next" alt="Next Slide" onclick="next();" src="images/slideshow/rightarrow.png"></img>
</div>
And the CSS:
.slideshow {
display: none;
height: 100%;
position: relative;
transition: display 0.2s;
}
.slideshow img {
max-width: 100%;
max-height: 100vh;
margin: auto;
}
.ssText {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.ssText * {
text-align: center;
}
.ssText h1 {
font-size: 2.5em;
text-transform: uppercase;
background-color: rgba(0, 0, 0, 50%);
padding: 5px;
}
.ssText p {
font-size: 1.1em;
background-color: rgba(0, 0, 0, 50%);
padding: 5px;
}
.ssText button {
position: absolute;
}
#prev, #next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
margin-top: -22px;
padding: 10px;
transition: background-color 0.2s;
}
#next {
right: 0;
}
#prev:hover, #next:hover {
background-color: rgba(0, 0, 0, 50%);
}
#selected {
display: block !important;
}
#portfolioBtn {
left: 26%;
transform: translateX(26%);
}
#contactBtn {
left: 29%;
transform: translateX(29%);
}
button {
display: block;
border: none;
background-color: #0074c2;
padding: 15px;
font-size: 1em;
font-family: roboto;
color: white;
border-radius: 3px;
transition: background-color 0.2s;
}
Also, the font is Roboto. I added that in the body section of the CSS.
And here are the images:
1.jpg
2.jpg
3.jpg
leftarrow.png (Chevron Left Icon by Icons8)
rightarrow.png (Chevron Right Icon by Icons8)
I got a pretty basic concept of the JavaScript now thanks to an answer:
var slideIndex = 1;
var slides = document.getElementByClassName("slideshow");
function prev() {
if(slideindex < 1) {
slideindex = 3;
}
else {
slideindex--;
}
showSlides();
}
function next() {
if(slideIndex > 3) {
slideIndex = 1;
}
else {
slideIndex++;
}
showSlides();
}
function showSlides() {
if(slideIndex == 1) {
slides[0].id = "selected";
slides[1].id = "";
slides[2].id = "";
}
else if(slideIndex == 2) {
slides[0].id = "";
slides[1].id = "selected";
slides[2].id = "";
}
else if(slideIndex == 3) {
slides[0].id = "";
slides[1].id = "";
slides[2].id = "selected";
}
}
Now, here's the problem:
With the display transition, the images don't transition from block to none.
I even tried messing with the opacity. Gives me the animation but not the slideshow feel.
Changed code for .slideshow and #selected section but reverted:
.slideshow {
display: block;
height: 100%;
position: relative;
opacity: 0;
transition: opacity 0.2s;
}
#selected {
opacity: 1 !important;
}
How do I fix this? Also, tried messing with z-index.
Also, I have to click the previous and next button twice to change from slide 3 to 1 or slide 1 to 3. Weird. Would also want a fix for this.
No jQuery, or any external JS scripts besides my own, please.
Well, this question doesn't comply with Stackoverflow in the way that we expect you to show what you have try and show what you researched. Now you are mostly asking us to write code for you.
Some research and reading will help you get a start on the subject:
how to create transition css javascript
But hey! I've been there too, so, I'll try to give you an example.
DON'T USE THIS CODE
This is only for example purposes and it won't achieve exactly what you are asking for. This code only fades the image background and you are trying to change the whole block of code including the image and text.
The goal behind what follows is only to help you get an idea on how things work.
Let's say that you only want to fade in and fade out your slide. For that, I would use opacity CSS property.
.slideshow img {
max-width: 100%;
max-height: 100vh;
margin: auto;
opacity: 0;
transition: opacity 2s;
}
That said, you will have to add some IDs and your function to your clickable images:
<img id="slide1" src="images/slideshow/1.jpg" />
<img id="slide2" src="images/slideshow/2.jpg" />
<img id="slide3" src="images/slideshow/3.jpg" />
<img id="prev" alt="Previous Slide" onclick="fadeTransition('prev')" src="images/slideshow/leftarrow.png"></img>
<img id="next" alt="Next Slide" onclick="fadeTransition('next')" src="images/slideshow/rightarrow.png"></img>
And then, there is some javacript to help you start with it
var currentSlide = 1;//You need a var that contain the current slide that is show
function fadeTransition(side) {
if ((side === 'prev' && currentSlide === 1) || (side === 'next' && currentSlide === 3)) {return;}
if (side === 'prev') {var newSlide = currentSlide - 1;}
if (side === 'next') {var newSlide = currentSlide + 1;}
document.getElementById('slide'+currentSlide).style.opacity = 0;
document.getElementById('slide'+newSlide).style.opacity = 1;
currentSlide = newSlide;
return;
}
There us a problem with that , on load, all your image will be at opacity 0. You'll have to change the initial state of the first image. At this point, I'll use a class like
.in {
opacity: 1 !important;
}
And into the Javascript, instead of changing style.opacity I would add and remove the in class and adding it into the HTML for load purposes:
<img id="slide1" class="in" src="images/slideshow/1.jpg" />
javascript change class
So now, most of the previous Javascript code blocks are unusable. Keep it in mind that you have to store what the current displayed block is. Restrict your code so the user can't get to a point where he's going to a previous slide when the current slide is the first one.
I hope this will help you in achieving your goal.
I have a webpage where there is a full height intro image. Underneath this image is the main body of the site with a regular site header at the top, I'm trying to create an effect where once the user scrolls down to the site header, they cannot scroll back up to view the intro image.
CSS Classes:
Main Intro Image: .cq-fullscreen-intro
Site Header: .nav-down
I had a poke around on StackOverflow but I can't find anything that addresses this circumstance, can anyone point me in the right direction to achieve this using jQuery?
you can use JQuery scrollTop function like this
$(function() {
$(window).scroll(function() {
var scroll = $(window).scrollTop();
// set the height in pixels
if (scroll >= 200) {
// after the scroll is greater than height then you can remove it or hide it
$(".intro-image").hide();
}
});
});
So instead of scrolling, I personally think it would be better to have it be actionable. Forcing the user to manually do the transition (and all in between states) is a bad idea. If the user scrolls half way, and see's something actionable (menu, button, input field) is it usable? If it is, what happens if they submit... very awkward. If it isn't usable, how do they know when it is? How do they know it's because they haven't scrolled all the way. It's very poor user experience.
In the following example, I've created a pseudo-screenport for you to see what's actually going on. The .body container in your real site would be the body element.
Code Pen Example
$(document).ready(function(){
$('.splash-screen').on('click', function(){
$('.splash-screen').addClass("is-hidden");
});
})
html, body{
background: #eee;
margin: 0;
padding: 0;
}
.flex-root {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
width: 100vw;
}
.web-container {
width: 640px;
height: 480px;
background: #fff;
}
.body {
font-size: 0; // this is only to prevent spacing between img placholders
position: relative;
}
.splash-screen{
position: absolute;
transition: transform 1s ease-in-out;
}
.splash-screen .fa {
position: absolute;
z-index: 1;
font-size: 24px;
color: #fff;
left: 50%;
bottom: 15px;
}
.splash-screen.is-hidden {
transform: translateY(-110%);
transition: transform 1s ease-in-out;
}
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="flex-root">
<div class="web-container">
<div class="body">
<div class="splash-screen">
<img src="https://via.placeholder.com/640x480?text=Splash+Screen"/>
<i class="fa fa-chevron-circle-up"></i>
</div>
<img src="https://via.placeholder.com/640x60/cbcbcb?text=Menu"/>
<img src="https://via.placeholder.com/640x420/dddddd?text=Site Body"/>
<div>
</div>
</div>
While its not direclty preventing you from scrolling up and its not jQuery, I would suggest to remove/hide the element once its out of view.
You could get the current scroll position, relative to the top of the page, and check if its greater than the elements height:
const target = document.getElementById('my-target')
const targetHeight = target.getBoundingClientRect().height
const scrollEventListener = () => {
if (
document.body.scrollTop > targetHeight ||
document.documentElement.scrollTop > targetHeight
) {
target.remove()
window.removeEventListener('scroll', scrollEventListener)
document.documentElement.scrollTop = 0
}
}
window.addEventListener('scroll', scrollEventListener)
Here is a codepen https://codepen.io/bluebrown/full/aboagov
I'm currently working on a project where the desired user experience involves a very customized interaction with scroll events.
Problem to solve:
The page has X sections, each of them with a height equal to the viewport hight height: 100vh;. When a user scrolls down on the viewport, the current visible section stays where it is and a scroll indicator animates based on a threshold of distance scrolled (30px, for example). Once the user has scrolled the threshold, the next section comes up from the bottom of the screen and covers up the current section (which still doesn't move).
Initial Approach:
Set each section to an absolute position and adjust them with by changing CSS classes based on the scrollwheel event. Body overflow:hidden and transform property to manipulate the sections. I am running in to issues, though.
The scrollwheel event seems to be documented as very unstable solution to implement.
The .wheelDelta aspect of the event fires asynchronously and is difficult to capture a gesture with. (On chrome, it just spits out a multiple of 3 a bunch of times rather than a distance of the gesture in px). This makes it difficult to set a threshold and animate the elements that are responsive to that threshold.
I basically want to be able to track the number of pixels a scrollwheel-like event is covering and apply that number to the position of a certain scroll-hint element until the scroll threshold is met. Once it is met, a function fires to change the classes and update some information on the page. If the threshold is not met, the scroll hint element goes back to it's default position.
My attached approach doesn't feel very conducive to accomplishing this, so I'm looking for either 1) a different and more stable approach or 2) revisions / criticisms on what I'm doing wrong with this approach to make it stable.
(function scrollerTest($){
$('body').on ('mousewheel', function (e) {
var delta = e.originalEvent.wheelDelta,
currentScreenID = $('section.active').data('self').section_id,
currentScreen = $('section.part-' + currentScreenID),
nextScreenID = currentScreenID + 1,
nextScreen = $('section.part-' + nextScreenID);;
if (delta < 0) { // User is Scrolling Down
currentScreen.removeClass('active').addClass('top');
nextScreen.removeClass('bottom').addClass('active')
} else if (delta > 0) { // User is Scrolling Up
}
});
}(jQuery));
body {
overflow: hidden;
padding: 0;
margin: 0;
}
section {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100vh;
z-index: 999;
background-color: #CA5D44;
transition: 0.8s all ease-in-out;
}
section.part-1 {
position: relative;
z-index: 9;
}
section.part-2 {
background-color: #222629;
}
section.active {
transform: translateY(0);
}
section.top {
transform: translateY(-10%);
}
section.bottom {
transform: translateY(100%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<body>
<section class="part-1 home active" data-self='{ "section_id" : 1, "section_title" : "Home", "menu_main_clr" : "#fff" , "menu_second_clr" : "#CA5D44", "logo_clr" : "white" }'>
</section>
<section class="part-2 about bottom" data-self='{ "section_id" : 1, "section_title" : "About", "menu_main_clr" : "#CA5D44" , "menu_second_clr" : "#fff", "logo_clr" : "white" }'>
</section>
<section class="part-3 contact bottom" data-self='{ "section_id" : 1, "section_title" : "Contact", "menu_main_clr" : "#fff" , "menu_second_clr" : "#CA5D44", "logo_clr" : "white" }'>
</section>
</body>
Edit Note:
The snippet seems to have some issue with firing the event and changing classes after the first instance - not sure why. On my local example it fires them all at once..
**Edite Note 2: **
Listed code is just a copy of the closest behaviour I could achieve. The whole threshold functionality seems pretty unattainable with this method, unfortunately, as the wheel event doesn't behave like a scroll event.
the whole scroll topic is rather complex especially when you think about touch scroll events, too.
There are some libraries out there - see this list for example: http://ninodezign.com/30-jquery-plugins-for-scrolling-effects-with-css-animation/
I used https://projects.lukehaas.me/scrollify/ before and it might allow you to do what you intend (using the before callback eventually) but I can't tell without trying myself. Also regard that scrollify is relatively big (8kb minified) in comparison to other libraries.
You can approach this using by ensuring each content-filled section is followed by a blank transparent gap (in the example below, also 100vh in height) and then using javascript to apply position:fixed to each content-filled section when it hits the top of the viewport.
Example:
var screens = document.getElementsByClassName('screen');
function checkPosition() {
for (var i = 0; i < (screens.length - 1); i++) {
var topPosition = screens[i].getBoundingClientRect().top;
if (topPosition < 1) {
screens[i].style.top = '0';
screens[i].style.position = 'fixed';
}
}
}
window.addEventListener('scroll',checkPosition,false);
.screen {
position: absolute;
display: block;
left: 0;
width: 100%;
height: 100vh;
}
.red {
position: fixed;
top: 0;
background-color: rgb(255,0,0);
}
.orange {
top: 200vh;
background-color: rgb(255,140,0);
}
.yellow {
top: 400vh;
background-color: rgb(255,255,0);
}
.green {
top: 600vh;
background-color: rgb(0,191,0);
}
.blue {
top: 800vh;
background-color: rgb(0,0,127);
}
p {
font-size: 20vh;
line-height: 20vh;
text-align: center;
color: rgba(255,255,255,0.4);
}
<div class="red screen">
<p>Screen One</p>
</div>
<div class="orange screen">
<p>Screen Two</p>
</div>
<div class="yellow screen">
<p>Screen Three</p>
</div>
<div class="green screen">
<p>Screen Four</p>
</div>
<div class="blue screen">
<p>Screen Five</p>
</div>
My divs are not showing when I click on submit.
I can get them to show if I do a window.onload() but the divs have to have display: none; by default;
How can I make it so these divs show when I hit submit because my form takes about 30 seconds to process, it has a lot of fields.
HTML
<div id="overlay-back"></div>
<div id="overlay">
<div id="dvLoading">
<p>Please wait<br>while we are loading...</p>
<img id="loading-image" src="img/ajax-loader.gif" alt="Loading..." />
</div>
</div>
Submit Button
<div class="form-buttons-wrapper">
<button id="submit" name="submit" type="submit" class="form-submit-button">
Submit
</button>
</div>
CSS
#overlay {
position : absolute;
top : 0;
left : 0;
width : 100%;
height : 100%;
z-index : 995;
display : none;
}
#overlay-back {
position : absolute;
top : 0;
left : 0;
width : 100%;
height : 100%;
background : #000;
opacity : 0.6;
filter : alpha(opacity=60);
z-index : 990;
display : none;
}
#dvLoading {
padding: 20px;
background-color: #fff;
border-radius: 10px;
height: 150px;
width: 250px;
position: fixed;
z-index: 1000;
left: 50%;
top: 50%;
margin: -125px 0 0 -125px;
text-align: center;
display: none;
}
jQuery
<script>
$(function() {
$('#submit').on('submit', function() {
$('#dvLoading, #overlay, #overlay-back').prop("display", "block").fadeIn(500);
});
});
</script>
The reason I am displaying none by default in css because if someone has javascript disabled I do not want any inteference
Please provide your own custom form validation as I have no context to supplement that. This should be placed in a document ready OR in a setInterval JavaScript function (the latter typically yeilds much better results).
$('button#submit').click(function() {
If (formValid === true && $('#dvLoading, #overlay, #overlay-back').not(':visible');)
{
$('#dvLoading, #overlay, #overlay-back').toggle(500);
$('button#submit').toggle(500); //hide this to prevent multiple clicks and odd behavior
} else {
var doNothing = "";
}
});
Try this:
<script>
$(function() {
$('#submit').on('click', function(evt) {
evt.preventDefault();
$('#dvLoading, #overlay, #overlay-back').fadeIn(500);
});
});
</script>
The fadeIn will make the div visible.
.prop sets the properties of the element, not the style.
Changed to use the click event
I created a jQuery popup by following an online tutorial (http://uposonghar.com/popup.html).
Due to my low knowledge on jQuery I am not able to make it work as of my requirements.
My problem:
I want to disable scroll of webpage while popup is active.
Background fade color of popup while active is not working on full webpage.
CSS:
body {
background: #999;
}
#ac-wrapper {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255,255,255,.6);
z-index: 1001;
}
#popup{
width: 555px;
height: 375px;
background: #FFFFFF;
border: 5px solid #000;
border-radius: 25px;
-moz-border-radius: 25px;
-webkit-border-radius: 25px;
box-shadow: #64686e 0px 0px 3px 3px;
-moz-box-shadow: #64686e 0px 0px 3px 3px;
-webkit-box-shadow: #64686e 0px 0px 3px 3px;
position: relative;
top: 150px; left: 375px;
}
JavaScript:
<script type="text/javascript">
function PopUp(){
document.getElementById('ac-wrapper').style.display="none";
}
</script>
HTML:
<div id="ac-wrapper">
<div id="popup">
<center>
<p>Popup Content Here</p>
<input type="submit" name="submit" value="Submit" onClick="PopUp()" />
</center>
</div>
</div>
<p>Page Content Here</p>
A simple answer, which you could use and would not require you to stop the scroll event would be to set the position of your #ac-wrapper fixed.
e.g.
#ac-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255,255,255,.6);
z-index: 1001;
}
this will keep the container of the popup always visible (aligned top - left) but would still allow scrolling.
But scrolling the page with a popup open is BAD!!! (almost always anyway)
Reason you would not want to allow scrolling though is because if your popup isn't fullscreen or is semi transparent, users will see the content scroll behind the popup. In addition to that, when they close the popup they will now be in a different position on the page.
A solution is that, when you bind a click event in javascript to display this popup, to also add a class to the body with essentially these rules:
.my-body-noscroll-class {
overflow: hidden;
}
Then, when closing the popup by triggering some action or dismissing it with a click, you simply remove the class again, allowing scroll after the popup has closed.
If the user then scrolls while the popup is open, the document will not scroll. When the user closes the popup, scrolling will become available again and the user can continue where they left off :)
To disable scrollbar:
$('body').css('overflow', 'hidden');
This will hide the scrollbar
Background-fade-thing:
I created my own popup-dialog-widget that has a background too. I used the following CSS:
div.modal{
position: fixed;
margin: auto;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 9998;
background-color: #000;
display: none;
filter: alpha(opacity=25); /* internet explorer */
-khtml-opacity: 0.25; /* khtml, old safari */
-moz-opacity: 0.25; /* mozilla, netscape */
opacity: 0.25; /* fx, safari, opera */
}
I had a similar problem; wanting to disable vertical scrolling while a "popup" div was displayed.
Changing the overflow property of the body does work, but also mess with the document's width.
I opted jquery to solve this using and used a placeholder for the scrollbar.
This was done without binding to the scroll event, ergo this doesn't change your scrollbar position or cause flickering :)
HTML:
<div id="scrollPlaceHolder"></div>
CSS:
body,html
{
height:100%; /*otherwise won't work*/
}
#scrollPlaceHolder
{
height:100%;
width:0px;
float:right;
display: inline;
top:0;
right: 0;
position: fixed;
background-color: #eee;
z-index: 100;
}
Jquery:
function DisableScrollbar()
{
// exit if page can't scroll
if($(document).height() == $('body').height()) return;
var old_width = $(document).width();
var new_width = old_width;
// ID's \ class to change
var items_to_change = "#Banner, #Footer, #Content";
$('body').css('overflow-y','hidden');
// get new width
new_width = $(document).width()
// update width of items to their old one(one with the scrollbar visible)
$(items_to_change).width(old_width);
// make the placeholder the same width the scrollbar was
$("#ScrollbarPlaceholder").show().width(new_width-old_width);
// and float the items to the other side.
$(items_to_change).css("float", "left");
}
function EnableScrollbar()
{
// exit if page can't scroll
if ($(document).height() == $('body').height()) return;
// remove the placeholder, then bring back the scrollbar
$("#ScrollbarPlaceholder").fadeOut(function(){
$('body').css('overflow-y','auto');
});
}
Hope this helps.
If simple switching of body's 'overflow-y' is breaking your page's scroll position, try to use these 2 functions (jQuery):
// Run this function when you open your popup:
var disableBodyScroll = function(){
window.body_scroll_pos = $(window).scrollTop(); // write page scroll position in a global variable
$('body').css('overflow-y','hidden');
}
// Run this function when you close your popup:
var enableBodyScroll = function(){
$('body').css('overflow-y','scroll');
$(window).scrollTop(window.body_scroll_pos); // restore page scroll position from the global variable
}
Use below code for disabling and enabling scroll bar.
Scroll = (
function(){
var x,y;
function hndlr(){
window.scrollTo(x,y);
//return;
}
return {
disable : function(x1,y1){
x = x1;
y = y1;
if(window.addEventListener){
window.addEventListener("scroll",hndlr);
}
else{
window.attachEvent("onscroll", hndlr);
}
},
enable: function(){
if(window.removeEventListener){
window.removeEventListener("scroll",hndlr);
}
else{
window.detachEvent("onscroll", hndlr);
}
}
}
})();
//for disabled scroll bar.
Scroll.disable(0,document.body.scrollTop);
//for enabled scroll bar.
Scroll.enable();
https://jsfiddle.net/satishdodia/L9vfhdwq/1/
html:-
Open popup
Popup
pop open scroll stop now...when i will click on close automatically scroll running.
close
**css:-**
#popup{
position: fixed;
background: rgba(0,0,0,.8);
display: none;
top: 20px;
left: 50px;
width: 300px;
height: 200px;
border: 1px solid #000;
border-radius: 5px;
padding: 5px;
color: #fff;
}
**jquery**:-
<script type="text/javascript">
$("#open_popup").click(function(){
$("#popup").css("display", "block");
$('body').css('overflow', 'hidden');
});
$("#close_popup").click(function(){
$("#popup").css("display", "none");
$('body').css('overflow', 'scroll');
});
</script>
I had the same problem and found a way to get rid of it, you just have to stop the propagation on touchmove on your element that pops up. For me, it was fullscreen menu that appeared on the screen and you couldn't scroll, now you can.
$(document).on("touchmove","#menu-left-toggle",function(e){
e.stopPropagation();
});
This solution works for me.
HTML:
<div id="payu-modal" class="modal-payu">
<!-- Modal content -->
<div class="modal-content">
<span class="close">×</span>
<p>Some text in the Modal..</p>
</div>
</div>
CSS:
.modal-payu {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
padding-top: 100px; /* Location of the box */
left: 0;
bottom: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
/* Modal Content */
.modal-content {
background-color: #fefefe;
margin: auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
}
/* The Close Button */
.close {
color: #aaaaaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
JS:
<script>
var btn = document.getElementById("button_1");
btn.onclick = function() {
modal.style.display = "block";
$('html').css('overflow', 'hidden');
}
var span = document.getElementsByClassName("close")[0];
var modal = document.getElementById('payu-modal');
window.onclick = function(event) {
if (event.target != modal) {
}else{
modal.style.display = "none";
$('html').css('overflow', 'scroll');
}
}
span.onclick = function() {
modal.style.display = "none";
$('html').css('overflow', 'scroll');
}
</script>
I ran into the problem and tried several solutions,
here is the article that solved my problem (https://css-tricks.com/prevent-page-scrolling-when-a-modal-is-open/) and it is quite simple!
It uses the 'fixed body' solution, which is quite common to find in lots of posts.
The problem with this solution is, when the popup is closed, the body will scroll back to the top.
But the article points out: by manipulating the CSS top and position attributes while using the solution, we can recover the scroll position.
Another issue of the solution is, you can't apply the solution with the multiple popup scenario.
So I added a variable to store the count of the popup, just to make sure the program won't trigger the initiating process nor the reset process at the wrong timing.
Here is the final solution I get:
// freeze or free the scrolling of the body:
const objectCountRef = { current: 0 }
function freezeBodyScroll () {
if (objectCountRef.current === 0) { // trigger the init process when there is no other popup exist
document.body.style.top = `-${window.scrollY}px`
document.body.style.position = 'fixed'
}
objectCountRef.current += 1
}
function freeBodyScroll () {
objectCountRef.current -= 1
if (objectCountRef.current === 0) { // trigger the reset process when all the popup are closed
const scrollY = document.body.style.top
document.body.style.position = ''
document.body.style.top = ''
window.scrollTo(0, parseInt(scrollY || '0') * -1)
}
}
You can also see the demo on my Codepen: https://codepen.io/tabsteveyang/pen/WNpbvyb
Edit
More about the 'fixed body' solution
The approach is mainly about setting the CSS position attribute of the body element into 'fixed' to make it unscrollable.
No matter how far it has been scrolled, when the body is fixed, it will scroll back to the top, which is the behavior that I don't expect to see. (Imagine the user is browsing a long content and almost scrolls to the bottom of the page, suddenly a popup shows up and make the page scroll right back to the top, that's a bad user experience)
The solution from the article
Base on the 'fixed body' approach, additionally, the solution sets the CSS top of the body as the value of '-window.scrollY px' to make the body looks like it stays in the current scrolling position while it is fixed.
Furthermore, the solution uses the CSS top of the body as a temporary reference, so that we can retrieve the scrolling position by the attribute when we want to make the body scrollable again. (Notice you have to multiple the position you get to -1 to make it positive)