Disable window scroll when scrolling an overflowed element - javascript

I got an element with a vertical scrollbar via overflow: auto. When I scroll vertically inside it and reach the bottom, the window starts scrolling instead, due to the page content being longer than the height of the window. Can I disable this behavior?
// CSS
#container {
width: 100px;
height: 300px;
border: 1px solid #000;
overflow: auto;
}
// HTML
<div id="container">
<div>Foo</div>
...
</div>
// Other content, stretching out the page vertically,
// forcing a scrollbar on the window
Example: http://jsbin.com/zimabuco/1/

Setting the overflow of the body to hidden when the container is being hovered seems to work well.
$('div#container').mouseenter(function(event) {
$('body').css('overflow', 'hidden');
}).mouseleave(function(event) {
$('body').css('overflow', '');
});
See the following example, you'll see the scrollbar disappear when the div is hovered.
Example http://jsbin.com/sihihewi/3/edit

This will disable the window to scroll when you hover over the list:
$(document).ready(function(){
$("#container").hover(function(){
$('html, body').css({
'overflow': 'hidden',
'height': '100%'
})
});
});

Related

Scroll to div with a sticky navigation bar

The page has a sticky navbar that stay on screen all the time.
When I am scrolling to the next section(div) of the page, it will scroll so the div starts at the top of the screen , so the navigation bar cover it a little bit.
How to minus from y scrolling position the navigation bar height ?
$('html, body').animate({
scrollTop: $("#section2").offset().top // minus the nav height
}, 1000);
Also - how to make this navbar height available to my javascript (from the css) using a good practice ? (global var?)
You can select your navigation bar (here I gave my navigation bar the id nav) and get its height by doing:
$("#nav").height();
You can then subtract this from the scrollTop property.
However, do note, if your nav bar has padding and/or a margin, to correctly calculate the height you will need to use a different method from .height. See this answer if you're having difficulties.
See working example below:
$('html, body').animate({
scrollTop: $("#section2").offset().top - $("#nav").height() // minus the nav height
}, 1000);
body {
margin: 0;
}
nav {
background: black;
height: 10vh;
width: 100%;
position: fixed;
}
section {
height: 100vh;
}
#section1 {
background: red;
}
#section2 {
background: lime;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav id="nav"></nav>
<section id="section1">Top</section>
<section id="section2">Top</section>
To know the height of any element :
Go to the Inspector (Ctrl+Shift+i), select the 'nav' element and on the right side, click the box-model. This will give you the height and width of the selected element.
In JavaScript, to get the height :
$("nav").height();

How to remove a div but prevent the scroll position to be changed?

What do i want to achive?
I want to remove a div which isnt visible(for the user not the css atribute) anymore on the screen because i let the html and body scroll to a div with jquery(scrollTop). Now i want to remove the div which was visible beforr i scrolled down with jquery.
Edit: After removing the .header div, the #begining should be the top of the page and the .header div should be removed forever.
What is the problem?
After i scrolled down and removed the div with the following line of code: $('.header').css('display','none'); the scroll position changes.
Code to scroll down and remove the div.
function scrollToBegining(){
$('html, body').animate({
scrollTop: $("#begining").offset().top
}, 750);
setTimeout(function(){
$('.header').css('display','none');
},750);
}
Problem visualized:
GIF of the problem (Watch to understand better)
This is odd, but I think a better choice is to slideUp the div instead of scrolling:
function scrollToBegining(){
$('.header').slideUp(750);
}
Obviously, rename the function since it's no longer scrolling.
You can use visibility: hidden to hide the div but reserve its space. Also, sometimes the scroll position has to be changed when you use display: none.
visibility: hidden
is what you are looking for, but another solution I use with this kind of issue is instead of scrolling down to your second div, have the initial div shrink its height in a uniform animation until it is 0. This prevents the weird shuddering scroll issue you are experiencing
document.querySelector('#header h1').addEventListener('click', closeHeader)
function closeHeader(){
document.querySelector('#header').classList.add("hidden");
}
#header {
height: 300px;
width: 100%;
background: red;
text-align: center;
}
#content {
height: 1000px;
width: 100%;
background: yellow;
text-align: center;
}
.hidden {
display: none !important;
margin: 0 !important;
padding: 0 !important;
}
<div id="header">
<h1>
HEADER
</h1>
</div>
<div id="content">
CONTENT
</div>

Overflow: auto on html,body breaks jQuery .animate scroll to top?

I have a button at the bottom of my webpage that when clicked scrolls back to the top of the page. This works perfectly and can be seen in my demo here.
I had another issue with a drawer in my site where the entire page kept jumping up when the drawer was opened - to solve this i needed to apply overflow:auto; to the html,body and that fixed the issue.
However in the process it stopped my back to top button from working. I wondered if anyone might be able to explain why or if there is an easy solution to this, I just can't figure it out?
To see my issue simply uncomment the overflow:auto in my demo CSS.
UPDATE
Thanks to a few suggestions below applying overflow:auto just to the body NOT html fixes the issue on everything except desktop Safari - anyone got any clue how to remedy this?
var offset = 300,
scroll_top_duration = 700,
$back_to_top = $('.top');
// Smooth scroll to top
$back_to_top.on('click', function(event) {
event.preventDefault();
$('body,html').animate({
scrollTop: 0,
}, scroll_top_duration
);
});
It seems that it doesn't like having overflow on the html element.
Here's a fiddle:
http://jsfiddle.net/330zyny7/2/
Moving the overflow to the body fixed it.
var offset = 300,
scroll_top_duration = 700,
$back_to_top = $('.top');
// Smooth scroll to top
$back_to_top.on('click', function(event) {
event.preventDefault();
alert();
$('body,html').animate(
{scrollTop: 0, },
scroll_top_duration
);
});
html, body {
padding: 0;
margin: 0;
height: 100%;
-webkit-overflow-scrolling: touch;
}
body{
overflow:auto;
}
.page-wrapper {
position: relative;
height: 1000px;
}
h3 {
position: absolute;
bottom: 0;
}
<div class="page-wrapper">
<p>Top - scroll to the bottom to click 'back to top'</p>
<h3>
Back to top
</h3>
</div>

Why div have different animation in these two cases

I have two divs with animation, both are doing the same but with different animation. I have
$(document).ready( function(){
$('#show_hide_button').click( function() {
$('#some_box').animate({ width: 'toggle' });
});
});
Whole code in in jsfiddle http://jsfiddle.net/xLHb8/192/
Can anyone please explain to me why first div is animating right to left, left to right and second div is animating always to top left corner.
How can I make second div animate same as first div?
First, the relevant details in your code should be included in your question (in addition to providing the fiddle). But so you have the following CSS:
#some_box {
background: #fc0;
width: 25%;
height: 200px;
}
.second img {
max-width:100%;
max-height:100%;
}
.second {
width: 200px;
}
With the following HTML:
<button id="show_hide_button">click me</button>
<div id="some_box"></div>
<div class="second">
<img src="http://piq.codeus.net/static/media/userpics/piq_66223.png" />;
</div>
Note that you're setting the img to have a maximum width and height of its parent container. So because you're toggling the width of the parent, as parent collapses, the image is scaling down. Further, since you don't have a height setting on the img, its height is going to animate along with the animated width. This creates the effect of the image animating to the top left corner.
Without further details, it's hard to say how to fix your code to achieve the desired effect.
Update
If you want the width only to collapse, you can set a pixel height on your image so that it doesn't scale in proportion to its width:
.second img {
max-width: 100%;
height: 200px;
}
You can also put both animations in a single click event handler, like so:
$(document).ready( function(){
$('#show_hide_button').click( function() {
$('#some_box').animate({ width: 'toggle'});
$('.second').animate({ width: 'toggle' });
});
});
Forked your fiddle: http://jsfiddle.net/u1sdd8j5/1/
Update 2
From the comments, it seems like you want the image to collapse to the left, without losing the aspect ratio. We need to get a little creative to pull that off, especially if you're looking for a solution involving jQuery.animate(). The image actually needs to move downwards as it is scaled down. We can pull that off by animating the <img> itself, rather than its container, and adjusting its top margin at the same time animate its width.
Revised CSS (making the containers the same size for consistency):
#some_box {
background: #fc0;
width: 25%;
height: 200px;
}
.second {
width: 25%;
height: 200px;
}
.second img {
max-width: 100%;
max-height: 100%;
}
Revised JS:
$(document).ready( function(){
$('#show_hide_button').click( function() {
$('#some_box').animate({ width: 'toggle' });
var $secondImg = $('.second img'),
secondImgMargin = $secondImg.is(':visible') ? '50%' : 0;
$('.second img').animate({
width: 'toggle',
marginTop: secondImgMargin
});
});
});
Note that we need to first determine whether or not the <img> is visible. If it is, then we want to animate the top margin to 50%. If it's not, then switch the top margin back to 0.
Here's a new forked fiddle: http://jsfiddle.net/xwanm9ze/1/
Final Note
All of this might be easier to achieve with CSS3 transitions. You would want to set up a class that toggles the animation. And you can specify the transform-origin which, in this case, would be 'left center'.
The problem is, that you added a relative width and height attribute to the inside the second div and did not give a height and width attribute to the second div. This way, the image controls the height and width of the second div, since it has no height and width attribute.
In your case, a solution would be to give the second div a fixed width and height
Also, for the JQuery, you only need one $(document).ready function
$(document).ready(function () {
$('#show_hide_button').click(function () {
$('#some_box').animate({
width: 'toggle'
});
$('.second').animate({
width: 'toggle'
});
});
});
#some_box {
background: #fc0;
width: 25%;
height: 200px;
}
.second img {
width:100%;
height:100%;
}
.second {
width:200px;
height: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="show_hide_button">click me</button>
<div id="some_box"></div>
<div class="second">
<img src="http://piq.codeus.net/static/media/userpics/piq_66223.png" />
</div>

Element changes place when position fixed applied

When I apply position: fixed with Javascript my element moves a few pixels down and gets fixed in another position, some pixels down, instead of just staying where is was.
Why is this?
// html
<div id="container">
<div id="myDiv"></div>
</div>
// CSS
#container {
height: 2000px;
}
#myDiv {
margin-top: 50px;
width: 100px;
height: 50px;
background-color: #88a;
}
// Javascript
myDiv.style.position = 'fixed';
I find this behaviour at least in Chrome and FF.
http://jsfiddle.net/bSM8h/
When you apply position:fixed, also do:
pin.addEventListener('click', function () {
myDiv.style.position = 'fixed';
myDiv.style.top = '50px';
myDiv.style.marginTop = '0';
});
http://jsfiddle.net/bSM8h/2/
*edit*
By default browsers do body{padding:5px;} that is why a good idea is to html5boilerplate your css's
*end edit*
For some reason (see explanation here), margin-top also pushed the container with it. Once applied position:fixed, the container sprung back to the top of the page (lost the margin) and was positioned 5px from the top of page.
before position:fixed
after position:fixed
Just add this to your CSS:
body {
margin:0;
padding:0;
}
This will prevent the extra padding added by the browser defaults.

Categories

Resources