Reputation: 10571
I currently have this and it works fine but I wanted to have a nicer way to do the same thing, possibly having one single function rather than 2 distinctive ones and save lines. Just some more elegant way than so many lines. The 2 following functions look similar but what they do are slightly different as you can see. Anyone? Thanks
$("#container").on({
"mouseenter": function () {
$(this).stop().animate({
"opacity": "1"
}, 400);
$(this).prev(".caption").stop().fadeTo(0, 0).css('visibility', 'visible').fadeTo('fast', 1);
},
"mouseleave": function () {
$(this).stop().animate({
"opacity": "0.3"
}, 400);
$(this).prev(".caption").stop().fadeTo(0, 1).css('visibility', 'visible').fadeTo('fast', 0);
}
}, "img");
$("#container").on({
"mouseenter": function () {
$(this).stop().animate({
"opacity": "0.3"
}, 400);
},
"mouseleave": function () {
$(this).stop().animate({
"opacity": "1"
}, 400);
}
}, ".gallery a img");
Upvotes: 0
Views: 250
Reputation: 26320
This should help you.
You have different opacities for each element, so it will be a problem if you have to make a if
for each element, so the best way to do it is store it using jQuery.data().
JS
jQuery('#container1').data('opacity', {'enter': 0.1, 'leave': 1});
jQuery('#container2').data('opacity', {'enter': 0, 'leave': 0.1});
jQuery('#container1, #container2').on({
"mouseenter": function() {
var $element = jQuery(this);
$element.stop().animate({
"opacity": $element.data('opacity').enter;
}, 400);
if($element.is('#container1')) {
$element.prev(".caption").stop().fadeTo(0, 0).css('visibility', 'visible').fadeTo('fast', 1);
}
},
"mouseleave": function() {
var $element = jQuery(this);
$element.stop().animate({
"opacity": $element.data('opacity').leave;
}, 400);
if($element.is('#container1')) {
$element.prev(".caption").stop().fadeTo(0, 1).css('visibility', 'visible').fadeTo('fast', 0);
}
}
}, "img");
Upvotes: 1
Reputation: 8319
Some of the other answers are probably more elegant, but if you just want to reduce the number of lines and reduce duplication, you could break it off into a reusable function and call it twice like so:
function imageMouseover(selector, filterSelector, mouseEnterOpacity, mouseLeaveOpacity, fadeCaption) {
$(selector).on({
"mouseenter": function () {
$(this).stop().animate({
"opacity": mouseEnterOpacity
}, 400);
if (fadeCaption) {
$(this).prev(".caption").stop().fadeTo(0, 0).css('visibility', 'visible').fadeTo('fast', 1);
}
},
"mouseleave": function () {
$(this).stop().animate({
"opacity": mouseLeaveOpacity
}, 400);
if (fadeCaption) {
$(this).prev(".caption").stop().fadeTo(0, 1).css('visibility', 'visible').fadeTo('fast', 0);
}
}
}, filterSelector);
}
You can call it twice specifying just the stuff that's changing:
imageMouseover("#container", "img", "1", "0.3", true);
imageMouseover("#container", ".gallery a img", "0.3", "1", false);
Upvotes: 1
Reputation: 15566
not tested: Anyway it is better to keep code in a namespace and just call respective functions from events.
$("#container").on({
"mouseenter": function () {
var galleryImg = $(this).parents('.gallery').length >=1;
$(this).stop().animate({
"opacity": galleryImg? 0.3 : 1
}, 400);
if(!gallerImg)$(this).prev(".caption").stop().fadeTo(0, 0).css('visibility', 'visible').fadeTo('fast', 1);
},
"mouseleave": function () {
var galleryImg = $(this).parents('.gallery').length >=1;
$(this).stop().animate({
"opacity": galleryImg? 1 : 0.3
}, 400);
if(!gallerImg)$(this).prev(".caption").stop().fadeTo(0, 1).css('visibility', 'visible').fadeTo('fast', 0);
}
}, "img");
Upvotes: 1
Reputation: 858
You can try creating some general functions to handle most of these events.
For example:
function someEvent(container, opacity)
{
$(container).stop().animate({
"opacity": opacity
}, 400);
}
$("#container").on({
"mouseenter": someFunction($(this), '0.3');
},
"mouseleave": someFunction($(this), '1');
}
}, ".gallery a img");
Upvotes: 1
Reputation: 16020
You could pull out the common code into two functions, 'brighten' and 'dim'
brighten = function(container,hasCaption) {
container.stop().animate({opacity:1},400);
if(hasCaption) {
container.prev(".caption").stop().fadeTo(0, 0).css('visibility', 'visible').fadeTo('fast', 1);
}
}
dim = function(container,hasCaption) {
container.stop().animate({opacity:0.3},400);
if(hasCaption) {
container.prev(".caption").stop().fadeTo(0, 1).css('visibility', 'visible').fadeTo('fast', 0);
}
}
Then you event binding looks like:
$("#container").on({
"mouseenter": function () { brighten($(this),true); },
"mouseleave": function () { dim($(this),true); }
}, "img");
$("#container").on({
"mouseenter": function () { dim($(this)); },
"mouseleave": function () { brighten($(this)); }
}, ".gallery a img");
Upvotes: 1
Reputation: 9080
You can specify multiple selectors using comma ,
or the add()
function:
$("#container, #container2, #container3")
$("#container, #container2, #container3").on({
"mouseenter": function (e) {
var id = e.target.id;
if (id === 'container') {
// code for #container
}
else if (id === 'container2') {
// code for #container2
}
else if (id === 'container3') {
// code for #container3
}
},
"mouseleave": function (e) {
var id = e.target.id;
if (id === 'container') {
// code for #container
}
else if (id === 'container2') {
// code for #container2
}
else if (id === 'container3') {
// code for #container3
}
}
}, "img");
Upvotes: 3