Jquery toggle width on scroll position looping - javascript

I'm trying to toggle the width of my pagination on scroll but the toggle seams to be looping and it grows and shrinks over and over once the scroll trigger is hit.
I'm looking for the pagination menu to grow out like a shelf at my scroll point. and hide when you reach back to the top section of the site. – alcoven 16 secs ago edit
My JS
$(window).on('scroll', function() {
var y_scroll_pos = window.pageYOffset;
var element_in_view = y_scroll_pos > activation_point;
var has_reached_bottom_of_page = max_scroll_height <= y_scroll_pos && !element_in_view;
if(element_in_view || has_reached_bottom_of_page) {
$('ul.pagination').animate({
width: 'toggle'
}, 350);
}
else {
$('ul.pagination').animate({
width: 'toggle'
}, 350);
}
});
http://codepen.io/alcoven/pen/XjLjVz

Related

How to add a jQuery scrollTop offset?

I'm trying to get the div to snap to the center of the viewport, right now it just snaps to the top. I was trying to put an offset of 50% but can only get it in px's.
EDIT
I added a new fiddle where I tried to include $(window).scrollTop() / 2)
http://jsfiddle.net/kZY9R/84/
$("#item").offset().top - 100
var body = $("html, body");
var items = $(".item");
var animating = false;
$(window).scroll(function() {
clearTimeout($.data(this, 'scrollTimer'));
if (!animating) {
$.data(this, 'scrollTimer', setTimeout(function() {
items.each(function(key, value) {
if ($(value).offset().top > $(window).scrollTop()) {
animating = true;
$(body).stop().animate( { scrollTop: $(value).offset().top }, 1000,'swing');
setTimeout(function() { animating = false; }, 2000);
return false;
}
});
}, 50));
}
});
I found this:
$('html, body').animate({scrollTop: $('#your-id').offset().top -100 }, 'slow');
Source: Run ScrollTop with offset of element by ID
Here's the trick to keep your viewport centralized on a particular div.
Prerequisites
You need to take into account the following three criteria to be able to centralize the viewport on a given item:
height of the last item that appeared on the viewport.
The distance of the last item from the top of the page, i.e. the offset().top of the item.
The height value of the viewport (i.e the window object).
Calculating Vertical Position of the Item
The required scrollTop value for the window can be calculated as in the following:
var scrollValue = itemOffset // offset of the item from the top of the page
- .5 * windowHeight // half the height of the window
+ .5 * itemHeight; // half the height of the item
You are basically, moving the top of your viewport to the item under view's top offset initially. This, as you've already experienced, snaps the item to the top of the window.
The real magic part comes when you subtract half of the window's height to go halfway along it vertically, and then shifting your view back down by adding half the item's height. This makes the item appear vertically centralized with regards to the viewport.
Note:
To be able to query the last item that appeared on the viewport, you have to iterate over all of the elements that have a top offset value (i.e. offset().top) less than or equal to that of the window's scrollTop value:
$.each($('.item'), function(i, value) {
if ($(viewport).scrollTop() >= $(this).offset().top) {
lastItemInView = $(this);
}
});
With the above, the lastItemInView variable will always end up with the last element visible in the window.
Demo
Not sure if you figured this out yet or not but I took some code from this answer (How to tell if a DOM element is visible in the current viewport?) that shows how to tell if an element is visible in the view port.
Using that I modified your code to loop through each item and find the first visible one in the viewport and then center that one also factoring in the margin-top you have. Let me know if this helps!
Fiddle: http://jsfiddle.net/kZY9R/86/
var body = $("html, body");
var items = $(".item");
var animating = false;
$(window).scroll(function() {
clearTimeout($.data(this, 'scrollTimer'));
if (!animating) {
$.data(this, 'scrollTimer', setTimeout(function() {
items.each(function(key, value) {
if (elementInViewport(value)) {
animating = true;
var margin = parseInt($(value).css('margin-top'));
$('html,body').animate({
scrollTop: $(value).offset().top - ($(window).height() + margin - $(value).outerHeight(true)) / 2
}, 200);
setTimeout(function() {
animating = false;
}, 2000);
return false;
}
});
}, 50));
}
});
function elementInViewport(el) {
var top = el.offsetTop;
var left = el.offsetLeft;
var width = el.offsetWidth;
var height = el.offsetHeight;
while (el.offsetParent) {
el = el.offsetParent;
top += el.offsetTop;
left += el.offsetLeft;
}
return (
top < (window.pageYOffset + window.innerHeight) &&
left < (window.pageXOffset + window.innerWidth) &&
(top + height) > window.pageYOffset &&
(left + width) > window.pageXOffset
);
}

jQuery animate on window scroll

I want to slid a div on window scroll to bottom. When document reach 800 (bottom) Div should scroll right 0 and less then 800 it should slid and hide.
Problem is when scrolling to bottom div is sliding and showing but again when scrolling to top it doesn't slid and hide.
This is my code
$(document).scroll(function () { // remove "$"
var s = $("#slidebox");
var y = $(this).scrollTop();
if (y > 800) {
s.animate({"right":"-450px"}, "slow");
} else if (y < 800) {
s.animate({"right":"0px"}, "slow");
}
});
Basically i want is to hide and show (with a slid effect) div on document scroll to bottom.
Check scrolling below jsfiddle.
jsfiddle
On one hand, user390....'s response is correct in that the height is calculated incorrectly.
On the other hand, the way animations work is that they queue up one after another, so sometimes the div doesn't slide in/away until everything else before it is done. Using .stop() fixes the issue.
var s = $("#slidebox");
$(document).scroll(function () { // remove "$"
var y = $(this).scrollTop() + $(window).height();
console.log(y);
if (y > 800) {
s.stop().animate({"right":"-450px"}, "slow");
} else {
s.stop().animate({"right":"0px"}, "slow");
}
});
Your problem is that the value you are using for your "Did I reach the bottom" if statement is wrong.
Here is the calculated value you should be using:
$(document).scroll(function () { // remove "$"
var s = $("#slidebox");
var y = $(this).scrollTop();
var bottom = jQuery(document).height() - jQuery(window).height();
if (y >= bottom) {
s.animate({"right":"-450px"}, "slow");
} else {
s.animate({"right":"0px"}, "slow");
}
});
Plus, I'd also recommand you to use a .stop(true, true) on your animated element before triggering the "animate" function if you don't want people to mess around with it.

scroll to next div already in browser

I have a series of divs that are 100% height with a scroll to function that takes you to the next div out of the viewport on background click. However, if the next div is already slightly in the viewport the whole thing is counted as being visible and the scroll to bypasses it. Can anyone offer direction on how to get the script to scroll to the div even if it's partially in the viewport already?
Codepen here.
If you begin scrolling slightly in the codepen and then click on the background you'll see that it doesnt scroll you to the div that's already in the viewport but the div after that.
$(document).ready(function() {
// get initial nav height
var $window = $(window);
var wst = $window.scrollTop();
var th = $('div.top').height();
var currentSlide = $('#wrapper').data( 'current-slide', $('div.slide').eq(0) );
$('div.scroll_images').css({ height: 'auto', overflow: 'visible', top: 0 });
$('div.scroll_images div.inner').css({ position: 'absolute', top: 0 });
$('div.slide').each(function() {
$(this).css('padding',function() {
return (($(window).height()-$(this).height())/2)+'px 0'
});
});
// scrollto for click on slide
jQuery.fn.scrollTo = function(hash) {
$this = $(this);
st = $this.offset().top - th; // subtract nav height
$('html, body').animate({ scrollTop: st }, 550
);
}
$('#wrapper').click(function(e){
//get the current slide index from the body tag.
$this = currentSlide.data( 'current-slide' );
$next = $(".slide:below-the-fold");
if($next.length) {
$next.scrollTo($next.attr('id'));
//Save the next slide as the current.
$('#wrapper').data( 'current-slide', $next );
} else {
//Throw us back to the top.
$('div.slide:first').scrollTo($('div.slide:first').attr('id'));
//Save the first slide as the first slide, which
//Cycles us back to the top.
$('#wrapper').data( 'current-slide', $('div.slide:first'));
}
})
//Images fade in
$('img').hide();
$('img').each(function(i) {
if (this.complete) {
$(this).fadeIn();
} else {
$(this).load(function() {
$(this).fadeIn();
});
}
});
//Stop links affecting scroll function
$("a").click(function(e) {
e.stopPropagation();
});
});
(function($) {
$.belowthefold = function(element, settings) {
var fold = $(window).height() + $(window).scrollTop();
return fold <= $(element).offset().top - settings.threshold;
};
$.extend($.expr[':'], {
"below-the-fold": function(a, i, m) {
return $.belowthefold(a, {threshold : 0});
}
});
})(jQuery);
Here's what I might try to do: go through each div in the series. Find the div who's offset() is closest to $(window).scrollTop(). Now, find the next() div after the "current" one and scroll to it.
For comparing the offset() of each div, try something like this:
var closest = $('[selector]:first');
$('[selector]').each(function() {
var oldDistance = Math.abs(closest.offset() - $(window).scrollTop());
var newDistance = Math.abs($(this).offset() - $(window).scrollTop());
if(newDistance < oldDistance) {
closest = $(this);
}
}

Reverse fixed menu animation

The menu is currently set up so that when you open a page it is visible at the bottom of the page. As you scroll up the black menu panel will disappear out of view then reappear with the logo from the top.
Is there a way to reverse it so that once you scroll back up the black menu will disappear and reappear at the bottom of the page?
see website by clicking here
var distance = $('#content-div').offset().top,
$window = $(window);
var didscroll=true;
$window.scroll(function() {
if(didscroll==true){
if ( $window.scrollTop() >= distance ) {
didscroll = false;
//alert("r");
// Your div has reached the top
jQuery('.header').css({"position":"fixed","top":'-100px',"left":0});
jQuery('a.logo').css("visibility","visible");
jQuery( ".header" ).slideDown( 5000, function() {
jQuery(this).css({"top":0});
});
}
}
});
});
Remove the inline styles when you reached the breakpoint. Like this
if ( $window.scrollTop() >= distance ) {
$(".header").attr({style : ""});
$("a.logo").attr({style : ""});
}
Try this one..
var oritop = -100;
$(window).scroll(function() { //on scroll,
var scrollt = window.scrollY; //get the amount of scrolling
var elm = $(".box"); //get the box we want to make sticky
if(oritop < 0) {
oritop= elm.offset().top; //cache the original top offset
}
if(scrollt >= oritop) { //if you scrolled past it,
//make it sticky or else
}
else { //otherwise
//Do what you want to
}
});

Jquery slide in div keeps moving on scroll

I have aa div that I want to slide in once the user scrolls down a specified amount. It initially works but after than the div keeps moving to the left a little on every scroll action instead of staying in place. Anyone has an idea why is this happening?
var opening = false;
var closing = false;
$(window).scroll(function(){
var windowHeight = $(window).height();
var windowScroll = $(window).scrollTop();
var position1 = $("#Support").offset().top;
if ( windowScroll > (position1 - (windowHeight/2)) )
{
if (!opening) {
opening = true;
closing = false;
$("#SupportImage1").stop().animate({
left: "1200px"
}, 1500, function(){
opening = false;
});
}
}
else
{
if (!closing) {
closing = true;
opening = false;
$("#SupportImage1").stop().animate({
left: "100%"
}, 1400, function() {
closing = false;
});
}
}
});
the scroll bar is most likely affecting your width calculations.
everytime you run that function against the scroll bar you are adding in the total screen width plus the offset by the scroll bar.

Categories