Bastiaan
Bastiaan

Reputation: 99

Jquery hovering multiple elements

I am trying to write a little script that does the following;

I have three circles on a row. If I hover one all three have to slide to the left on top of each-other and the one I pointed on top of the stack. In the example the blue one.

Afterwards all three circles have to slide back to there original position.

RGB example

This is what I got. Yes it is working but...

  1. it is not working properly.
  2. I am wondering if there is a better approach

$('.circle').hover(
    function(e){
        $(this).css({'z-index' : '99'});
        $('.circle').animate({'left' : '0px'},1000);
    },
    function(e){
        $(this).css({'z-index' : '0'});
        $('.circle-red').animate({'left' : '0px'},1000);
        $('.circle-blue').animate({'left' : '200px'},1000);
        $('.circle-green').animate({'left' : '400px'},1000);
    }
);

Upvotes: 2

Views: 222

Answers (2)

Alain Jacomet Forte
Alain Jacomet Forte

Reputation: 4685

This is an implementation using mostly CSS transitions:

HTML

<div class="circles">
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
</div>

CSS

// Just basic looks. Notice the position: absolute; and the z-index defaulting to 0.
.circles {
  width: 300px;
  position: relative;  
}
.circle {
  position:absolute;
  display:inline-block; 
  z-index:0;
  border-radius: 100px;
  width: 100px;
  height: 100px;
  border: 2px solid #222;  
  transition: 500ms ease-in;
}
// Positioning for each one using the CSS3 nth-of-type pseudoselector.
.circle:nth-of-type(1) { background:red; left: 0%}
.circle:nth-of-type(2) { background:blue; left: 40%}
.circle:nth-of-type(3) { background:yellow; left: 80%}

// Matched items. jQuery will set all items' data-active attribute to the current active element.
.circle:nth-of-type(1)[data-active="0"],
.circle:nth-of-type(2)[data-active="1"],
.circle:nth-of-type(3)[data-active="2"] { z-index: 2;}

// We'll send all the circles to the same position depending on which is active
.circle[data-active="0"] { left: 0%; }
.circle[data-active="1"] { left: 40%; }
.circle[data-active="2"] { left: 80%; }

JS

$('.circle').on('mouseenter',function() {
  var index = $('.circle').index( $(this) );
  $('.circle').attr('data-active', index);
});

$('.circle').on('mouseleave',function() {
  $('.circle').attr('data-active', '');
});

CODEPEN HERE

What is going on here?

jQuery sets [data-active] to the current index (circle 1 is 0, circle 2 is 1, circle 3 is 2 - Note the difference in the numbers) using the index() method.

We use the :nth-of-type CSS3 pseudoselector to match against the data-active attribute. If circle 1 has [data-active=0], then we'll give it a z-index of 2 so it can be on top.

All items with data-active=0 will move to the same position of circle 1: 10% left. All items with data-active=1 will move to left:40% and so on.

Note: for extra fun, add transform: rotateY(180deg); after the z-index:2; property.

The movement is made with the transition: 500ms ease-in; property, and automatically sequences the animation when the left property changes.

This could be more concise but the way the code is structure, I think it's easier to understand.

Upvotes: 1

csteel
csteel

Reputation: 393

The issue is that the mouseleave function is being fired when the circle moves away from the mouse. It would make more sense to have everything move to the circle that you hovered over. That way it could snap back to normal when you leave the circle.

Anyways, my approach was to create the container around the objects that is used to trigger them snapping back to place. Check out this fiddle: http://jsfiddle.net/cz366/2/

One thing to keep in mind is always use .stop() before .animate(). This will prevent the animation from queuing up on you. Stop will clear/kill the animation queue on the element.

Upvotes: 1

Related Questions