fadeOut() and slideUp() at the same time? - javascript

I have found jQuery: FadeOut then SlideUp and it's good, but it's not the one.
How can I fadeOut() and slideUp() at the same time? I tried two separate setTimeout() calls with the same delay but the slideUp() happened as soon as the page loaded.
Has anyone done this?

You can do something like this, this is a full toggle version:
$("#mySelector").animate({ height: 'toggle', opacity: 'toggle' }, 'slow');
For strictly a fadeout:
$("#mySelector").animate({ height: 0, opacity: 0 }, 'slow');

Directly animating height results in a jerky motion on some web pages. However, combining a CSS transition with jQuery's slideUp() makes for a smooth disappearing act.
const slideFade = (elem) => {
const fade = { opacity: 0, transition: 'opacity 400ms' };
elem.css(fade).slideUp();
};
slideFade($('#mySelector'));
Fiddle with the code:
https://jsfiddle.net/00Lodcqf/435
In some situations, a very quick 100 millisecond pause to allow more fading creates a slightly smoother experience:
elem.css(fade).delay(100).slideUp();
This is the solution I used in the dna.js project where you can view the code (github.com/dnajs/dna.js) for the dna.ui.slideFade() function to see additional support for toggling and callbacks.

The accepted answer by "Nick Craver" is definitely the way to go. The only thing I'd add is that his answer doesn't actually "hide" it, meaning the DOM still sees it as a viable element to display.
This can be a problem if you have margin's or padding's on the 'slid' element... they will still show. So I just added a callback to the animate() function to actually hide it after animation is complete:
$("#mySelector").animate({
height: 0,
opacity: 0,
margin: 0,
padding: 0
}, 'slow', function(){
$(this).hide();
});

It's possible to do this with the slideUp and fadeOut methods themselves like so:
$('#mydiv').slideUp(300, function(){
console.log('Done!');
}).fadeOut({
duration: 300,
queue: false
});

I had a similar problem and fixed it like this.
$('#mydiv').animate({
height: 0,
}, {
duration: 1000,
complete: function(){$('#mydiv').css('display', 'none');}
});
$('#mydiv').animate({
opacity: 0,
}, {
duration: 1000,
queue: false
});
the queue property tells it whether to queue the animation or just play it right away

Throwing one more refinement in there based on #CodeKoalas. It accounts for vertical margin and padding but not horizontal.
$('.selector').animate({
opacity: 0,
height: 0,
marginTop: 0,
marginBottom: 0,
paddingTop: 0,
paddingBottom: 0
}, 'slow', function() {
$(this).hide();
});

Related

How to replace margin-left animation with transform in Jquery animate() to fix laggy multislider

I'll preface this by saying my initial problem is difficult to reproduce.
Brief explanation of my problem following, question is at the bottom.
So I am using the Jquery multislider for a project.
Here is a link to it: Multislider
Now my issue is that the animation of the moving elements seems to lag... Sometimes.
It jumps instead of moving smoothly.
The way the element works is by applying the animate() method to the first item and applies an inline margin-left property to the first .item
With some research I have found that CSS animations often cause problems when margins are used for the animation(among some other properties like top/bottom/left/right, as well as height/width) and that using transform is preferable.
So far so good.
This is the snippet in the javascript that creates the animation:
function singleLeft(){
isItAnimating(function(){
reTargetSlides();
$imgFirst.animate(
{
marginLeft: -animateDistance /* This is the part that causes me problems */
}, {
duration: animateDuration,
easing: "swing",
complete: function(){
$imgFirst.detach().removeAttr('style').appendTo($msContent);
doneAnimating();
}
}
);
});
}
function singleRight(){
isItAnimating(function(){
reTargetSlides();
$imgLast.css('margin-left',-animateDistance).prependTo($msContent);
$imgLast.animate(
{
marginLeft: 0
}, {
duration: animateDuration,
easing: "swing",
complete: function(){
$imgLast.removeAttr("style");
doneAnimating();
}
}
);
});
}
Now if I understand it correctly, I have to replace the marginLeft: -animateDistance portion with a transformX property, is that correct?
But I am failing to make it work.
So my question is, how can I replace the marginLeft: -animateDistance portion with transform: translateX() and add the animateDistance variable between the parentheses?
I have tried something like transform: "translateX(-$(animateDistance))", but that just disables the animation entirely.
Am I missing something?
I'm open for other suggestions to solve the issue of the laggy animation as well, this just is the conclusion I came to.
You can use animate with $(this) and .css() if you use step()
let test = "100";
$('div h2').animate({ pxNumber: test }, {
step: function(pxNumber) {
$(this).css('transform','translateX(-' + pxNumber + 'px )');
},
duration:'slow',
easing: "swing",
complete: function(){
console.log('Animation done');
// doneAnimating();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div><h2>Move it</h2></div>

Child elements starting opacity while using velocity.js and blast.js

I have a simple wrapper div that I animate in using velocity.js UI pack. In the complete callback function, I am using a combination of UI pack and blast.js to animate three sentences.
The problem is that my sentences are initially shown, and only after that they are animated. They shouldn't be visible after the wrapper div is animated into view.
Everything is working fine if I don't animate the wrapper div, guess the opacity settings during animation are messing with child elements.
$('.wrap').velocity('transition.slideUpIn', {
delay: 1000,
display: null,
complete : function(){
$(".animated")
.blast({ delimiter: "character" })
.velocity("transition.fadeIn", {
display: null,
duration: 1000,
stagger: 60,
delay: 400
});
}
})
Here is the fiddle to see the problem : http://jsfiddle.net/vcsr6aqj/1/
The problem is that your p tags aren't at opacity: 0, but only their characters, which are inside a span having as class blast. Since your invisible characters are only created when you call $(".animated").blast({ delimiter: "character" }), which means once your wrapper has completed its apparition, the sentences will be visible until then. So you have two possibilities that I can think of.
Create your span characters with blast at the page load, instead at the wrapper velocity complete and then call velocity on your created spans:
$(document).ready(function() {
$(".animated").blast({ delimiter: "character" });
$('.wrap').velocity('transition.slideUpIn', {
delay: 1000,
display: null,
complete : function(){
$(".animated .blast").velocity("transition.fadeIn", {
display: null,
duration: 1000,
stagger: 60,
delay: 400
});
}
})
});
JSFiddle example
Add a class to your p tags having opacity: 0:
<p class="animated no-opacity">Sentence number one.</p>
<p class="animated no-opacity">Sentence number two.</p>
<p class="animated no-opacity">Just one sentence more.</p>
CSS:
.no-opacity {
opacity: 0;
}
When your wrapper has completed the velocity, remove the class from your p tags. Also, remove delay: 400 from your velocity attributes, otherwise the sentences will show for 400 milliseconds:
$(document).ready(function() {
$('.wrap').velocity('transition.slideUpIn', {
delay: 1000,
display: null,
complete : function(){
$animated = $(".animated");
$animated.removeClass("no-opacity");
$animated.blast({ delimiter: "character" })
.velocity("transition.fadeIn", {
display: null,
duration: 1000,
stagger: 60
});
}
})
});
JSFiddle example
Here you go (fiddle). I'm sure there are more elegant solutions.
It appears that the slideUpIn animates opacity from 0 to 1, including the opacity of .animated which is probably 'inherited'. Setting it to 0 to hide it fixes it, but then .blast() doesn't work, so we enable it again.

how to remove a method with a callback or otherwise

I have the following code that animates an object with a delay of 800 ms:
$('#navMenu').mousemove(function (e) {
thisX = e.pageX
if (thisX >= 1625) {
$('#prbBtnHolder').animate({ left: '-=150' }, 300).delay(800);
}
});
If the #prbBtnHolder has a certain css left property i want to be able to remove the delay()method and stop the animation. How do i do this? This is what I've tried so far:
//...
$('#prbBtnHolder').animate({ left: '-=150' }, 300).delay(800);
if ($('#prbBtnHolder').css('left') < -100) {
$(this).animate({left: '-=0px'});
}
But this does not remove the delay method nor does it achieve the desired effect. Any other ideas?
In order to clear the effects queue, you'll need to use the step callback to see if your condition is met.
http://api.jquery.com/animate/
$('#prbBtnHolder').animate({
left: '-=150'
},
{
duration: 300,
step: function(now, fx) {
if (now < -100) {
// uncomment and you'll see the next animation
$(fx.elem).clearQueue().stop();
}
}
}).delay(800).animate({ width: '200px', height: '200px' }, 300);
Here is a jsbin example:
http://jsbin.com/utejew/3
$(this).clearQueue();
jQuery Docs for clearQueue
Removes all elements in the effect Queue for the given Element. Otherwise you could use js native setTimeoutfunction to animate which can easily be cleared with clearTimeout.
Before you Animate $('#prbBtnHolder') you can calculate how far the Button is away from -100 and animate it only that far.

jquery menu slides in and bounces

http://jsfiddle.net/E6cUF/
The idea is that after the page finished loading the grey box slides left from behind the green box, if possible bounce a little.
Edit: made a new version based on changes people made to the jsfiddle and the comment from Nicola
http://jsfiddle.net/RBD3K/
However the grey one should be behind the green one and slide from right to left so it appears
To have it bounce you are missing two things i think:
1) you need to load jquery UI.
2) put the bounce effect after the animate effect:
$('#test').click(function() {
var $marginLefty = $('.left');
$marginLefty.animate({
marginLeft: parseInt($marginLefty.css('marginLeft'),10) == 0 ?
$marginLefty.outerWidth() :
0
}).effect("bounce", { times:5 }, 300);
});
updated fiddle: http://jsfiddle.net/nicolapeluchetti/E6cUF/4/
Try this . Not sure if this is what you want.
$('#test').click(function() {
var $marginLefty = $('.left');
var $marginRight = $('.right');
$marginLefty.animate({
marginLeft: 0
},{ duration: 200, queue: false });
$marginRight.animate({
marginLeft: 100
},{ duration: 200, queue: false });
});
Update: from your updated fiddle,add for .right position :absolute;z-index:1000 as css
http://jsfiddle.net/E6cUF/11/

mootools "fx.styles" and "addevent" equivalent in jquery

having a lot of trouble finding the equivalent of this code in jquery
var reveal = new Fx.Styles(div, {
duration: 200,
transition: Fx.Transitions.Quad.easeIn,
wait: true,
fps: 24
});
reveal.addEvent('onStart', function(){
tt_has(true);
});
I think it would become:
$(div).animate( {left: 500, top: 500}, 200, 'linear');
tt_has(true);
There is no 'start' event in jquery animations (they start automatically), so we call tt_has(true) right after the call to .animate(),
More info here.
Hope this helps. Cheers

Categories