I have a select2.js dropdown that I would like to animate; I would like the dropdown to slidedown instead of appear suddenly.
This is what I am doing now:
var select = $("#select").select2({
minimumResultsForSearch: -1
});
$('#select').on('select2:open', function (e) {
$("#select option[value='0']").remove();
$('.select2-results').hide().slideDown("slow", "easeInOutQuint");
});
The problem is that the first time I open the drop down, there is a slight lag/jitter. Here is a more precise description of what is happening:
Select container is clicked
Select dropdown starts sliding down.
20% down the animation, it lags for like 0.2s (trying to eliminate that)
Slide down then continues fine.
After the first time, the slideDown is flawless. It's just the first time that has the jitter/lag.
Any ideas?
Note that easeInOutQuint is coming from jQuery Mobile transitions.
You need to apply it on .select2-dropdown with timeout function check below code how i did achieve that
jQuery('#select').on('select2:open', function (e) {
jQuery('.select2-dropdown').hide();
setTimeout(function(){ jQuery('.select2-dropdown').slideDown("slow", "easeInOutQuint"); }, 200);
});
Related
I am working on a simple slideshow where each slide has its own duration.
I would like to add transitions between the slides using animate.css by adding and removing classes on the current and the next slides.
My problem is that - with my current approach - only the next slide will be animated (it slides in) but the current one is just disappear without any animation.
I have tried to detect the end of the current animation and then change(adding/removing) the classes but in that case there was a huge gap between the slides...
How can make sure that two animations plays at once?`
var slides = $this.find('.slide');
slideIt = function(time) {
setTimeout(function() {
var duration = slides.eq(nextSlide).data('duration');
slides.eq(currentSlide)
.removeClass(animateIn)
.addClass(animateOut)
.hide();
slides.eq(nextSlide)
.removeClass(animateOut)
.addClass(animateIn)
.show();
slideIt(duration);
currentSlide = nextSlide; nextSlide ++;
if (nextSlide == slidesLength) { nextSlide = 0;}
},time);
};
Thank you for the help in advance!
Ps.: While typing this post I have realized that it must be the .hide() but without it only the first slide displayed.
Native CSS animations on two different elements should always run at the same time.
But if you hide an element, it disappears before the animation has even started. You have to add a timer for that.
slides.eq(currentSlide)
.removeClass(animateIn)
.addClass(animateOut);
// save the jQuery instance of the element that should be hidden.
var $currentSlide = slides.eq(currentSlide);
// hide this element later
setTimeout(function() {
$currentSlide.hide();
}, 1000); // 1000 for 1000ms, replace that with the duration of the animateOut animation
If my first answer doesn't satisfy you, because you want so solve that on the CSS side, when there is a second way:
Remove the .hide() in JavaScript.
Make sure your CSS animation ends with a state, there the element cannot be seen anymore (like transform: scale(0) or left: -100%).
Maintain that final state of the CSS animation. To do that, see: Maintaining the final state at end of a CSS3 animation
Introduction
I'm using Semantic-UI's sidebar functionality, which gives you a button that triggers a sidebar that pushes the content from the left (in this case).
I want to unfold that same sidebar by hovering with the mouse on the left side. I realize there are several ways to do it (as these often do. Maybe just checking the X position of the mouse would work but that's beside the point); I chose to create a transparent div on the left side and make its :hover pseudo-class to trigger the sidebar:
// create sidebar and attach to menu open
$('.ui.sidebar').sidebar('attach events', '.toc.item');
// hover transparent div to trigger the sidebar too:
$('.sidebar-trigger').hover(function() {
$('.ui.sidebar').sidebar('show')
});
// hide() and show() the sidebar accordingly to use the sidebar:
$('.ui.sidebar').sidebar('setting', {
onShow: function() {
$('.sidebar-trigger').hide();
},
onHidden: function() {
$('.sidebar-trigger').show();
}
});
Problem
Now, it all works except for one occasion: when you don't stop moving the mouse as the sidebar opens. I've looked at $(document).on('transitionend', function(event) { ... } and that mouse effectively prevents the transition to finish.
Resources
I've put a blue background on my .sidebar-trigger and made a small video/gif so as to be clearer.
I moved the mouse like a crazy creature but with natural gestures the problem occurs as well.
I'm using Semantic-UI's guide on this thing: http://semantic-ui.com/modules/sidebar.html#/settings (I've also tried onVisible and onHide with no luck)
This is a OSX Yosemite 10.10.3 running Chrome 45.0.2454.101 (64-bit)
jsfiddle with the problem at hand
PS: It seems it might be an OSX Chrome bug?
I would try using one and mouseover:
$('.sidebar-trigger').one('mouseover', function() {
$('.ui.sidebar').sidebar('show')
});
Then, when it has finished animating, reattach the event:
$(document).on('transitionend', function(event) {
$('.sidebar-trigger').one('mouseover', function() {
$('.ui.sidebar').sidebar('show')
});
});
I think what is happening is that the hover event is getting called multiple times - every time the element is hovered, then goes over a child element, and then goes back over the hover element, and things are getting mixed up at some point. So you need to only call show if it's not already shown.
Here is a working example: Fiddle
I believe when the element was hovered, it was adding a classes 'uncover' and 'visible', and another called 'animating' which wouldn't fire until the mouse stopped moving. I changed the jQuery slightly to only add classes 'uncover' and 'visible', and it still animated okay. However, the body was pushing right too far by 175px, so I had to edit the class that was causing that (noted below) from 260px to 85px. This DOES get the menu acting properly though from my understanding.
$('.sidebar-trigger').mouseenter(function() {
$('.ui.sidebar').addClass('uncover, visible');
$('body').addClass('mleft175');
});
$('body').click(function() {
$('.ui.sidebar').removeClass('uncover, visible');
$('body').removeClass('mleft175');
});
and then add overriding class
.ui.visible.left.sidebar ~ .pusher
{
-webkit-transform: translate3d(85px, 0, 0);
transform: translate3d(85px, 0, 0);
}
Right now it is set to hide the menu when the body is clicked. Alternatively you can hide it when the mouse leaves the sidebar menu:
$('.ui.sidebar').mouseleave(function(){
$(this).removeClass('uncover, visible')
});
Ok, my first answer was (of course) way too much work for what it really needed. The onVisible seems to work perfectly. Was that not working for you? Demo HERE
Simply change 'onShow' to 'onVisible' in your sidebar setting:
$('.ui.sidebar').sidebar('setting', {
onVisible: function() {
$('.sidebar-trigger').hide();
},
onHidden: function() {
$('.sidebar-trigger').show();
}
});
As shown on the Semantic UI site, the onVisible fires when the animating starts. The onShow fires when the animating finishes. So what you were doing was hiding that blue / transparent bar when the animation was finally done (the .animating class noted in my previous answer), as opposed to when it starts. If you need further explanation please let me know.
I have a jQuery simple slider it has 15 picture each five show in a slide. I have a previous button and next button.
Each next click generate a left movement by 855px with a slider animation.
Each previous click generate a right movement by 855px with a slider animation.
This is my jQuery code :
$(document).ready(function(){
$(".prev_button").click(function(){
$("ul.slider").animate({
left: "+=855"
}, 3000, function(){
$("ul.slider").css('left', '0');
li_no = 0;
$("ul.slider").find("li").each(function(){
li_no = li_no + 1;
});
slide_after_this = li_no - 6;
$('ul.slider li:gt('+slide_after_this+')').prependTo('ul.slider'); // << line changed
});
});
$(".next_button").click(function(){
//alert($("ul.slider").css("right"));
$("ul.slider").animate({
right: "+=855"
}, 3000, function(){
//alert($("ul.slider").css("right"));
$("ul.slider").css('right', '0');
$('ul.slider li:not(:nth-child(n+6))').appendTo('ul.slider');
});
});
});
Now I have two problems :
First one is with the previous button (left arrow) When I click it the animation shows and the elements changed but they do not wrapped with each other (I mean does not show the last elements immidiatly before the first element). I can not find the reason of this.
Second problem is with both right and left arrows it is like following :
If I click just the right arrow the slider working fine it animates and change the elements but If I click the both button in order (I mean right then left or left then right ) the elements change but the animation does not show. but I check if the routine go inside the animate function by some alerts and it is going inside but does not animate on the screen .
This is a link that may help you:
http://jsfiddle.net/mpx83tpv/18/
you are really close try overflow:hidden for .slider_container
div.slider_container
{
height:380px;
width:855px;
margin-left:auto;
margin-right:auto;
overflow:hidden;
}
edit js:
also use below code as you are using both right and left in the end the slider has both of them one of them is always zero.
$(document).ready(function(){
$(".prev_button").click(function(){
$("ul.slider").animate({
left: "+=855"
}, 3000);
});
$(".next_button").click(function(){
//alert($("ul.slider").css("right"));
$("ul.slider").animate({
left: "-=855"
}, 3000);
});
});
if you want a infinite scrolling you need to use right and left in this case replace your $("ul.slider").css('right', '0'); line to $("ul.slider").css('right', ''); do same for left as well, as you need the remove them.
for adding the next visible div implement you logic before the animation as you callbacks do it after the animation.
the tricky part would be the prev button for this after calculation of the div count you also need the set new left without animation and then call left move animation.
hope these make sense.
I use jQuery function that should animate divs (Slide down and up) like a dynamic menu or something.
The problem is even I set up delay() - when mouse goes over it, no matter how long the cursor stays over one div it will slidewon and up.
To clarify. If I put a mouse over the certain div, it works well, it waits the delay and then slide. But if I fast goes over all divs in the example it will make a weird reaction, like the divs start to slide down but then suddenly stops and go up. Try my fiddle and you'll see.
This is the FIDDLE
jQuery(".subdiv").hide();
jQuery(".mydiv").hover(function(){
jQuery(this).find(".subdiv").stop().delay(800).slideDown("slow");
}, function(){
jQuery(this).find(".subdiv").stop().delay(200).slideUp("slow");
});
So something like this:
http://jsfiddle.net/GzxJf/12/
jQuery(".subdiv").hide();
jQuery(".mydiv").hover(function(){
jQuery(".subdiv").each(function() {
if(jQuery(this).attr('display') !== "none") {
jQuery(this).stop(true).slideUp("slow");
}
});
jQuery(this).find(".subdiv").slideDown("slow");
}, function(){
jQuery(this).find(".subdiv").slideUp("slow");
});
I am trying to make a div slide down when the mouse moves over another div just above it. Basically the div above it is just the trigger that makes the div slide down. Mouseover of .trigger makes .slidedown expand, and mouseout of .slidedown makes itself slide back up. Here's the code i have so far:
$(document).ready(function() {
$('.slidedown').hide();
//When mouse rolls over
$('.trigger').mouseover(function(){
$('.slidedown').stop().animate({
height: ['toggle', 'swing'],
}, 600, function() {
// Animation complete.
});
});
//When mouse is removed
$('.slidedown').mouseout(function(){
$('.slidedown').stop().animate({
height:'0px'
}, 600, function() {
// Animation complete.
});
});
});
This works, but there are just two teaks i need help with. Firstly, after mouseout and the .slidedown div slides up and disappears, if i then mouse over the .trigger div again, nothing happens. It should make the .slidedown move down again. I need it to every time keep working. I tried removing the .stop() but it still doesn't work.
Also can i make it also slide back up if the mouse moves out of .trigger but only if it isn't moving out of .trigger into .slidedown? This is so incase the user doesn't move the mouse into .slidedown, it would remain forever which isn't good. Or just have a time limit that it can remain expanded if the mouse doesn't move over .slidedown.
Second, is there a way to make a delay of around 1 second between mouseout and the div sliding back up? Thanks for your help!
You might try using the jQuery hover event. For the delay, you can put the closing animation in setTimeout:
$(document).ready( function(){
$('.trigger').hover( function(){ // enter animation
$('.slidedown').stop(true,true).animate({
height: ['toggle', 'swing'],
}, 600, function() { /* animation done */ });
}, function(){ // leave animation
setTimeout( function(){
$('.slidedown').stop(true,true).animate({
height: '0px',
}, 600, function() { /* animation done */ });
}, 1000 );
});
});
You might also look into the hoverIntent plug-in for more nuanced control over the mouseenter/mouseleave behavior, including timing.
I think you'll find that setting a numerical height in $('.trigger').mouseover() may help the animation be repeatable. FYI, you can set an integer number for something like height or width in jQuery and it will automatically set the unit to px for you.
As Ken pointed out, setTimeout is useful for a delay in code, but keep it in your $('.slidedown').mouseout() event or the slideown div will hide after you mouseout of the trigger div instead of when you leave the slidedown div as you specified.