I had posted this question in Stack Overflow and they told me it would be better served on Code Review.
Is there a more effecient way of changing the mouseout state when a button is clicked? When a button is clicked I want the image in the click event to take precedence over the image in the mouseout event. The following code works but I'm not sure if nesting events is a good practice.
$("#targetBtn").on({
"mouseover" : function() {
$(this).find('img').attr('src', 'images/_hover.png');
},
"mouseout" : function() {
$(this).find('img').attr('src', 'images/_mouseout.png');
},
"click" : function() {
$(this).find('img').attr('src', 'images/_selected.png');
$(this).mouseout(function() {
$(this).find('img').attr('src', 'images/_selected.png');
});
}
});
If anyone could refactor this code and show me a better way of doing this it would be greatly appreciated. Also if someone could explain why nesting events is bad (if indeed it is) I would appreciate that as well.
1 Answer 1
It is bad practice as you add a new handler each time your event is fired.
To better understand this, try this:
$('p')
.on('click', function(e) {
console.log('1');
$(this).on('click', function(e) {
console.log('2');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
click me
</p>
Each time you click "click me", it should log one more "2".
A better way is to refactor your code to use a flag
(function() {
var flag = true;
$('#targetBtn')
.on('mouseover', function(e) {
$(this).find('img').attr('src', 'images/_hover.png');
})
.on('mouseout', function(e) {
if(flag)
$(this).find('img').attr('src', 'images/_mouseout.png');
else
$(this).find('img').attr('src', 'images/_selected.png');
// or
// $(this).find('img').attr('src', (flag ? 'images/_mouseout.png' : 'images/_selected.png'));
})
.on('click', function(e) {
flag = false;
$(this).find('img').attr('src', 'images/_selected.png');
});
})();
See this demonstration to grasp the result:
(function() {
var flag = true;
$('#targetBtn')
.on('mouseover', function(e) {
console.log('src', 'images/_hover.png');
})
.on('mouseout', function(e) {
if (flag)
console.log('src', 'images/_mouseout.png');
else
console.log('src', 'images/_selected.png');
// or
//console.log('src', (flag ? 'images/_mouseout.png' : 'images/_selected.png'));
})
.on('click', function(e) {
flag = false;
console.log('src', 'images/_selected.png');
});
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#" id="targetBtn">btn</a>
-
\$\begingroup\$ Awesome explained. I hope you write more here. \$\endgroup\$michael.zech– michael.zech2016年03月18日 06:54:15 +00:00Commented Mar 18, 2016 at 6:54
-
\$\begingroup\$ I would invert the sense of the
flag
, initialize it tofalse
, and rename it tobuttonHasBeenClicked
. \$\endgroup\$200_success– 200_success2016年03月31日 11:42:13 +00:00Commented Mar 31, 2016 at 11:42
querySelector
? \$\endgroup\$stackoverflow
that its a bad practice. Why is it a bad practice ifJQuery
is just a=
Javascript` library? \$\endgroup\$