I'm working on a jQuery slider with an active class .slider-active
when mouseEnter
a figure.
In this way, I want to animate my .slider-imgcontainer
and my figcaption in a cool effet:
When the .slideractive
change, the previous object have to reduce the width of .slider-imgcontainer
to 250px and after the width
and padding
of the figcaption
to 0. When I reduce the width
of figcaption
, the text was too high, so I just use .hide
and .show
to correct this.
Then the slider begin to work, but... when the mouse roll over mutliple figure, all of them is animated. I've tried to correct this but I cannot find any solutions (with .clearQueue()
et .stop()
).
Result: current slider
Main animation code:
$(document).ready(function(){
var GLOBAL = {
window:$(window),
slider:$('.slider-work'),
container:$('#container'),
figure:$("figure")
}
/********* SLIDER MAIN *************/
// INIT LARGEUR ---
GLOBAL.slider.width($(".slider-work img").size() * 250 + 900);
// save width of figcaption in attr to animate them after (no auto animate)
GLOBAL.slider.find("figcaption").each(function(i) {
var t = $(this);
if(!t.parent().hasClass("slider-active"))
t.hide();
t.attr("largeur", t.width());
});
// hover
GLOBAL.slider.children("figure").mouseenter( function () {
var oldActive = $(".slider-active");
var thiss = $(this);
oldActive.removeClass("slider-active");
thiss.addClass("slider-active");
oldActive.find("figcaption").animate({
width: 0,
padding: 0
}, 220, 'linear', function() {
oldActive.find(".slider-imgcontainer").animate({
width : 250
}, 400, 'linear', function() {
// Animation de l'ancien active fini , alors :
//$(".slider-imgcontainer").removeAttr("style");
thiss.removeAttr("style").children(".slider-imgcontainer").animate({
width : 400
}, 400, 'linear', function(){
var largeurFigcaption = thiss.find("figcaption").show().attr("largeur");
thiss.find("figcaption").animate({
width : largeurFigcaption,
padding : " 0 20px 20px 20px"
}, 220, 'linear', function(){
});
});
});
});
});
// END MouseEnter
//End ready
});
And my code for debugging the slider
GLOBAL.slider.children("figure").mouseout( function () {
var thiss = $(this);
//$("#title span").append(" toto");
var myChildrenBehave = GLOBAL.slider.filter(function() {
var filtered = $(this).children().is(":animated");
return filtered;
});
myChildrenBehave.clearQueue().stop();
});
I accept all idee :)
There are multiple ways to deal with this, but the one I prefer is after the animation of the initial mouseover completes you check to see if the mouse is still over that item. If it is not you close it back down.
jQuery doesn't have a built in check for mouse still over an object that I am aware of, but I wrote one of my own for the situation that is pretty simple.
var mouse = {
mouseX: null,
mouseY: null,
mouseInWindow: true,
init: function() {
$(document).bind('mousemove', function(event) {
mouse.mouseX = event.pageX;
mouse.mouseY = event.pageY;
mouse.mouseInWindow = true;
});
$(document).bind("mouseleave", function(event) {
mouse.mouseInWindow = false;
});
$(document).bind("mouseenter", function(event) {
mouse.mouseInWindow = true;
});
},
isOver: function($element) {
$elementPosition = $($element).offset();
$elementWidth = $($element).width();
$elementHeight = $($element).height();
$returnValue = true;
if (mouse.mouseX !== null) {
if (mouse.mouseX < $elementPosition.left) { $returnValue = false; }
if (mouse.mouseY < $elementPosition.top) { $returnValue = false; }
if (mouse.mouseX > $elementPosition.left + $elementWidth) { $returnValue = false; }
if (mouse.mouseY > $elementPosition.top + $elementHeight) { $returnValue = false; }
if (!mouse.mouseInWindow) { $returnValue = false; }
}
return $returnValue;
}
}
You will need to run mouse.init() before your other code, but then you can use mouse.isOver($(yourSlideActivator));