Animate a div when an element is visible in the viewport - javascript

Im am trying to create a horizontally scrolling, one-page website where I am using divs as buttons to get the page to scroll to an element when they are clicked. I have the scrolling mechanism working but I want the divs to animate (change size or colour ect...) when the element they are linked to to is visible in the viewport. What is the best way to do this?

I'm not sure how you code is done for the scrolling because you didn't provide any code / exemple but I will try to help you in some way.
$(function(){
var sections = {},
_height = $(window).height(),
i = 0;
// Grab positions of our sections
$('.section').each(function(){
//this.name would be the attr name="" of a section but you could change to the id
sections[this.name] = $(this).offset().top;
});
$(document).scroll(function(){
var pos = $(this).scrollTop();
// Look in the sections object and see if any section is viewable on the screen.
// If two are viewable, the lower one will be the active one.
for(i in sections){
if(sections[i] > pos && sections[i] < pos + _height){
$('a').removeClass('active');
$('#nav_' + i).addClass('active');
}
}
});
});
This Code should do what you want to achive atm it's just active a 'active' class but you could do a Css3 animation as you want.

Related

Get the position of div on page scroll

Hi Guys,
I'm not so good with jQuery and javascript.
I will make a script that take the position of my div and when it's on the top of the page it make something.
Example:
I have a menu. When i scroll the page and my div arrive at the top (or better at 100/200px from top), something in my menu changes...
I hope somebody can help me.
Thanks.
You should use the jQuery offset() scrollTop() and scroll() methods to achieve this.
http://api.jquery.com/offset/
https://api.jquery.com/scrollTop/
https://api.jquery.com/scroll/
Offset returns the pixel value of the elements from the top of the page. Run this on scroll, and you can detect when the element is 100px, or 200px from the top.
Here is an example of running offset() and scrollTop() on window.scroll(), and adding/removing classes when the element has reached the top of this page. In this example, I am fixing the $mainMenuBar to the top of the page when the user scrolls past it, and un-fixing it when the user scroll back up past it.
// declare vars
var $window = $(window),
$mainMenuBar = $('.anchor-tabs'),
$mainMenuBarAnchor = $('.anchor-tabs-anchor');
// run on every pixel scroll
$window.scroll(function() {
var window_top = $window.scrollTop();
var div_top = $mainMenuBarAnchor.offset().top;
if (window_top > div_top) {
// Make the div sticky.
$mainMenuBar.addClass('fixed-top');
$mainMenuBarAnchor.height($mainMenuBar.height());
}
else {
// Unstick the div
$mainMenuBar.removeClass('fixed-top');
$mainMenuBarAnchor.height(0);
}
});
Hope this helps.
You can compare the offset of your div element to how far down the page the user has scrolled.
The $(window).scrollTop() function get you how far the user has scrolled down, i.e :
$(window).scroll(function() {
var yourDiv = $("#theIdOfYourDiv");
var window_offset = yourDiv.offset().top - $(window).scrollTop();
if ( window_offset < 100 )
{
// do what you want
}
});

'Endless scroll' in a div on a web page

I want to create a div containing endless scrollable content in a page.
For recognizing the end of the scrollable content in order to load more data from the data base I've written the following:
$(window).scroll(function(){
var wintop = $(window).scrollTop(), docheight = $(document).height(), winheight = $(window).height();
var scrolltrigger = 0.95;
if ((wintop/(docheight-winheight)) > scrolltrigger) {
lastAddedLiveFunc();
}
});
Question: The following code is for creating the endless scroll which fits in the entire webpage, but how can I write the same for a 'div' inside a web page?
(Hint: An exact similar thing is the Ticker on Facebook, on the right side which shows the recent activities of your friends in real time.)
The principle is the exact same. The div will be your browser viewport, and the div content is your document. You just need to exchange
$(window).scroll() --> $("#someDiv").scroll()
$(window).scrollTop() --> $("#someDiv").scrollTop()
$(document).height() --> $("#someDiv")[0].scrollHeight
$(window).height() --> $("#someDiv").height()
and it should work.
Note that:
scrollHeight is a property, not a function.
scrollHeight isn't jQuery, so you need to obtain it from the actual javascript element of the selector, hence the [0] addition. Another way is to use $("#someDiv").prop("scrollHeight").
$("#yourdiv").scroll(function(){
//your logic
}
You can use your div instead of window
For example
$('#yourdiv').scrollTop() // etc
use this
// get box div position
var box = document.getElementById('box').offsetTop;
window.onscroll = function(){
// get current scroll position
var scroll_top = document.body.scrollTop || document.documentElement.scrollTop;
document.getElementById('scbox').innerText = scroll_top + ' ' + box;
// if current scroll position >= box div position then box position fixed
if(scroll_top >= box)
document.getElementById('box').style.position = 'fixed';
else
document.getElementById('box').style.position = 'relative';
}

Automatically Highlight Navigation Links on Horizontal Free Scrolling Website

I have a particular page with a set of images contained in a white-space:nowrap div, so the page scrolls horizontally. There's a fixed (main) navigation menu on the left.
I have a second navigation set, underneath the images, which when you click on the various links uses scrollTo to scroll the browser to the relevant image. This second navigation menu is contained in a fixed div and made up of a series of links to the various anchors associated with the images.
I would like a way of attaching and removing an active class to these links (i.e. addClass() ) depending on where the browser window is (and what is in view).
I have found lots of vertical versions of this, but my JS knowledge isn't fantastic and I haven't been able to successfully convert these to be used horizontally.
Essentially what I would like is a horizontal version of this JSFiddle.
I have come across this plugin, but haven't managed to get this to work for me either:
here
Thank you!
this your fiddle horizontal:
http://jsfiddle.net/x3V6Y/
I made a little change on HTML, and here is the JS:
$(function(){
var sections = {},
_width = $(window).width(),
i = 0;
// Grab positions of our sections
$('.section').each(function(){
sections[this.name] = $(this).offset().left;
});
$(document).scroll(function(){
var $this = $(this),
pos = $this.scrollLeft();
for(i in sections){
if(sections[i] >= pos && sections[i] <= pos + _width){
$('a').removeClass('active');
$('#nav_' + i).addClass('active');
}
}
});
});

Dynamically change relatively positioned content to fixed content - bug

I have a sidebar that contains content larger than the screen. As the user scrolls down I want that content to come into view until the last bit. Then I want it to be fixed so that as much content stays on screen as possible. I actually want it to work exactly like the "Similar Questions" sidebar when you are posting a question in SO. In each of these example links scroll down. In the broken case notice how everything gets all jumpy.
Should work like this = http://jsfiddle.net/mrtsherman/G4Uqm/2/
But broken in this case = http://jsfiddle.net/mrtsherman/G4Uqm/1/
In the broken case it looks like the scroll event is being retriggered when you reach the end of the page. This then causes subsequent scroll events to trigger which then screw everything up. How can I properly handle this case? I just can't figure it out.
$(document).ready(function() {
var dynamic = false;
var topOfSidebar = $("#sidebar").offset().top;
var leftOfSidebar = $("#sidebar").offset().left;
var botOfSidebar = topOfSidebar + $("#sidebar").height();
var botOfScreen = $(window).height() + $(window).scrollTop();
//if sidebar fits on screen then use fixed version of it
if (botOfSidebar < $(window).height()) {
$("#sidebar").addClass("fixed");
$("#sidebar").css("top", topOfSidebar);
$("#sidebar").css("left", leftOfSidebar);
}
else {
dynamic = true;
}
//toggle sidebar class when user scrolls
$(window).scroll(function() {
console.log($("#sidebar").css("position"));
botOfScreen = $(window).height() + $(window).scrollTop();
//return;
if (botOfSidebar < botOfScreen && dynamic) {
$("#sidebar").addClass("fixed");
//$("#sidebar").css("bottom", 0);
//$("#sidebar").css("left", leftOfSidebar);
}
else if (dynamic) {
$("#sidebar").removeClass("fixed");
}
});
});
So I figured this one out on my own. The trick is to wrap the content in a div with a min-height attribute. If we switch the sidebar to fixed then the div holds the place of the sidebar. Therefore no more screen resizing.
.wrap creates the div
.parent gets the sidebar's parent (the new div)
add css properties where min-height is the height of the sidebar. Remove padding and margin
$("#sidebar")
.wrap('')
.parent()
.css("min-height", this.height())
.css("padding", "0px")
.css("margin", "0px");

Keeping sidebar in viewport, problem with scrolling

I've got a solution for keeping a sidebar in the viewport as you scroll up and down the page. Problem comes in when the sidebar is longer than the content area, and you keep scrolling you get this jittering effect as the sidebar keeps pushing the footer down.
I've got an example of this setup in jsFiddle: http://jsfiddle.net/U9F7w/2/ (full screen: http://jsfiddle.net/U9F7w/2/embedded/result/ )
My question is, is there a way to make the sidebar stop once it touches the bottom/footer area?
I've read some solutions about setting the sidebar to absolute, unfortunately it's an existing site and changing the position didn't work and messed with a lot of the existing page elements.
Here's the jQuery/js I'm working with:
// set the offset
var sidebarOffset = $(".sidebar").offset();
var sidebarPadding = 15;
// when the window scrolls, keep sidebar in view
$(window).scroll(function() {
if ($(window).scrollTop() > sidebarOffset.top) {
$(".sidebar").stop().animate({marginTop: $(window).scrollTop() - sidebarOffset.top + sidebarPadding });
}
else {
$(".sidebar").stop().animate({marginTop: 0});
};
});
edit
One thing I thought about was (not sure if this is possible) to detect if the bottom of one div was lower than the bottom of another, stop the scrolling. Is there a way to detect if the bottom of one div is lower than the other?
Check if the sidebar's height is greater then that of the content:
var ct = $(".content");
var sb = $(".sidebar");
var sbOffsetTop = sb.offset().top;
var sbPadding = 15;
$(window).scroll(function() {
if (sb.height() < ct.height()) {
if ($(window).scrollTop() > sbOffsetTop) {
sb.stop().animate({top: $(window).scrollTop() - sbOffsetTop + sbPadding });
}
else {
sb.stop().animate({top: 0});
};
};
});
See demo fiddle with large content and demo fiddle with large sidebar.
And I don't know why exactly, I would use top in conjunction with position: relative, but marginTop works also fine.

Categories

Resources