Making smarter jQuery code
I was wondering if anyone has any idea on how I could rewrite this simple jquery code to be more efficient. It's of course working fine now but I imagine adding say 10 more items would make the code really big. I thought maybe I could add the classes to arrays and use some kind of loop? Not sure if that's the right appro开发者_运维百科ach though.
Here it is on jsfiddle: http://jsfiddle.net/QVS9X/42/
and here's a sample of it: JS:
$(".image1").mouseout(function() {
$(".default").show();
$(".cat1").hide();
}).mouseover(function() {
$(".default").hide();
$(".cat1").show();
});
$(".image2").mouseout(function() {
$(".default").show();
$(".cat2").hide();
}).mouseover(function() {
$(".default").hide();
$(".cat2").show();
});
HTML:
<div class="image1 image">
<p>Hover for cat 1</p>
</div>
<div class="image2 image">
<p>Hover for cat 2</p>
</div>
<div class="image3 image">
<p>Hover for cat 3</p>
</div>
<div class="default">
<p>Default Text</p>
</div>
<div id="cats">
<p class="cat1">Category 1 text</p>
<p class="cat2">Category 2 text</p>
<p class="cat3">Category 3 text</p>
</div>
If you can put a class of image on the divs that current have image1, image2 etc, then you can do this:
$(".image").hover(function() {
$(".default").toggle();
$("#cats p").eq($(this).index()).toggle();
});
This assumes that the image divs will be in the same order as the p tags inside #cats.
http://jsfiddle.net/QVS9X/44/
Example using data attributes:
JS:
$(".image").hover(function() {
$(".default").toggle();
$($(this).data('id')).toggle()
});
HTML:
<div class="image" data-id="#cat1">
<p>Hover for cat 1</p>
</div>
<div id="cats">
<p id="cat1">Category 1 text</p>
</div>
http://jsfiddle.net/QVS9X/55/
var myDefault = $(".default");
var myCat1 = $(".cat1");
var myCat2 = $(".cat2");
and then
$(".image1").mouseout(function() {
myDefault.show();
myCat1.hide();
}).mouseover(function() {
myDefault .hide();
myCat1 .show();
});
$(".image2").mouseout(function() {
myDefault.show();
myCat2.hide();
}).mouseover(function() {
myDefault.hide();
myCat2.show();
});
will reduce dom traversal, and improve performance
http://jsfiddle.net/QVS9X/45/ for example
<div class="image" data-id="1">
<p>Hover for cat 1</p>
</div>
<div class="image" data-id="2">
<p>Hover for cat 2</p>
</div>
<div class="image" data-id="3">
<p>Hover for cat 3</p>
</div>
<div class="default">
<p>Default Text</p>
</div>
<div id="cats">
<p class="cat1">Category 1 text</p>
<p class="cat2">Category 2 text</p>
<p class="cat3">Category 3 text</p>
</div>
$(document).ready(function() {
$(".image").mouseout(function() {
$(".default").show();
$(".cat"+$(this).data('id')).hide();
}).mouseover(function() {
$(".default").hide();
$(".cat"+$(this).data('id')).show();
});
});
First, I'd wrap the target divs in a parent div if they aren't already contained - like such:
<div id="images">
<div class="image1">
<p>Hover for cat 1</p>
</div>
etc..
</div>
Then you can bind a single event handler to handle all your cases -
$('#images').delegate('div[class^=image]', 'mouseenter mouseleave', function(e) {
$('.default').toggle(e.type === 'mouseleave');
$('#cats p').eq($(this).index()).toggle(e.type !== 'mouseleave');
});
EDIT
You can actually clean it up much further by removing the "image1", "image2", "image3" and just name the class "image". You can also remove the class from the <p>
in #cats
See here for the revised example - http://jsfiddle.net/QVS9X/50/
EDIT 2
Someday, you'll add a cat div dynamically and wonder why the event handler isn't working... then you'll revisit my answer :) And be like... John really had a 100% complete solution. =p
I would say you should make use of two things
- Use of
data-
attributes and jQuery's.data
method - A generic class used to identify all images that you want to have this behaviour
Then your code for all those items becomes:
$(".image").mouseout(function() {
$(".default").show();
$(".cat" + $(this).data('id')).hide();
}).mouseover(function() {
$(".default").hide();
$(".cat" + $(this).data('id')).show();
});
Live example: http://jsfiddle.net/sW8mZ/
Here is my code. http://jsfiddle.net/QVS9X/47/
examples:
$(document).ready(function() {
$('.image').hover(
function(){
$('.default p').html($(this).children('p').html());
},
function(){$('.default p').html('Default Text')});
});
Get rid of all the cat
divs, have 1 div with default text, and then just update this text.
Something like this http://jsfiddle.net/QVS9X/51/
$(document).ready(function() {
var defaultCat = $(".default");
var cat1 = $(".cat1");
var cat2 = $(".cat2");
var cat3 = $(".cat3");
$(".image").mouseout(function() {
cat1.hide();
cat2.hide();
cat3.hide();
defaultCat.show();
});
$(".i1").mouseover(function() {
cat1.show();
defaultCat.hide();
});
$(".i2").mouseover(function() {
cat2.show();
defaultCat.hide();
});
$(".i3").mouseover(function() {
cat3.show();
defaultCat.hide();
});
});
Something along the lines of this should work:
<div class="default">Content</div>
<img class="image" data-ref="1" />
<div class="cat" data-ref="1">Cat 1</div>
<img class="image" data-ref="2" />
<div class="cat" data-ref="2">Cat 2</div>
$('.image').hover(function() {
$('.default, .cat[data-ref='+$(this).data('ref')+']').toggle();
});
http://jsfiddle.net/cugmj/2/
Here's my attempt, moving the category text to the div elements makes things a little easier.
http://jsfiddle.net/HV8vq/
* {
font-size: 20px;
text-align: center;
}
.image-cat-hover {
float: left;
width: 150px;
border: thin solid #CCC;
margin-bottom: 20px;
}
#cats, .default {
width: 450px;
}
<div class="image-cat-hover" data-category="Category 1 text">
<p>Hover for cat 1</p>
</div>
<div class="image-cat-hover" data-category="Category 2 text">
<p>Hover for cat 2</p>
</div>
<div class="image-cat-hover" data-category="Category 3 text">
<p>Hover for cat 3</p>
</div>
<div class="default">
<p id="placeholder">Default Text</p>
</div>
$(document).ready(function() {
var defaultText = $(".default").text();
$(".image-cat-hover").mouseout(function() {
$(".default").text(defaultText);
}).mouseover(function() {
$(".default").text($(this).data("category"));
});
});
Edit
I have to say I've learned alot answering and reading the other answers to this question. Here is an updated response:
http://jsfiddle.net/HV8vq/3/
<div>
<p id="defaultText">Default Text</p>
<p id="placeholder" style="display:none;"></p>
</div>
$(document).ready(function() {
$(".image-cat-hover").hover(function() {
$("#defaultText").toggle();
$("#placeholder").toggle().text($(this).data("category"));
});
});
精彩评论