Reposition DIV after scrolling - javascript

I have a navigation bar that repositions after scrolling down. It works with position:fixed, but while scrolling I want it to move up like all the other content that follow on the site . I the user stops scrolling it should reposition on top:
Heres a demo:
http://jsfiddle.net/gvjeyywa/7/
But I want it to be position:absolute (especially for the scrolling on the Ipad)
http://jsfiddle.net/gvjeyywa/5/
How do i let the JS overide my CSS? Here is my JS:
var isInAction = false;
var lastScrollTop = 0;
$(window).scroll(function(event){
var st = $(this).scrollTop();
if (st > lastScrollTop){
if (!isInAction){
isInAction = true;
$( "#navigation" ).animate({
top: "-" + $("#navigation").innerHeight() + "px"
}).delay(1000).animate({
top: "0px"
}, 800, function() {
isInAction = false;
});
}
}
lastScrollTop = st;
});

In the first look i think it's impossible but after some tries this code was created.
I spent long time to write this code and use several techniques and hope to be helpful.
Maybe there are simpler solutions too !!
var bitFlag = false;
var lastScrollTop = 0;
var timeoutId;
$navigation = $("#navigation");
$(window).scroll(function (event) {
var intWindowTop = $(window).scrollTop();
var intElementBottom = $navigation.offset().top + $navigation.innerHeight();
if (intWindowTop > lastScrollTop) {
if (!bitFlag) {
$navigation.css("position", "absolute").css("top", intWindowTop + "px");
bitFlag = true;
}
if (timeoutId) {
clearTimeout(timeoutId);
}
timeoutId = setTimeout(function () {
if (intWindowTop > intElementBottom) {
intDelayTime = setTimeout(function () {
$navigation.animate({
top: intWindowTop + "px"
}, 800);
}, 500);
}
}, 100);
} else {
$navigation.css("position", "fixed").css("top", "0px");
bitFlag = false;
}
lastScrollTop = intWindowTop;
});
The }, 500); section control Delay time in milliseconds and the }, 800); section control the slide down animation speed.
Check JSFiddle Demo

Related

Why is jQuery removeClass reappearing on scroll?

I have a div with a 2 logos in it and on scroll the first logo hides and the second appears using classes. On reverse scroll the second logo should hide and the first reappear. The first is reappearing but the second is hiding then reappearing when I reach the top of the page.
I've been going around in circles and I can't understand why on reverse scroll the 'show-logo' class is reappearing. Can anyone explain why?
JS:
if ($(window).width() > 640){
var scrollTop = $(window).scrollTop();
var header = $(".site-header");
if (scrollTop > 50) {
header.addClass("scrolling");
setTimeout(function() {
header.addClass("show-logo");
}, 500);
}
else {
header.removeClass("show-logo scrolling");
};
} else {
header.removeClass("show-logo scrolling");
}
Thanks in advance.
The setTimeout has no clue that it should not run so it runs. So if you do not want it to execute it, you need to cancel it. Two different ways depending on what you want to happen.
var myTimer = null;
var header = $(".site-header");
var win = $(window);
win.on("scroll", function() {
if (myTimer) {
window.clearTimeout(myTimer)
}
if ($(win.width() > 640) {
var scrollTop = win.scrollTop();
if (scrollTop > 50) {
header.addClass("scrolling");
myTimer = setTimeout(function() {
header.addClass("show-logo");
}, 500);
} else {
header.removeClass("show-logo scrolling");
}
} else {
header.removeClass("show-logo scrolling");
}
});
or
var myTimer = null;
var header = $(".site-header");
var win = $(window);
win.on("scroll", function() {
if ($(win.width() > 640) {
var scrollTop = win.scrollTop();
if (scrollTop > 50) {
header.addClass("scrolling");
if (!myTimer) {
myTimer = setTimeout(function() {
header.addClass("show-logo");
}, 500);
}
} else {
header.removeClass("show-logo scrolling");
if (myTimer) {
window.clearTimeout(myTimer)
myTimer = null
}
}
} else {
header.removeClass("show-logo scrolling");
}
});

Animate element on user scroll

I am currently using the logic below to animate a navigation block. It is working well when user scroll greater than 5px, the element animates out of the viewport. However the user must scroll top top of window for the element to animate back into position.
Rather than waiting for the user to scroll to the top of page how do I trigger the animate function as soon as a user scrolls up? (Not waiting till they get to the top of page)
var _throttleTimer = null;
var _throttleDelay = 100;
var $window = $(window);
var $document = $(document);
$document.ready(function () {
$window
.off('scroll', ScrollHandler)
.on('scroll', ScrollHandler);
});
function ScrollHandler(e) {
clearTimeout(_throttleTimer);
_throttleTimer = setTimeout(function () {
//console.log('scroll');
if($(window).scrollTop() > 5) {
$( ".mobile_header .content" ).animate({
top: "-34px"
}, 100 );
} else {
////Need help here
$( ".mobile_header .content" ).animate({
top: "34px"
}, 100 );
}
}, _throttleDelay);
}
Heres is the solution. had to modify logic to detect if the user scroll down or scroll up.
var _throttleTimer = null;
var _throttleDelay = 100;
var lastScrollTop = 0;
var $window = $(window);
var $document = $(document);
$document.ready(function () {
$window
.off('scroll', ScrollHandler)
.on('scroll', ScrollHandler);
});
function ScrollHandler(e) {
clearTimeout(_throttleTimer);
_throttleTimer = setTimeout(function () {
console.log('scroll');
var st = $(this).scrollTop();
if (st > lastScrollTop && $(window).scrollTop() > 5){
$( ".mobile_header .content" ).animate({
top: "-34px"
}, 100 );
} else {
$( ".mobile_header .content" ).animate({
top: "34px"
}, 100 );
}
lastScrollTop = st;
}, _throttleDelay);
}

Animation ( bar fills up over time ) with Jquery (Suggestion)

I would like to replicate the same functionality as at ign.com, where the indicator bar fills up over time. I got it working but I got some sync issues after a while. So i'm open to suggestions to do it from scratch (I'm beginner with all this animation stuff).
This is the code.
function GoProgressBar() {
var $lineStatus = $('.featured-articles-line-status');
$lineStatus.css('width', '0px');
$lineStatus.animate({ width: '694px' }, 12000, 'linear', GoProgressBar);
};
function GoOverlay(width, isLast, currentWidth) {
var $overlayLine = $('.status-overlay');
if (isLast) {
$overlayLine.css('width', '0px');
return;
}
if (currentWidth) {
$overlayLine.css('width', currentWidth);
$overlayLine.animate({ width: width }, 700);
} else {
$overlayLine.css('width', '0px');
$overlayLine.animate({ width: width }, 700);
}
};
function ShowNextElement() {
var $elements = $('.element'),
$overlayLine = $('.status-overlay'),
$liElements = $('#elements li'),
width;
if (currentElement === elements[elements.length - 1]) {
currentWidth = $overlayLine.width() + 'px',
width = currentWidth + $($liElements[(elements.length - 1)]).outerWidth() + 'px';
GoOverlay(width, true, currentWidth);
currentElement = elements[0];
$elements.hide();
$(currentElement).fadeIn(1000);
return;
}
i = elements.indexOf(currentElement) + 1;
var currentTab = $liElements[(i - 1)],
currentWidth = $overlayLine.width();
if (currentWidth) {
width = currentWidth + $(currentTab).outerWidth() + 'px';
GoOverlay(width, false, currentWidth);
} else {
width = $(currentTab).outerWidth() + 'px';
GoOverlay(width, false, false);
}
currentElement = elements[i];
$elements.hide();
$(currentElement).fadeIn(1000);
}
Thanks!
http://jqueryui.com/progressbar/
You could try this..
There are more features in addition to this,check it out.
Might come useful :)
There are a wealth of ways in which you could do this.
You should have some kind of controller to manage the show and hide.
var Application = {
show : function() {
jQuery('.application-overlay').stop().animate({ top: 40 }, 500);
jQuery('.cf-ribbon').stop().animate({height: 1000},500);
},
hide : function() {
jQuery('.application-overlay').stop().animate({ top: -1200 }, 500);
jQuery('.cf-ribbon').stop().animate({height: 200},500);
}
};
Then you have your triggers : Application.show();
jQuery(document).ready(function() {
jQuery('.cf-speakers .span2 a').hover(function() {
jQuery('span',this).stop().animate({ opacity: 1.0 },100);
}, function() {
jQuery('span',this).stop().animate({ opacity: 0.0 },100);
});;
jQuery('.apply-now').click(function(e) {
Application.show();
e.stopPropagation();
e.preventDefault();
});
jQuery('body').click(function(e) {
var application = jQuery('.application-overlay');
if( application.has(e.target).length === 0)
Application.hide();
});
jQuery('.gallery a').click(function(e) {
var src = jQuery(this).attr('href');
jQuery('.main-container img').hide().attr('src', src).fadeIn('fast');
jQuery('.gallery a').each(function() {
jQuery(this).removeClass('active');
});
jQuery(this).addClass('active');
e.stopPropagation();
e.preventDefault();
});
});
Your css would of course come into play also but that can be left to you!
This should give you an example of what you need .. But you're already on the right track, sometimes there is merit in reusing other people code too you know! :)

jQuery function losing the called elements and only keeping the last caller

I am developing a parallax site, and I want to ease out the elements when the scrolling has stopped. So I developed a plugin to detect when the scrolling stops, and once it stops, then smooth out the movement of the element (The object moves 5 pixels on to the direction in which the user was scrolling). It works but only to the last element that the plugin was applied to. When i was trying to debug, I see that both elements are still in effect inside the $(window).scroll(function(event) { but once we reach $(window).scrollStopped(function(){ only the last element is in effect. Any solutions?
// Scroll Direction set
var lastScrollTop = 0, scrollDirection = "";
$(window).scroll(function(event){
var st = $(this).scrollTop();
if (st > lastScrollTop){
scrollDirection = "down";
} else {
scrollDirection = "up";
}
lastScrollTop = st;
});
// Scroll Stopped detection
$.fn.scrollStopped = function(callback) {
$(this).scroll(function(){
var self = this, $this = $(self);
if ($this.data('scrollTimeout')) {
clearTimeout($this.data('scrollTimeout'));
}
$this.data('scrollTimeout', setTimeout(callback,250,self));
});
};
// Smooth ending
$.fn.smoothStop = function () {
var $this = $(this);
$(window).scroll(function(event) {
$(window).scrollStopped(function(){
var top = parseFloat($this.css("top"));
if(scrollDirection == "down")
{
console.log(top, $this);
var new_top = top + 5;
$this.animate({
top: new_top + 'px'},
1000);
}
else{
var new_top = top - 5;
$this.animate({
top: new_top + 'px'},
1000);
}
});
});
};
$(".g6").smoothStop();
$(".g2").smoothStop();
JSFIDDLE
// Scroll Stopped detection
$.fn.scrollStopped = function(callback) {
$(this).scroll(function(){ <-- this is the window
var self = this, $this = $(self);
if ($this.data('scrollTimeout')) {
clearTimeout($this.data('scrollTimeout')); <----timeout is removed from window
}
$this.data('scrollTimeout', setTimeout(callback,250,self)); <----timeout is set to window
});
};
basically you are trying to run multiple events, but you end up storing those multiple events in the same memory location. So when you add a new one, it cancells out the previous entry.

Footer toggle with two images for closing

Thank you for giving me the opportunity to be helped.
I would like to create a toggle footer (slide pannel).
I found the code below which works fine but I want to be able to close the footer with two different buttons: the same image I used to open (#footer_button) AND another image (a cross) placed inside the content (#footer_content).
How should I proceed to integrate the same function on this image (#footer_button_2) with this code?
Many thanks in advance!
Here is a printscreen: http://hpics.li/cb5b88a.
Here is the code I use:
<script type="text/javascript">
jQuery(function($) {
var slide = false;
var height = $('#footer_content').height();
$('#footer_button').click(function() {
var docHeight = $(document).height();
var windowHeight = $(window).height();
var scrollPos = docHeight - windowHeight + height;
$('#footer_content').animate({ height: "toggle"}, 1000);
if(slide == false) {
if($.browser.opera) { //Fix opera double scroll bug by targeting only HTML.
$('html').animate({scrollTop: scrollPos+'px'}, 1000);
} else {
$('html, body').animate({scrollTop: scrollPos+'px'}, 1000);
}
slide = true;
} else {
slide = false;
}
});
});
</script>
You can separate them with comas like in CSS: $('#footer_button, #CrossImgID') :)
<script type="text/javascript">
jQuery(function($) {
var slide = false;
var height = $('#footer_content').height();
$('#footer_button, #CrossImgID').click(function() {
var docHeight = $(document).height();
var windowHeight = $(window).height();
var scrollPos = docHeight - windowHeight + height;
$('#footer_content').animate({ height: "toggle"}, 1000);
if(slide == false) {
if($.browser.opera) { //Fix opera double scroll bug by targeting only HTML.
$('html').animate({scrollTop: scrollPos+'px'}, 1000);
} else {
$('html, body').animate({scrollTop: scrollPos+'px'}, 1000);
}
slide = true;
} else {
slide = false;
}
});
});
</script>

Categories

Resources