Footer slides up with .slideUp but then slides down - javascript

I've got the jQuery .slideUp and .slideDown function below, and when reaching the #showfootershop div at the bottom of the browser window, the #footershop div slides up and then immediately slidesdown.
How can I get the #footershop to remain "up" and visible when #showfootershop is at the bottom of the browser window and not slide down until the user scrolls the browser window up?
Fiddle: http://jsfiddle.net/8PUa9/1/
jQuery:
$(window).scroll(function(){
/* when reaching the element with id "showfootershop" we want to
show the slidebox. */
var distanceTop = $('#showfootershop').offset().top - $(window).height();
if ($(window).scrollTop() > distanceTop)
$("#footershop").slideUp();
else
$("#footershop").slideDown();
});
html in footer:
<div id="showfootershop"></div>
<div id="footershop">
<h1>Shop Links</h1>
</div>
</body>
</html>
CSS:
#footershop {
height:35px;
width:100%;
display: none;
z-index: 2;
}

Use two functions for slidingUp and slidingDown, and toggle them once you have shown the slider and hidden it alternatively.
$(function() {
var slideUp = function() {
if ($(window).scrollTop() + $(window).height() >= $(document).height()) {
console.log('At bottom!!');
//toggle the handlers
$("#footershop").slideDown(function() {
$(window).off('scroll', slideUp).on('scroll', slideDown);
});
}
};
var slideDown = function() {
if ($(window).scrollTop() + $(window).height() < $(document).height()) {
//toggle the handlers
$("#footershop").slideUp(function() {
$(window).off('scroll', slideDown).on('scroll', slideUp);
});
}
};
$(window).on('scroll', slideUp);
});​
EDIT: I think the main problem you have is #footershop increases document.height when it shows and reduces when hidden, which is correct. This causes additional scroll events which creates the undesired behaviour.
Check this fiddle: I fixed this partially.
http://jsfiddle.net/BuddhiP/8PUa9/8/
Check this JSBin version for fixed version: http://jsbin.com/axobow/2
Main thing I did was #footershop is now absolutely positioned, so it doesn't cause the document size to change when shown or hidden, which is important in this case as if document.height() changed it affects you calculation.
Although fiddle works as expected, div is not positioned right on bottom. I hope you can fix that.
Hope this helps.
NOTE: You need to test the fiddle with full-height window, otherwise you will not see the footer sliding up since it shows somewhere in the middle of text.

I'm not sure what's wrong with the other answers that you haven't accepted, but here's mine:
JSFiddle
JS:
$(window).scroll(function() {
var distanceTop = $('#showfootershop').offset().top - $(window).height();
if ($(window).scrollTop() >= distanceTop - 20) {
$("#footershop").animate({
'height': '35px'
}, 'fast');
}
else {
$("#footershop").animate({
'height': '0px'
}, 'fast');
}
});​
CSS:
#footershop {
height:0px;
width:100%;
z-index: 2;
background:#00ffff;
position: absolute;
bottom:0;
left:0;
overflow:hidden;
}
body {
position:relative;
}
​

An alternative to all of this jQuery slideUp/slideDown is to use CSS to handle it.
We detect when the user has reached your #showfootershop element and then add or remove a class from the footer:
$(window).scroll(function()
{
var distanceTop = $('#showfootershop').offset().top - $(window).height();
if($(document).scrollTop() >= distanceTop)
$('#footershop').addClass("show");
else
$('#footershop').removeClass("show");
}
Then we use CSS to display the footer or hide it depending on the presence of that class:
#footershop
{
position: fixed;
height: 0px;
z-index:999;
bottom: 0;
overflow:none;
-moz-transition:all 0.5s ease-in-out;
-o-transition:all 0.5s ease-in-out;
transition:all 0.5s ease-in-out;
-webkit-transition:all 0.5s ease-in-out;
}
#footershop.show
{
height:35px;
-moz-transition:all 0.5s ease-in-out;
-o-transition:all 0.5s ease-in-out;
transition:all 0.5s ease-in-out;
-webkit-transition:all 0.5s ease-in-out;
}
As you can see above when the .show class is on the footer we change the height of the footer element to display it. CSS transitions are then used to animate this change.
The nice thing about this method is it's very lightweight and efficient (especially if you've got a lot of jQuery animations working at the same time), and you can easily animate various different changes like the opacity, text and background colours, etc. without needing to touch your JS at all.
jsFiddle
Here's your jsFiddle modified
http://jsfiddle.net/DigitalBiscuits/8PUa9/29/

slideUp() will also hide the element and offset of a hidden element is [0,0] so the instant footer is hidden distanceTop is negative. You could animate height to zero and get same visual result and since you aren't hiding the footer it will still have same top offset

I would recommend just putting a little buffer inbetween your scroll up and scroll down code.
I have made a slight tweak to your code to put in a buffer of 100px:
Javascript
$(window).scroll(function() {
var distanceTop = $('#showfootershop').offset().top - $(window).height();
if ($(window).scrollTop() >= distanceTop) {
$("#footershop").slideDown();
}
else if ($(window).scrollTop() < (distanceTop - 100)) {
$("#footershop").slideUp();
}
});
Demo

Trying to scroll to an element is way too messy, just use the bottom of the page.
$(window).scroll(function() {
if ($(window).scrollTop() + $(window).height() == $(document).height()) {
$("#footershop").slideDown();
}
else {
$("#footershop").slideUp();
}
});​
jsfiddle

Related

jQuery animate not taking easing on transform

I have a problem while trying to make a scale animation. I have a video element as a background and have scaled it to (1,1) at beginning. I have binded the mouse move in the document to get the position and scale the video whenever the mouse moves in Y axis, it scales accordingly like zoom in and out effect. However I have been trying to implement easing option to that but it just scales without the effect. Here is my code
$(document).mousemove(function(event) {
var pos = (event.pageY / 4000);
$("#bgvid").animate({
transform: pos
},
{ step: function(now, fx) {
$(this).css('-webkit-transform', 'scale('+ (1+pos) +','+ (1+pos) +')');
},
duration: '100',
queue:false,
easing:'swing'
});
});
So what it does is whenever cursor enters the document and moves in Y axis, it starts to scale from 1 to (1+value) whenever I move the cursor down/up scaling the <video> element. But it is not taking the easing.
What I am trying to achieve is similar to this website.
http://admirhadzic.com/#/project/kamui
Workaround as suggested by #ntgCleaner
my jquery
$(document).mousemove(function(event) {
var pos = (event.pageY/50);
var wid = 120+pos;
$('#bgvid').stop().animate({
width : wid+'%',
left: -(pos/2)+'%'
}, 400,false,'swing');
});
element css
video.fullscreen {
position: absolute;
top:0;
left: 0;
right:0;
bottom: 0;
width: 120%;
z-index:1;
}
So, I've made a fiddle for you here.
What I've done is make a container for the thing you want to scale, then I've used CSS width to scale the container. I also added a transition effect on the container that's being animated so the thing will ease as you want.
html
<div class="box-container">
<div class="box"></div>
</div>
js
$(document).on('mousemove', function(e){
var mouseY = e.pageY;
$('.box-container').css({"width":mouseY+"px"});
})
css
.box-container {
width:200px;
position:relative;
transition:all 400ms ease-out; /* NOTE THIS LINE HERE FOR EASING */
}
.box-container:after {
content:"";
display:block;
padding-top:100%;
}
.box {
position:absolute;
}

Animate item on bottom of screen to top of screen in jquery

I am using jQuery and am making a "drawer" where a button appears (fixed to bottom of screen), that when clicked "slides" to the top of the screen. It's not in my example below but it shows content below it, which works (kinda).
I use jquery to animate it going up by setting the top and bottom attributes.
if (!mapShowing) {
$("#mapcontainer").animate({bottom: "auto", top: "0px"},1000,'swing');
$("#map").fadeIn();
$('#showmap').text('↓ Click to hide map ↓');
} else {
$("#mapcontainer").animate({bottom: "30px", top: "auto"},1000,'swing');
$('#showmap').text('↑ Click to show map ↑');
$("#map").fadeOut();
}
However, it goes up, but it never comes down. I am unsure how to fix this... I tried using blanks (top: '', etc), but that didn't work. I'm not sure how to "slide" up a button from the bottom to top... perhaps make the bottom values positive instead? I can't find a lot of documentation on how to clear top bottom left right values, nothing I do seems to work.
https://jsfiddle.net/01h95r7s/2/
Here is a super simplified setup...with very little jquery and better CSS use
https://jsfiddle.net/01h95r7s/4/
HTML
<div id="map"></div>
Jquery
$(document).on('click', '#showmap', function(){
$('#map, #showmap').toggleClass('open');
});
CSS
#map{
position: fixed;
display: block;
left:0; right:0;
top:100%; bottom:0;
background:#555;
-webkit-transition: height 500ms, top 500ms;
transition: height 500ms, top 500ms;
}
#map.open{
top:40px;
}
#showmap {
position:fixed;
bottom:0; left:0;
z-index:5;
-webkit-transition: all 500ms;
transition: all 500ms;
}
#showmap.open {
bottom:100%;
margin-bottom:-37px;
}
#showmap:after {
content:'▲ Click to Show Map ▲';
}
#showmap.open:after {
content:'▼ Click to Hide Map ▼';
}
this should works
if (!mapShowing) {
$("#mapcontainer").animate({ bottom: ($(window).height()-$("#mapcontainer").height())+"px"},1000);
$("#map").fadeIn();
$('#showmap').text('↓ Click to hide map ↓');
} else {
$("#mapcontainer").animate({bottom: "30px"},1000);
$('#showmap').text('↑ Click to show map ↑');
$("#map").fadeOut();
}
}
demo here
https://jsfiddle.net/3yf0q86b/
and better to add animating detection and stop the animation
if($("#mapcontainer").is(':animated'))
$("#mapcontainer").stop()

Smooth Transition Between Background Images

So, I made this script where the background changes the farther you scroll down the page, but I want it so there is a transition between each of the images. So when you scroll from one image to the next, it slowly fades into the next. Sort of like a parallax.
JS:
$(document).ready(function() {
$("body ").css("background-image", "url('http://i.imgur.com/rs2Ittp.jpg')");
$(window).scroll(function() {
if($(this).scrollTop() > 0) {
$("body ").css("background-image", "url('http://i.imgur.com/rs2Ittp.jpg')");
}
if($(this).scrollTop() > 1000) {
$("body ").css("background-image", "url('http://i.imgur.com/H5QLuD6.jpg')");
}
if($(this).scrollTop() > 2000) {
$("body ").css("background-image", "url('http://i.imgur.com/KzZpgdS.jpg')");
}
if($(this).scrollTop() > 3000) {
$("body ").css("background-image", "url('http://i.imgur.com/UsLLJSx.jpg')");
}
});
});
Any solutions are appreciated (:
The easiest solution is through CSS:
body {
transition: background-image 0.5s ease-in-out;
}
Edit: My answer may have been a bit premature, since this is not a cross-browser solution. A better way to do this would be by using two divs with different background images using transition: opacity 0.5s; A lot more javascript is involved in this solution though.
Here's one way of doing it.
Create two elements with position: fixed, then change the opacity as you scroll. Once you get over a certain scroll position, swap the next images in and use the same opacity logic minus the intended scroll length.
edit: my opacity math could be more refined + need to add swapping the images back when scrolling the reverse direction
<!-- html -->
<div class="bottom"></div>
<div class="top"></div>
/* css */
.bottom,
.top {
position: fixed;
background-size: cover;
height: 100%;
width: 100%;
}
// js
var img1 = 'url(http://i.imgur.com/rs2Ittp.jpg)'
, img2 = 'url(http://i.imgur.com/H5QLuD6.jpg)'
, img3 = 'url(http://i.imgur.com/KzZpgdS.jpg)'
$(document).ready(function() {
$('.top').css("background-image", img1)
$('.bottom').css("background-image", img2)
$(window).scroll(function() {
var scrollTop = $(this).scrollTop()
if (scrollTop < 1000) {
$('.top').css('opacity', 100 / scrollTop)
}
else if ($(this).scrollTop() > 1000) {
$('.top').css("background-image", img2)
$('.bottom').css("background-image", img3)
$('.top').css('opacity', 100 / (scrollTop - 1000))
}
})
})
codepen

Can you fix a div and make it change opacity, size and position as you scroll with CSS3

I'm not even sure how to search this question. But effectively I'm trying to figure out how this website is achieving this fixed opacity/size changing effect on their table: http://sqlzoo.net/wiki/SELECT_within_SELECT_Tutorial . If you scroll down you'll see the effect on the table. When you hover over it it pops out having the data more visible.
The only thing I can think of is using a fixed div that when scrolled past a certain point triggers a jquery UI event that shrinks while decreasing opacity and then an on hover event that reverses this effect.
Achieving this animation in the way I described above seems inefficient and I'm not sure if more (or all) can be done with CSS3. So basically can you achieve the effect shown on the page provided completely or almost completely in CSS3.
Also i looked at the source of the page and couldn't fish it out of the css and scripts they include.
Here's a fiddle of what I have so far. Haven't started on scrolling yet:
HTML
<div id="stuff">Blahblah</div>
CSS
div {
width:250px;
height:250px;
border:2px solid #a1a1a1;
}
JavaScript
$( "#stuff" ).click(function() {
$( "#stuff" ).animate({
width: "20%",
height:"20px",
opacity: 0.4
}, 1500 );
});
http://jsfiddle.net/thed0ctor/1kx5jg1e/
You could do this easily with a combination of CSS3 transform and a bit of Javascript / jQuery:
Demo Fiddle: http://jsfiddle.net/abhitalks/hcwyth8n/2/
Relevant CSS:
#hanger {
width: 200px; height: 200px;
background-color: #00f;
position: fixed; /* Position fixed important */
top: 10px; right: 10px;
opacity: 1;
transition: 0.5s all; /* Animate transitions */
}
#hanger.dim { /* Style to make it appear dimmed */
transform: scale(.75); /* Make it smaller */
opacity: 0.5; /* Make it dimmer */
}
#hanger.dim:hover { /* To change back on hover only when it is dimmed */
transform: scale(1); /* Back to original size */
opacity: 1; /* Back to original opacity */
}
Relevant jQuery Code:
$(window).on("scroll", function() { /* When window scrolls, */
if ($(window).scrollTop() > 50) { /* Check if it scrolls more than 50 pixels */
$("#hanger").addClass("dim"); /* Apply class dim */
} else {
$("#hanger").removeClass("dim"); /* Otherwise remove class dim */
}
});
Hope that helps.
.
Pseudo code only:
window.scroll(function(){
if (window.scrolltop > selectedElement.offset().top){
selectedElement.animate({
transform: scale(.75),
opacity: .5
position: fixed
});
}else{
selectElement.animate({
transform: scale(.75),
opacity: 1
position: static
});
}
});
The links provided in the he pseudo code should point you in the right direction.

Animating a navigation menu coming in

I have some kind of sticky menu optimised with jQuery. I wrote some code to detect the height we're in and after a certain value bring the navigation down and make it sticky by setting its position value fixed!
Here is the code :
$(window).scroll(function () {
var $locationY = $(window).scrollTop(),
$defaultY = 385;
if ( $locationY < $defaultY ){
$('#nav').removeClass("sticky")
}
else {
$('#nav').addClass("sticky")
}
});
And the question is how can I animate this? To show up nicely for example slides from top to bottom. I wanna know what's the right approach for using slideDown, animate, ... methods for this case.
Thanks.
Something like this? DEMO http://jsfiddle.net/yeyene/UZgXB/1/
Not sure your sticky menu is shown on load or not.
JQUERY
$(document).ready(function () {
$(window).scroll(function () {
if ($(this).scrollTop() > 200) {
$('#nav').stop()
.addClass('sticky')
.animate({
'padding': '1% 2% 1% 2%'
}, 400, "swing");
} else {
$('#nav').stop()
.removeClass('sticky').addClass('normal')
.animate({
'padding': '6% 2% 6% 2%'
}, 400, "swing");
}
});
});
CSS
#nav, .normal {
float:left;
margin:0;
padding:6% 2%;
width:96%;
background:red;
}
.sticky {
position:fixed;
left:0;
top:0;
}
I think transition can help you.
#nav{
transition:top 2s ease;
}
And position the #nav using postion:fixed; and top:xxxpx; like
.sticky{
position:fixed;
top:300px;
}
demo Try it.
What I would do is have it position fixed, its top value equal to 0 minus its height. Then animate it to top value 0.
This way it will slide from the top exactly like the facebook timeline menu... The sticky class should have the negative top value, the JS will correct it in animation.
$(window).scroll(function () {
var $locationY = $(window).scrollTop(),
$defaultY = 385;
if ( $locationY < $defaultY ){
$('#nav').removeClass("sticky")
}
else {
$('#nav').addClass("sticky").animate({top:0},400);
}
});

Categories