June 28, 2012

Why can't I animate a cloned element?

Question by markzzz

This is my code :

var newElement=$('.oggetto').eq(0).clone();
newElement.animate({ 'top': '2000px'}, 5000);

<div id="container">
    <div class="oggetto" style="left:0px;">&nbsp;</div>
    <div class="oggetto" style="left:50px;">&nbsp;</div>
</div> 

but seems that “.oggetto” won’t to move after the clone().

In fact, if I just write :

$('.oggetto').eq(0).animate({ 'top': '2000px'}, 5000);

it works as well. Where am I wrong?

Answer by Starx

Because, first the cloned element have to inserted into the DOM and then should be animated.

var newElement=$('.oggetto').eq(0).clone();
$("#container").append(newElement); //add the element 

//Now animate
newElement.animate({ 'top': '2000px'}, 5000);

Demo

May 3, 2012

CSS3 Animating position

Question by George

Consider CSS3 animation with ship moving above blue div. For some reason the ship isn’t moving. The HTML is as follows:

<div id="wrapper">
  <div id="sea">
    <img src="ship.png" alt="ship" width="128" height="128"/>
  </div>
</div>

In order to make CSS3 animation I use the following:

#wrapper { position:relative;top:50px;width:700px;height:320px;
          margin:0 auto;background:white;border-radius:10px;}
#sea { position:relative;background:#2875DE;width:700px;height:170px;
       border-radius:10px;top:190px; }
#sea img { 
  position:relative;left:480px;top:-20px;
  animation:myship 10s;
  -moz-animation:myship 10s; /* Firefox */
  -webkit-animation:myship 10s; /* Safari and Chrome */
  @keyframes myship {
    from {left: 480px;} 
    to{left:20px;} 
   }
   @-moz-keyframes myship {
     from {left: 480px;} 
     to {left:20px;} 
   }
   @-webkit-keyframes myship {
     from {left: 480px;} 
     to{left:20px;} 
   }
}

The ship image isn’t moving. Any help is greatly appreciated.

Answer by Kirean

you have to declare your keyframe outside the css selector, as well as animate an absolutely positioned element.

http://jsfiddle.net/aNvSf/

your modified css looks like this:

#wrapper{position:relative;
    top:50px;
    width:700px;
    height:320px;
            margin:0 auto;background:white;
    border-radius:10px;
}
#sea{position:relative;
    background:#2875DE;
    width:700px;height:170px;border-radius:10px;top:190px;
}
#sea img{
    position:absolute;
    left:480px;
    top:-20px;
    animation:myship 10s;
            -moz-animation:myship 10s; /* Firefox */
            -webkit-animation:myship 10s; /* Safari and Chrome */

}

@keyframes myship
                {
                from {left: 480px;} 
                to{left:20px;} 
                }
                @-moz-keyframes myship
                {
                from {left: 480px;} 
                to{left:20px;} 
                }
                @-webkit-keyframes myship
                {
                from {left: 480px;} 
                to{left:20px;} 
                }​

Answer by Starx

To animate with left, top, bottom or right, you either have to have a absolutely positioned or floated element. SO, Change the position to absolute.

Also, there was as unclosed braces } before you started to declare the keyframes.

#sea img { 
    position:absolute;
    /* ... */
}

Braces Error:

    #sea img{
         position:absolute; /* absolute */
         left:480px;top:-20px;
         animation:myship 10s;
        -moz-animation:myship 10s; /* Firefox */
        -webkit-animation:myship 10s; /* Safari and Chrome */
    } 
 /* ^ You have to close the braces here, before declaring the keyframes.

Here is a working demo

March 31, 2012

jQuery sliding animation not working

Question by Jake Zeitz

I have three divs stacked on each other but offset so that a part of each div is visible. When one of the bottom divs is clicked I want the top div to animate out and back into the stack at the bottom, then the div that is clicked will appear at the top. So far I only have the code for when the middle div is clicked, but I cannot get it to work properly. What am I doing wrong? (I also realize that the code I wrote is probably terrible, this is the first jQuery code I have written.)

The css is very very simple:

    .first {
        z-index: 3;
    }
    .second {
        z-index: 2;
    }
    .third {
        z-index: 1;
    }

The basic html is this:

    <div class="first"></div>
    <div class="second"></div>
    <div class="third"></div>

Here is my code:

    $("div.second").click(function () {
        $("div.first").animate({
            left: "-=200px"},
            {duration: "fast",
            complete: function () {
                $("div.first").removeClass("first").addClass("third").animate({left: "+=350px", top: "+=60px"}, "fast");
            }
        });
        $("div.second").animate({
            left: "-=24px", top: "-=30px"},
            {duration: "fast",
            complete: function () {
                $("div.second").removeClass("second").addClass("first");
            }
        });
        $("div.third").animate({
            left: "-=24px", top: "-=30px"},
            {duration: "fast",
            complete: function () {
                $("div.third").removeClass("third").addClass("second");
            }
        });
    });

I can get the div.first to move to the side and back. But now I can’t get the classes to stay changed. What keeps happening is the div.second will remove it’s class and add .first in the animation, but when the animation is complete, it acts like it still has a class of .second.

Answer by Starx

That coding style is very inefficient.

Use something like this, It applies to every div

$("div").click(function() {
   var first = $(".first");
   var fleft = first.css("left");
   var ftop = first.css("top");           

   var $this = $(this);
   var tLeft = $this.css('left');
   var tTop = $this.css('top');
   var tClass = $this.attr("class");

   first.animate({
      left: tLeft,
      top: tTop
   }).attr("class", tClass);

   $this.animate({
       top: ftop,
       left: fleft
   }).attr("class", "first");        

});

Demo

March 23, 2012

Making divs slide down (not open) when a div above is opened

Question by Shaun Woolf

So here’s my question–and I’m not too well versed in programming just yet, so please be patient:

I would like to have a list of objects on my page, with each functioning as a toggle to open a div. That part I have down! What I can’t figure out is how to make it so that divs below the opened object slide below the newly opened div. Currently they just sit there on top the content within the opened div. Thanks!

Answer by Starx

Its called an Accordion Effect. Check out the jQuery UI Accordion Effect here

Here it’s a very simple version of the accordion effect, I just created it using jQuery.

April 19, 2011

Best way to do a horizontal scrolling pane in jQuery?

Question by CaptSaltyJack

I came up with the solution below. It works great, but I’m curious to know if there’s a more efficient way of doing it. Thanks!

HTML:

<div id="magic-pane" style="width: 300px; height: 400px; background: #eee; overflow: hidden">
    <div id="scroller" style="width: 600px; height: 100%; left: 0px; position: relative">
        <div id="pane1" style="width: 300px; height: 100%; background: #efe; float: left">
            <span id="pane1-clicker">Whee, click me!</span>
        </div>
        <div id="pane2" style="width: 300px; height: 100%; background: #fee; float: left">
            <span id="pane2-clicker">Whoosh! Click me!</span>
        </div>
    </div>
</div>

Script:

$(document).ready(function() {
    $('#pane1-clicker').click(function() {
        $('#scroller').animate({ left: '-300px' }, 500);
    });
    $('#pane2-clicker').click(function() {
        $('#scroller').animate({ left: '0' }, 500);
    });
});

So basically, the magic-pane is a small viewport that’s 300px wide. Inside it is a scroller that’s twice as wide and contains two divs side-by-side. Pretty simple, but again, just wondering if there’s a more efficient way of coding this.

Demo

Answer by Starx

When the number are minimum, you do not need to worry about anything. Like in you case, 2 is pretty manageable. Note: that you are writing separate onClick function for all the pane, which will create problem.

But as the number grow, lets say 50, then you will have to write different onClick functions of $('#pane1-clicker') …. $("#pane50-clicker), which is highly inefficient. You should modify your script, to support any number of panes, without writing extra codes.

  • Also, extend the function, so that it can be used as plugin.
  • It would be better if the plugin could match a particular selector and assign the related positions like left:300px
...

Please fill the form - I will response as fast as I can!