I'm trying to hover over over the img then use Greensock Tweenmax on hover to control the speed and opacity of the text within the span. The opacity will change on mouseover and mouseout.
The problem is that I'm having to repeat the same exact same effect on several div's and it's becoming repetitive. Each one will be unique to the image being hovered. I don't want them all to appear at the same time when I hover over one div. I could give them all the same class then use .hover
but then that would activate all of them instead of individually.
They are only to appear respective to that particular div being hovered. It works just fine, but I would like to simplify it since I will be doing this to about 20 different div
s.
I need some help simplifying the code below. It works just fine, but maybe there is an easier way.
<a href="#click-for-modal" data-toggle="modal">
<div class="test">
<img src="img/image.png"><span>Here is some text</span>
</div>
</a>
<a href="#click-for-another-modal" data-toggle="modal">
<div class="testx">
<img src="img/image.png"><span>Here is some other text</span>
</div>
</a>
/* tweenmax hover animations */
$('.test img').hover(
function(){
/*mouseover function*/
TweenLite.to(".test span", 1.5, {opacity:1});
},
function(){
/*mouseout function*/
TweenLite.to(".test span", 1.5, {opacity:0});
});
$('.testx img').hover(
function(){
/*mouseover function*/
TweenLite.to(".testx span", 1.5, {opacity:1});
},
function(){
/*mouseout function*/
TweenLite.to(".testx span", 1.5, {opacity:0});
});
$('.testxy img').hover(
function(){
/*mouseover function*/
TweenLite.to(".testxy span", 1.5, {opacity:1});
},
function(){
/*mouseout function*/
TweenLite.to(".testxy span", 1.5, {opacity:0});
});
$('.testxyz img').hover(
function(){
/*mouseover function*/
TweenLite.to(".testxyz span", 1.5, {opacity:1});
},
function(){
/*mouseout function*/
TweenLite.to(".testxyz span", 1.5, {opacity:0});
});
-
1\$\begingroup\$ Welcome to Code Review! To make life easier for reviewers, please add sufficient context to your question. The more you tell us about what your code does and what the purpose of doing that is, the easier it will be for reviewers to help you. See also this meta question \$\endgroup\$Simon Forsberg– Simon Forsberg2014年07月17日 22:04:58 +00:00Commented Jul 17, 2014 at 22:04
-
\$\begingroup\$ Just use closures. \$\endgroup\$rds– rds2014年07月17日 22:10:19 +00:00Commented Jul 17, 2014 at 22:10
-
\$\begingroup\$ Thanks @SimonAndréForsberg I'll review the link and update the answer. \$\endgroup\$user1222186– user12221862014年07月17日 22:20:49 +00:00Commented Jul 17, 2014 at 22:20
2 Answers 2
The recommended way is to use event delegation
:
$('.test, .testx, .testxy, .testxyz')
.on('mouseover', 'img', function (e) {
TweenLite.to($(e.delegateTarget).find('span'), 1.5, {opacity:1});
}).on('mouseout', 'img', function (e) {
TweenLite.to($(e.delegateTarget).find('span'), 1.5, {opacity:0});
});
This will add the mouseover
and mouseout
events to all img
tags within your parent elements. When the event is fired e.delegateTarget
will be the parent element, so we can easily search for the span
.
-
\$\begingroup\$ I believe this would assume that the
span
s are inside theimg
. \$\endgroup\$RoToRa– RoToRa2014年07月18日 10:13:13 +00:00Commented Jul 18, 2014 at 10:13 -
1\$\begingroup\$ @RoToRa Whoops, you are right. It should be using the
delegateTarget
. \$\endgroup\$Jivings– Jivings2014年07月18日 10:14:26 +00:00Commented Jul 18, 2014 at 10:14 -
\$\begingroup\$ This won't handle the cases where there are 2+
.testx
and the user clicks one \$\endgroup\$megawac– megawac2014年07月18日 14:10:28 +00:00Commented Jul 18, 2014 at 14:10 -
\$\begingroup\$ @megawac The original code posted also doesn't cater for that. \$\endgroup\$Jivings– Jivings2014年07月18日 14:34:10 +00:00Commented Jul 18, 2014 at 14:34
-
\$\begingroup\$ @Jivings Thank you for your answer, let me update my question as per Simons request to further clarify my question \$\endgroup\$user1222186– user12221862014年07月18日 15:36:46 +00:00Commented Jul 18, 2014 at 15:36
Considering you are assigning the same functionality to all of those elements, you should assign them all the same class, eg:
<div class="test my-hover">...</div>
<div class="testx my-hover">...</div>
<div class="testxy my-hover">...</div>
<!-- etc. -->
and then use $(".my-hover")
.
(BTW, my-hover
is just an example, and is probably a bad choice for a class name. Use a class name that expresses why they get that hover effect, not that they get a hover effect.)
-
\$\begingroup\$ Thanks for you input, but this solution wouldn't work because then the hover would trigger all the events at the same time. As opposed to individually. \$\endgroup\$user1222186– user12221862014年07月18日 15:34:41 +00:00Commented Jul 18, 2014 at 15:34
-
\$\begingroup\$ @user1222186 No, it wouldn't. The class name just defines which elements the event handlers apply to. The use of
this
/event.target
(or in the case of Jivings solutionevent.delegateTarget
) inside the handler decides which elements the effects are applied to. \$\endgroup\$RoToRa– RoToRa2014年07月19日 16:35:14 +00:00Commented Jul 19, 2014 at 16:35