Animation affecting siblings position - javascript

I have animation on one element but its movement affects siblings as well. How can I have animation only on item without affecting siblings element?
Example of problem:
function animateSearch() {
$('.glyphicon-search').animate({'margin-top':'-10px'}, 1000);
$('.glyphicon-search').animate({'margin-top':'0px'}, 1000);
}
var interval = setInterval(animateSearch,1000);
$('.arrowDown').mouseover(function() {
clearInterval(interval);
});
DEMO: jsfiddle

Simply put Css postion:absolue rule like bellow :
.glyphicon-search {
position:absolute;
}
Fiddle Here

Related

Prevent jQuery from jumping to the bottom (when using fadeIn)

I've created some divs fading in with jQuery, I have a problem if the user scrolls a bit down though. If you are not at the top of the page, it will always jump to the bottom when a new div fades in.
Here's my code:
<style>
#overflowwrap {
overflow:hidden !important;
}
</style>
<div id="overflowwrap">
<div id="five" style="display: none;">a lot of content</div>
<div id="four" style="display: none;">a lot of content</div>
<div id="three" style="display: none;">a lot of content</div>
<div id="two" style="display: none;">a lot of content</div>
<div id="one" style="display: none;">a lot of content</div>
</div>
<script>
$('#overflowwrap').css('max-height',$(window).height());
$("#one").fadeIn(500);
setTimeout( function show() {
$("#two").fadeIn(500);
}, 3000);
setTimeout( function show() {
$("#three").fadeIn(500);
}, 6000);
setTimeout( function show() {
$("#four").fadeIn(500);
}, 9000);
setTimeout( function show() {
$("#five").fadeIn(500);
}, 12000);
</script>
Update: Example fiddle: https://jsfiddle.net/6qj1hbp0/1/
This wouldn't be a problem, if this was the only element on a page and the user couldn't scroll. However, it's integrated on another site (survey software), so the user is able to scroll.
Is there anything I can do to prevent the site from jumping to the bottom?
Try a different approach.
Instead, of display: none on every element, try opacity: 0;
Then instead of:
setTimeout( function show() {
$("#two").fadeIn(500);
}, 5000);
use:
setTimeout( function show() {
$("#two").addClass('is-visible);
}, 5000);
and add:
.is-visible { opacity: 1 !important; }
within your <style> tags.
you cannot “freeze” scroll, but you can read and change the scroll position, especially because you are using jQuery.
My solution consists in saving the current position of the scroll immediately before the fadeIn instruction then reassign the same value immediately after, with this function:
function fadeInElement(id, time) {
var currentScroll = $(window).scrollTop();
$('#' + id).fadeIn(time);
$(window).scrollTop(currentScroll);
}
Then you may call the same function several times with different ids and duration time, something like this:
fadeInElement('one', 500);
or this:
setTimeout(function() {
fadeInElement('two', 500);
}, 5000);
You may look a working example on CodePen or on JSFiddle
In short, the easiest thing you can do is hide the previous div every time you show a new one.
https://jsfiddle.net/6qj1hbp0/2/
$("#one").fadeIn(500);
setTimeout( function() {
$("#one").hide();
$("#two").fadeIn(500);
}, 3000);
setTimeout( function() {
$("#two").hide();
$("#three").fadeIn(500);
}, 6000);
setTimeout( function() {
$("#three").hide();
$("#four").fadeIn(500);
}, 9000);
setTimeout( function() {
$("#four").hide();
$("#five").fadeIn(500);
}, 12000);
If you want to fade from one box to the other (which creates a much smoother looking effect), you will need to do some other stuff - most notably:
put the boxes in order, top to bottom, #one to #five (you should do this anyways - it just makes sense congnatively)
set the position to absolute for each of the boxes
set some other styles (see the fiddle below)
use a special class while a box is fading in
https://jsfiddle.net/6qj1hbp0/3/
It's simple. Just reorder your div's to the order you want to show them instead of "five, four, three, two, one".
Your browser doesn't have any intention to take you to the bottom, it's just trying to keep your view point fixed on the current hash navigation. As your fading div is always above, your scrollTop will just jump to the bottom.
Another solution - if you don't want to reorder - is to remove all div id's and creating other way to recognize them, something like "data-id".
PS: look for some id's after too!
Do you need to restrict the overflow with hidden?
You can just set overflow: auto and browser will automatically take care of ensuring scrollTop remains the same after the fade in. The element user is looking at after scroll will remain at the same offset. If user hasn't scrolled then it will show the latest faded element at the top
Here's a jsfiddle: https://jsfiddle.net/sm2qaa3c/2/
After re-reading your comment, it seems you always want to display the latest faded div at the top. In that case you want a function to reset scrollTop to 0. You want to do it on overflowwrap not window since that's where the overflow scrolling will happen.
['#one', '#two', '#three', '#four', '#five'].forEach((id, idx) => {
setTimeout(() => {
$(id).fadeIn(500);
$('#overflowwrap').scrollTop(0);
}, idx * 5000);
});
See jsfiddle: https://jsfiddle.net/sm2qaa3c/3/
Thanks for the answers, they didn't work for my purpose though.
However, I've got a solution from another forum which doesn't require changing the functionality. This seems to work:
$('#overflowwrap').css('max-height', $(window).height());
fadeIn("#one", 0)
fadeIn("#two", 5000)
fadeIn("#three", 10000)
fadeIn("#four", 15000)
fadeIn("#five", 20000)
function cs() {
console.log(document.scrollingElement.scrollTop)
}
document.scrollingElement.scrollTop = 16
function fadeIn(el, when) {
setTimeout(function show() {
var t=document.scrollingElement.scrollTop
$(el).fadeIn(500);
document.scrollingElement.scrollTop = t
}, when);
}
Here is a working example on JSFiddle: https://jsfiddle.net/6qj1hbp0/4/

Jquery animate created element

I made div, if i click on it, jquery makes bullet and that element is animated. This is code:
$('.square').click(function() {
$('<div class="bullet"></div>').appendTo($('body')).animate({
'margin-top': 554
}, 2000, function() {
$(this).remove();
});
});
It works properly when I'm not clicking second time on div before animation is done. If i do this, my second "bullet" starts animation from position of first.
How to fix that? Thank's for help :)
UPDATE##
Here's the jsfiddle with problem:
https://jsfiddle.net/2ghj1x45/
it's because the elements all have a size because they aren't positioned absolutely so each bullet div you add has display block, so will get it's own line where it's height is bullet size + margin top , which increases as it's animated. try instead using position absolute so the bullet div doesn't affect the layout of any other div
like so
$(bullet).animate({ top: value });
Why not timeout the click function with a variable:
var animating = false;
$('.square').click(function() {
if(!animating) {
animating = true;
setTimeout(function() {
animating = false;
}, 2000);
$('<div class="bullet"></div>').appendTo($('body')).animate({
'margin-top': 554
}, 2000, function() {
$(this).remove();
});
}
});
EDIT:
Updated JSfiddle

Hover out from two divs simultaneously

Have a look at the following JQuery code:
function my_hover()
{
$( "#up,#down" ).hover(
function() {
$("#up").animate({
"background-color": "#020306"
});
$("#down").animate({
"background-color": "#171716"
});
},
function() {
$("#up").css("background-color","#C8CACF" );
$("#down").css("background-color","#FAFAF8" );
}
);
}
There are two divs: #up,#down which I cannot wrap into a parent div(due to design restrictions). What I want to do is to animate the change in background color whenever #up or #down are being hovered. However, in case the mouse leaves one div by going directly to the other(the two divs are stuck together vertically) I do not want the last two lines of the above code being applied. I want them to be applied only when mouse hovers out from both divs. How may I achieve that? At users.sch.gr/ellhn you may see what is happening with the above code in the first left rectangle with the target photo (transition between up and down provokes change of color and that's not desirable).
Thank you
Try this.
HTML
<div id="up">Up</div>
<div id="down">down</div>
CSS
div{ transition:all 0.25s ease-in-out;}
#up{background:#C8CACF;}
#down{background:#FAFAF8;}
#up.up-hover{background-color:green;}
#down.down-hover{background-color:yellow;}
Script
$('#up, #down').mouseenter(function(){
//alert('hi')
$("#up").addClass('up-hover');
$("#down").addClass('down-hover');
})
.mouseleave(function(){
//alert('hi')
$("#up").removeClass('up-hover');
$("#down").removeClass('down-hover');
});
Fiddle Demo
Using the technique #nnnnn alluded to, e.g., using a timeout:
(function init() {
var $up = $('#up'),
$down = $('#down'),
hovered = false;
$up.hover(over, out);
$down.hover(over, out);
function over() {
hovered = true;
$up.css({
"background-color": "#020306"
});
$down.css({
"background-color": "#171716"
});
}
function out() {
setTimeout(function to() {
if (!hovered) {
$up.css("background-color", "#C8CACF");
$down.css("background-color", "#FAFAF8");
}
}, 1000);
hovered = false;
}
})();
http://jsfiddle.net/TudqT/3/
And with the elements inline next to each other, instead of vertically aligned:
http://jsfiddle.net/TudqT/5/

Using Jquery Animate to Move 2 items in a container

I'm trying to move two block at the same time within a container on hover and then off hover it will retain to its original state. When attempted this, it was unsuccessful. I was hoping for a little assistance doing this. here's an example of it:
var container = $('#blockcontainer');
var container2 = $('#blockcontainer .block1');
var container3 = $('#blockcontainer .block2');
container.hover(function(){
container3.animate({marginTop: '-100'}, 1000);
container2.animate({marginTop: '100'}, 1000);
});
http://jsfiddle.net/gy9py/
Would truly appreciate the assistance.
I positioned the elements absolutely within the parent container. The margin would always push the sibling element which is why it would disappear. Also changed hover to mouseenter and mouseleave.
You could also achieve the effect with CSS3 transitions.
http://jsfiddle.net/gy9py/3/
<script>
container.on({
'mouseenter': function(){
container3.stop().animate({top: '0'}, 1000);
container2.stop().animate({top: '100px'}, 1000);
},
'mouseleave': function(){
container3.stop().animate({top: '100px'}, 1000);
container2.stop().animate({top: '0'}, 1000);
}
});
</script>
Hopefully that's enough to get you started.

Animate and add class at the same time

I'm trying to add a class with top and left properties for animation, but the div just shifts to the added class attribute without animating.
#myClass.move {
top:100px;
left:100px;
}
The goal is to have the animation happen right when the class is added and animate based on the properties of the added class.
var shiftTop = parseInt($(".move").css("top"));
var shiftLeft = parseInt($(".move").css("left"));
$("#myClass").addClass("move").animate({top: "-="+shiftTop, left: "-="+shiftLeft}, 1000, function() {});
Is this possible?
Use jQueryUI.
Demo here
$("#myClass").click(function() {
$(this).addClass("move", 1000);
});​
$('#myClass').animate({top: "-="+shiftTop, left: "-="+shiftLeft}, 1000, function() {
$(this).addClass('#myClass');
});
Yes it's possible:
Add class before animate:
$("#myClass").addClass("move").animate({top: "-="+shiftTop, left: "-="+shiftLeft}, 1000);
demo
Add class after animate:
$("#myClass").animate({top: "-="+shiftTop, left: "-="+shiftLeft}, 1000, function() {
$(this).addClass('move');
});
demo
I'm assuming that you have an element with class .move in your document already, from which to read the shiftTop and shiftLeft values.
If all you need to do is change the top and left attributes you can remove the addClass step entirely, since the animate function adds them inline. If you do need the class applied after, do it in the animate callback.
Depending on your compatibility requirements you could also do this entirely with CSS, using transitions.

Categories

Resources