Jquery DIV collision - javascript

I found the following script to make a menu have a smooth animation following the screen when scrolling.
However, it's pushing down the footer, resulting the page height expanding with no further content. How do I make it stop scrolling when it collides with the footer?
Here's the code:
$(function() {
var $sidebar = $("#indhold_right"),
$window = $(window),
offset = $sidebar.offset(),
topPadding = 0;
$window.scroll(function() {
if ($window.scrollTop() > offset.top) {
$sidebar.stop().animate({
marginTop: $window.scrollTop() - offset.top + topPadding
}, "fast");
} else {
$sidebar.stop().animate({
marginTop: 0
});
}
});
});

Let us take a step back and see why it is happening the way it is happening.
When you scroll $window.scrollTop() AND offset.top both change. However, the former will always be greater than the latter. So, every time you scroll, your if condition evaluates to true and you are calling the animate function on it. You don't have a stop.
How do we put a stop? By putting a stop check beyond which you don't animate. When the page loads get the $("#footer").offset().top which is the footer height when you start. So, the check is against $window.scrollTop() which should be lesser than the footer top.
Will that check work? Yes, but it will not be pleasant(unless you want it that way) because your side bar has height and the stop works only after your sidebar top has reached the footer height(stop). So, just add the sidebar height to your stop. This will not be 100% accurate, there will be padding, margins, and other stuff that are not accounted for in this stop, but it looks pretty good and I think, you can continue from there.
Before I give you the code answer, please take a look at http://sscce.org/ (as mentioned by #Zeta). Always follow this. I had some time and a good mood. I wouldn't have even looked at it otherwise.
Below is the code. Working example - http://jsfiddle.net/H3Dqr/
$(function() {
var $sidebar = $("#indhold_right"),
$window = $(window),
offset = $sidebar.offset(),
topPadding = 0,
stop = $("#footer").offset().top;
$window.scroll(function() {
if ($window.scrollTop() > offset.top) {
if ($window.scrollTop() + $sidebar.height() < stop) {
$sidebar.stop().animate({
marginTop: $window.scrollTop() - offset.top + topPadding
}, "fast");
}
} else {
$sidebar.stop().animate({
marginTop: 0
});
}
});
});​

Related

Stop a scrollfollow div on specific div

I have a sidebar which are scrollfollow, that means it works as it is set to position:fixed. However, the sidebar continue scrolling till the user stop. This results in the elements on the bottom of the site doesn't reach the sight of the user, because the sidebar push elements down.
I have created a fiddle to illustrate the exact problem: jsd https://jsfiddle.net/Lv4humd6/2/
The javascript that makes the div scrollfollow:
$(function() {
var $sidebar = $("#sidebar-right"),
$window = $(window),
offset = $sidebar.offset(),
topPadding = 15;
$window.scroll(function() {
if ($window.scrollTop() > offset.top) {
$sidebar.stop().animate({
marginTop: $window.scrollTop() - offset.top + topPadding
});
} else {
$sidebar.stop().animate({
marginTop: 0
});
}
});
});
What I want is the sidebar to stop scrolling, when it reach the div break as you see in the jsfiddle. I have searched and tried everything, but I can't find any solution for it.

.slideDown() after certain height only once, listening to .scrollTop

I got this problem where I got an section (".aboutsection") that's hidden at first, needs to be revealed when hitting a certain point on the webpage and then start to animate the .slideDown(). I got it working, but everytime I scroll past that certain point it starts the animation over and over again and that's not what I want.
I sought for different solutions, but neither of them work nor match my needs.
(So please don't put this as a copy)
$(window).scroll(function(){
var wScroll = $(this).scrollTop();
$(".aboutcontainer").hide();
[...] (left out other function listening to scrolltop)
if(wScroll > $('section.about').offset().top - ($(window).height() / 1.2)) {
$(".aboutcontainer").slideDown(1400,'easeInOutQuart');
}
});
I've tried to let the function check if ".aboutcontainer" is ":visible" or ":hidden" to only animate it when the section is hidden, but that didn't work.
You could probably just set a flag and check as part of your conditional:
var expanded = false;
$(".aboutcontainer").hide();
$(window).scroll(function(){
var wScroll = $(this).scrollTop();
[...] (left out other function listening to scrolltop)
if(!expanded && wScroll > $('section.about').offset().top - ($(window).height() / 1.2)) {
expanded = true;
$(".aboutcontainer").slideDown(1400,'easeInOutQuart');
}
});
Since slideDown manipulates the height of the object have you tried to check if the height is greater than 0?
if(wScroll > $('section.about').offset().top - ($(window).height() / 1.2)) {
if( $(".aboutcontainer").height() < 0 ){
$(".aboutcontainer").slideDown(1400,'easeInOutQuart');
}
}

followTo issue with higher resolutions

I use this snippet to make an element "stop" at a certain point when scrolling.
$.fn.followTo = function (pos) {
var $this = this,
$window = $(window);
$window.scroll(function (e) {
if ($window.scrollTop() > pos) {
$this.css({
position: 'absolute',
top: pos
});
} else {
$this.css({
position: 'fixed',
top: 0
});
}
});
};
$('#braille').followTo(865);
The problem is that if there's not enough space to scroll (in higher resolutions), it's not positioned correctly.
It's important that you watch these 2 videos to understand how it works.
1920x1080: https://www.youtube.com/watch?v=WjT8FKAKTxA
It's properly positioned.
2775x1514: https://www.youtube.com/watch?v=oqQXm8BsfYA
Here instead as you can see it's not in the right place because there's not enough space to scroll
Resolutions until about 1190px height are ok, with higher resolutions there's this problem.
How can I solve this..? Can I set a followTo starting from the bottom of the page? Or set it in percentage? Or say "if height is > than 1190 just put that there"....
Here is the live webpage. To see what I'm talking about just zoom out like 3 times the resolution of your browser and try to scroll the page. The braille image isn't positioned properly under the music staff and above the yellow paragraph.
The short answer is yes, you can set followTo relative to the bottom of the page using $(document).height() - pos. The basic principle is:
$(window).scrollTop() == $(document).height() - $(window).height()
To change the followTo to work relative to the bottom of the page:
if ($(document).height() - $window.height() - $window.scrollTop() < pos)
To use a percentage you could do the calculation:
var percentageDownPage = $window.scrollTop() / ($(document).height() - $(window).height()) * 100;
if (percentageDownPage > pos) { /* your code*/ }

How to reverse a css transistion on scroll for fly in / fly out effect

I am trying to get an fly-in / fly- out effect happening
Scroll down - animate in
Scroll-up animate out
To get a similar effect to the nizo website
http://nizoapp.com/
I have used this code I found on Stackoverflow "Fade in element on scroll down using css"
to determine whether the element is on screen, in the viewport, and then animate it.
$(window).scroll(function () {
/* Check the location of each desired element */
$('.article').each(function (i) {
var bottom_of_object = $(this).position().top + $(this).outerHeight();
var bottom_of_window = $(window).scrollTop() + $(window).height();
/* If the object is completely visible in the window, fade it it */
if (bottom_of_window > bottom_of_object) {
$(this).animate({
'opacity': '1'
}, 500);
}
});
});
Which works quite well.
I have added it to this demo page, and modified it.
http://saigonhousefinder.com/potteryone/fadinonscroll.html
(probably not live for long)
I have used css transitions to get the effect I am looking for. FLy-in Fly-out etc etc
And then I found..... this function which does the same thing
function isScrolledIntoView(elem)
{
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
return ((elemTop <= docViewBottom) && (elemTop >= docViewTop));
}
Anyway.......
I cant get the animations to work when scrolling down, fly-in.
But I cannot get the animations to go in reverse when they fly out on scroll up
I thought the easiest way would be to detect if you are scrolling down of up, so I found this method / function
(function () {
var previousScroll = 0;
$(window).scroll(function () {
var currentScroll = $(this).scrollTop();
if (currentScroll > previousScroll){
$("#div").fadeIn("slow");
}
else {
$("#div").fadeOut("slow");
}
previousScroll = currentScroll;
});
}());
Which works well, but I cannot get it working.
At this point I can detect when an element is visible on the screen then add an effect to it.
What I need it to detect when that same element is beginning to go off the screen and apply another effect to it.
Any help on how to get this working would be great
Have a nice day
That's a really neat demo and a great concept! I played around with some code and it seems that you are almost there. You need to detect when the top of the screen meets the top of the element, so only calculate the offset once when the page is loaded. I added a 20px threshold so it kicks in a bit early. Let me know if this helps, it can be tweaked depending on how and when you want to call it. Here is a simple js fiddle demo
http://jsfiddle.net/XhAhR/23/
(function () {
var previousScroll = 0;
var elemTop = $("#div").offset().top;
$("#div").fadeOut();
$(window).scroll(function () {
var currentScroll = $(this).scrollTop();
if (currentScroll > previousScroll){
if(elemTop -20 > currentScroll){
$("#div").fadeIn("slow");
}
}
else {
if(elemTop - 20 > currentScroll){
$("#div").fadeOut("slow");
}
}
previousScroll = currentScroll;
});
}());

Position fixed when scrolled passed certain amount of pixels

I'm looking for a way to position the #header element of my page as "Fixed" only after having scrolled downward for about 170 pixels.
Above the header is a banner, so when people scroll down, I would like the banner to scroll away, the header to stay fixed when it hits the top of the window, and the page content to scroll underneath the header.
http://jsfiddle.net/tdskate/zEDMv/
This is the general idea although you may want to fudge around with the css a bit.
var header = $("#header");
$(document).scroll(function(e) {
if($(this).scrollTop() > $("#banner").height()) {
header.css({"position" : "fixed", "top" : "0"});
} else {
header.css("position", "relative");
}
});
You need to check for the different scroll positions:
var $header = $('#header'),
headerPos = $header.position().top,
$win = $(window);
$win.scroll(function() {
if ( $win.scrollTop() >= headerPos) {
$header.css({
'position':'fixed',
'top':0,
'width': '100%'
});
}
if ( $win.scrollTop() <= headerPos ) {
$header.css({
'position': 'static'
});
}
});
http://jsfiddle.net/DOSBeats/zEDMv/10/
Here's a slightly more concise version:
var header = $('#header'),
bannerHeight = $('#banner').height(),
win = $(window);
win.scroll(function() {
header.css({ top: Math.max(Number(win.scrollTop() - bannerHeight), 0) });
});
Here is a demo of a jquery plugin that takes care of this. Similar to John's answer above, but the plugin takes the solution a bit farther.
Demo: http://jsfiddle.net/ZczEt/
Plugin and source: https://github.com/bigspotteddog/ScrollToFixed
Usage:
$(document).ready(function() {
$('.header').scrollToFixed();
});
I think this should work: http://jsfiddle.net/Skooljester/K2mFT/. However, you'll need to define a width on your header or else it'll shrink when it becomes fixed.

Categories

Resources