Moving to sections of a website using jQuery `.scroll()` - javascript

I am trying to create a simple effect in jQuery that when the user scrolls down the page, a "pane" is automatically animated into view (so that the user doesn't have to scroll down all of the way themselves).
It's hard to explain, so here is the example: http://jsfiddle.net/naxb22q3/1/
As you can see, when you scroll down past the blue pane a few pixels, the green pane is shown. However, the code that I currently have makes it so that once that green pane is shown, you can no longer scroll up or down. You have to reload the page to get it to work again.
Ideally, the user could scroll up or down and the animations would work.
HTML:
<div class="pane bgBlue"></div>
<div class="pane bgGreen"></div>
<div class="pane bgRed"></div>
CSS:
.pane {
height: 1000px;
width: 100%;
}
.bgBlue {
background-color: blue;
}
.bgGreen {
background-color: green;
}
.bgRed {
background-color: red;
}
JavaScript:
/**
* Lock scroll position for each pane
* as the user scrolls down.
*/
$.fn.scrollView = function () {
return this.each(function () {
$('html, body').animate({
scrollTop: $(this).offset().top
}, 1250);
});
}
// Variables
var windowHeight = $(window).height();
var headerHeight = $('.siteHeader').outerHeight();
var paneHeight = windowHeight - (headerHeight / 2);
// `.scroll()` function
$(window).scroll(function () {
height = $(window).scrollTop();
if (height > 5) {
$('.pane.bgGreen').scrollView();
//$(this).off('scroll');
}
// After we scroll past the green pane,
// the red pane is shown (via the same animation)
if (height > (paneHeight * 2)) {
$('.pane.bgRed').scrollView();
}
});

Rough solution, but a start - http://jsfiddle.net/bkseqsu4/
Javascript:
// Variables
var windowHeight = $(window).height();
var headerHeight = $('.siteHeader').outerHeight();
var paneHeight = windowHeight - (headerHeight / 2);
var scrollLock = 0;
var paneIndex = 0;
var lastScroll = 0;
var panes = ['.pane.bgBlue', '.pane.bgGreen', '.pane.bgRed'];
/**
* Lock scroll position for each pane
* as the user scrolls down.
*/
$.fn.scrollView = function() {
this.each(function() {
$('html, body').animate({
scrollTop: $(this).offset().top
}, 1000, "swing", function() {
setTimeout(function() {
scrollLock = 0;
var currentPosition = $(this).scrollTop();
lastScroll = currentPosition;
}, 100);
});
});
}
// `.scroll()` function
$(window).scroll(function() {
if (scrollLock == 0) {
var currentPosition = $(this).scrollTop();
if (currentPosition > lastScroll) {
paneIndex = paneIndex + 1;
} else {
paneIndex = paneIndex - 1;
}
scrollLock = 1;
$(panes[paneIndex]).scrollView();
}
});

Related

jQuery problems with offset()

I ran into a problem when creating a scroll for headlines.
I looked at the element code, the code swears at the element "..offset().top"
$(function() {
var header = $("header"),
introH = $("#intro").innerHeight(),
scrollOffset = $(window).scrollTop()
// scroll
checkScroll(scrollOffset)
$(window).on("scroll", function() {
scrollOffset = $(this).scrollTop()
checkScroll(scrollOffset)
})
function checkScroll() {
if (scrollOffset >= introH) {
header.addClass("fixed")
} else {
header.removeClass("fixed")
}
}
// scroll keys
$("[data-scroll]").on("click", function(event) {
event.preventDefault();
var
blockId = $(this).data("scroll"),
blockOffset = $(blockId).offset().top /* This line */
$("html, body").animate({
scrollTop: blockOffset
}, 500)
})
})
enter image description here

How can I control the mouse scroll event and after that do an animation on the html, body?

I'm facing a very strange error, which is animation on body during mouse scroll. I think its happening because of the jQuery event window.scroll. I have tried a lot of things like unbinding of animation on mouse scroll, but nothing works. Below is my code.
$(document).on("scroll", function () {
var lastScrollTop = 0;
var windowHeight = $(window).scrollTop();
var seccion1 = $("#seccion1").height();
var seccion2 = $("#seccion2").offset().top;
var alturaseccion2 = $("#seccion2").height();
//this function returns in which section is the user with the scroll
var localizacion = comprobarSeccion(seccion1, seccion2);
if (windowHeight > lastScrollTop) {
// down scroll
console.log("scrollabajo");
if (localizacion == 1) {
$("html, body").animate({
scrollTop: $("#seccion2").offset().top
}, 2);
$(document).bind("scroll");
} else if (localizacion == 2) {
if (windowHeight >= ((alturaseccion2 * 0.80) + seccion2) && windowHeight <= (alturaseccion2 + seccion2)) {
} else {
}
}
} else {
// up scroll
console.log("scrollarriba");
}
lastScrollTop = windowHeight;
});
ยดยดยด
I'm not sure what you are trying to accomplish, but if your trying to trigger an event with a specific scroll value you can use the code below
$(window).scroll(function () {
var scroll = $(window).scrollTop();
if (scroll >= 500) {
alert("scroll is greater than 500 px)
} else if(scroll==500){
alert("scroll has hit 500px");
}
});

Scroll a specific element inside container using JS or jQuery

I have huge sidebar element and when the page is scrolled sidebar point to the current element that is in a viewport. But sometimes active element is out of sidebar visible space i.e below or above borders. And then the user needs to scroll manually to be able to see active element.
I want to try use logic for determining if the active element is out sidebar visible space and auto scroll if needed.
$(window).on('scroll', function () {
var scrollTop = $(this).scrollTop();
var container = $('#sectionMenu');
var containerHeight = container.height();
$(data).each(function () {
var topDistance = $(this).offset().top - 250;
var id = $(this).attr('id');
var elem = $('#_' + id);
if ((topDistance) < scrollTop && (topDistance + $(this).height() * 0.95) > scrollTop) {
if (autoScrollFlag) {
if (!elem.hasClass('sideBarActive')) {
var scrollPosition = elem.offset().top - container.offset().top;
removeActiveMenuItems(data);
elem.addClass('sideBarActive');
if (containerHeight < scrollPosition) {
// TODO automated scroll
}
}
}
autoScrollFlag = 1;
}
});
});
The solution that has worked for me was like this.
if (containerHeight < scrollPosition) {
container.animate({
scrollTop: '+=100px'
}, 800);
}

Jquery add CSS class after 'X' amount of viewport height scrolled

So I have this jQuery function that adds / removes a CSS class to an element after 600px of the viewport height has been scrolled.
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 600) {
$(".cta_box").addClass('fadeout');
} else {
$(".cta_box").removeClass('fadeout');
}
});
I'd like to tweak it so instead of working based off a pixel value, it works off of the view height css measurement "VH", but the equivalent results are what matter in this case.
It can be done by getting the window height using $(window).height().
For instance suppose you have to scroll half the screen more (height is 150vh) and you have to detect when 40% has been scrolled:
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 0.4 * $(window).height()) {
$(".cta_box").addClass('fadeout');
} else {
$(".cta_box").removeClass('fadeout');
}
});
body{
margin: 0;
height: 150vh;
}
.cta_box {
height: 100%;
background: green;
}
.cta_box.fadeout {
background: grey;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="cta_box"></div>
Use a percentage of the window height to compare
$(window).scroll(function() {
var height = $(window).height(),
scroll = $(window).scrollTop()
limit = 0.6; //implies 60 vh or 60% of viewport height
if (scroll >= height*limit) {
$(".clearHeader").addClass("darkHeader");
} else {
$(".clearHeader").removeClass("darkHeader");
}
});
and even better would be to update some variable only when the window is resized to avoid computations all the time
var limit = 0.6, //implies 60 vh or 60% of viewport height
scrollLimit = 0;
$(window).resize(function(){
scrollLimit = $(window).height() * limit;
}).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= scrollLimit ) {
$(".clearHeader").addClass("darkHeader");
} else {
$(".clearHeader").removeClass("darkHeader");
}
}).trigger('resize').trigger('scroll'); // trigger both events on start to force initial setup
Try something like this
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 500) {
$(".clearHeader").addClass("darkHeader");
} else {
$(".clearHeader").removeClass("darkHeader");
}
});
For retrieveing the viewport Height, you could use $(window).innerHeight():
$(window).scroll(function() {
var scroll = $(window).innerHeight();
if (scroll >= 600) {
$(".cta_box").addClass('fadeout');
} else {
$(".cta_box").removeClass('fadeout');
}
});
Hope this helps.
Leo.

Fixed header navigation and scrollTo() next/previous elements

First off I use this code to make the navigation bar always stay fixed;
After adding CSS position absolute:
var yOffset = $("#header").offset().top;
$(window).scroll(function() {
if ($(window).scrollTop() > yOffset) {
$("#header").css({
'top': 0,
'position': 'fixed'
});
} else {
$("#header").css({
'top': yOffset + 'px',
'position': 'absolute'
});
}
});
But now my next/previous key events which used to scroll to next element is not catching the right element position.
here is my code for browsing next/prev element.
// scroll to next post
function scrollToNew () {
scrollTop = $(window).scrollTop();
$('.post').each(function(i, h1){
h1top = $(h1).offset().top;
if (scrollTop < h1top) {
$.scrollTo(h1);
return false;
}
});
}
// scroll to previous post
function scrollToLast () {
scrollTop = $(window).scrollTop();
var scrollToThis = null;
$('.post').each(function(i, h1) {
h1top = $(h1).offset().top;
if (scrollTop > h1top) {
scrollToThis = h1;
} else {
return false;
}
});
if(scrollToThis != null) {
$.scrollTo(scrollToThis);
}
}
I simply used to fire the scrollToNew when key pressed and it was working until I made the fixed navigation (#header) because it stays always on top so the heading of post which user scrolls to, becomes invisible. I do not know how to get around this issue.
Any suggestions are greatly helpful really.
Here is the fix.
I added the height of navigation header into offset. Which is exact 61pixels. Problems solved.
// scroll to next post
function scrollToNew () {
scrollTop = $(window).scrollTop();
$('.post').each(function(i, h1){
h1top = $(h1).offset().top;
if (scrollTop < h1top - 61) {
$.scrollTo(h1, {offset: {left: 0, top: -61}});
return false;
}
});
}
// scroll to previous post
function scrollToLast () {
scrollTop = $(window).scrollTop();
var scrollToThis = null;
$('.post').each(function(i, h1) {
h1top = $(h1).offset().top;
if (scrollTop > h1top - 61) {
scrollToThis = h1;
} else {
return false;
}
});
if(scrollToThis != null) {
$.scrollTo(scrollToThis, {offset: {left: 0, top: -61}});
}
}

Categories