I ran into a problem that comes with jquery animation. I am having the user be able to click a button and based off that button direction they click it slides all the list(li) elements to that opposing direction. The problem comes in that I have it set to wrap-around inside a div, so when a list element ends on one side it getting the animation to slide off the div sight but getting the css style attribute set to the opposite side off the screen so it can be ready to scroll down for the next button click. But when the user clicks the button multiple times it queues up all the elements on top of each other because the animation hasn't finished. So then I attached the stop() animation to the elements, but then the second problem comes in that when the user clicks the button fast multiple times it, The elements never get to wrap around, they will just stay dissappeared until you click the button slowly or if you start pressing the button faster after some of them are dissappeared then start back slow then only the ones that were visible when slow are still wrapping in the div until the next wrap around:
quick example:
function Rotate(){
$("li.headline").each(function(){
var left= $(this).css("left");
left=left-100;
if(left>99){
$(this).stop().animation({left:left}, 'slow', function(){
$(this).css("left",left);});
}else{
$(this).stop().animation({left:left}, 'slow', function(){
$(this).css("left",max);}); //max is the max "left" calculated from all list items
}
});
}
$("button.next").click(function(){
Rotate();
});
could someone help me
html/css example
#scroll{
position:relative;
overflow:hidden;
width:300px
}
.headline{
position:absolute;
float:left
}
<div id="scroll">
<ul>
<li class="headline"><a>First</a>
<li class="headline"><a>Second</a>
<li class="headline"><a>Third</a>
<li class="headline"><a>Fourth</a>
<li class="headline"><a>Fifth</a>
</ul>
<div>
Have you tried this?
$(this).stop(true, true) // remainder of your code
It will clear the animation queue for the matched element and complete the animation. The default for both is false, which means any queued animations are still run (only the current animation is stopped) and the current animation is not completed.
http://api.jquery.com/stop/
I corrected the problem by adding a extra check in the if condition as so
var index;//this is the current li at the head that is incremented by the button click
//and updated outside this function
$("li.headline").each(function(i){ //added i to get the current index the each is on
if(left>99&&index==i){
$(this).stop(true, false).animation({left:left}, 'slow', function(){ //also made the first true
//and second false, so the animation wouldn't rush across the screen but true so it wouldn't
// build up the queue
$(this).css("left",left);});
}else{
$(this).stop(true, false).animation({left:left}, 'slow', function(){
$(this).css("left",max);}); //max is the max "left" calculated from all list items
}
Related
http://jsfiddle.net/czt0mycw/
<body>
<div id="hold_divs">hold divs
<div id="div1">div1</div>
<div id="div2">div2</div>
<div id="div3">div3</div>
<div id="div4">div4</div>
</div>
</body>
This is my first time building a jquery slider and it is exhibiting the strangest behavior. When the page first loads, it slides(automatically) the contents(my 4 divs stacked on top of one another) to the right successfully. But after a full slide show is completed, the slider no longer displays div1(the div with the red background). Instead, it skips(I believe that's whats happening) and shows the parent div("hold_divs").
When I was debugging, I altered the code to slide in only 2 divs, and a similar error occurred. This time, the two divs slid correctly only once (when the page is first loaded). After the first slide show completed successfully, it displayed the first of the 2 divs, but the 2nd div in the was not displayed; the 3rd div in the array was. O.o
http://jsfiddle.net/czt0mycw/1/
You need to reset the divs on the next iteration of the interval. Change:
setInterval(function()
{
var divs=[$("#div4"),$("#div3"),$("#div2"),$("#div1")];
var width=divs[x].width();
divs[x].stop().animate({right:"100%"},"slow");
x+=1;
if(x==4)
{
$("#div4,#div3,#div2,#div1").css("right",0);
x=0;
}
},3000);
to
setInterval(function()
{
if(x==4)
{
$("#div4,#div3,#div2,#div1").css("right",0);
x=0;
return;
}
var divs=[$("#div4"),$("#div3"),$("#div2"),$("#div1")];
var width=divs[x].width();
divs[x].stop().animate({right:"100%"},"slow");
x+=1;
},3000);
What's happening is that you're resetting the divs immediately after you start the animation for the 4th div. Instead, you want to reset the divs immediately before you start the animation again for the 1st div.
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 have a <div> on my web page that I would like to have an opacity of 1 while you're hovering over it, but when the mouse is not hovering over it I would like it to fade to an opacity of 0.3. My problem is that currently when I hover over the <div> it starts fading in and out several times (rather than just once). I'm not sure if this is why, but I suspect it's because it detects the mouse rolling over the multiple <div>s that are within the one that I set to fade out.
Here is a very simplified segment of my web page to illustrate what I have so far:
<div id="div1">
<div id="div2" onmouseover="fadeElementTo('div1', 500, 1)" onmouseout="fadeElementTo('div1', 500, 0.3)">
<div id="div3">
<div id="div4">
</div>
</div>
<button id="myButton" onclick="doACoolAnimation()" ></button>
</div>
</div>
My fadeElementTo() function is pretty simple:
function fadeElementTo(eid, speed, opacity, callback) {
$("#" + eid).fadeTo(speed, opacity, callback);
}
In case it's relevant, I also have a button that animates the same div by simply moving it left or right when the button is clicked.
function doACoolAnimation() {
var hiddenState = GLOBAL_VAR.hiddenState;
// If the <div> is already hidden, make it visible
if (hiddenState == null || hiddenState == 1) {
GLOBAL_VAR.hiddenState = 0;
$("#div1").animate({
left: "0px"
}, 1500);
}
// Otherwise, hide it
else {
GLOBAL_VAR.hiddenState = 1;
$("#div1").animate({
left: "-800px"
}, 1500);
}
}
Any ideas what might be causing my bug? And better yet, what can I do to fix it?
Try onmouseenter instead of onmouseover and use jQuery to attach/bind those events rather than the attributes so it works the same across all browsers.
$('#outer').mouseenter(function() {
$('#log').append('<div>Handler for .mouseenter() called.</div>');
});
see here
Use mouseenter event to stop event bubbling, and stop method to make sure you clear unfinished animations on that element.
$('#div2').mouseenter(function(){
$('#div1').stop().fadeTo(500,1);
});
It detects the events multiple times. For example, if you want to change the size, going on and off fast changes the size even when the mouse is not on the div. The code needs to exit the program when the mouse is not on the div. To do that, you might include the code in something that kills the code when the mouse is not on top of the div so that the queued fades/animations do not run.
Edit:
Try looking at the JQuery documentation to see if there is anything that you can use.
You might able to use these:
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.