How to avoid double jQuery object lookups
I'm working on a jQuery hover code snippet that will add markup on hover and then work with the class. Here is the JS.
$('.port-item').hover(function(){
var $this = $(this);
var name = $($this.find("img")).attr('title');
$this.append('<div class="port-item-cover"><h3>' + name + '</h3><div>');
$($this.children(".port-item-cover")).fadeIn();
}, function(){
$($(this).children(".port-item-cover")).fadeOut();
});
The HTML markup is pretty simple:
<div class="port-item">
<a href="/portfolio/#/<?=$p['shortname']?>">
<img src="images/portfolio/p_&开发者_运维问答lt;?=$p['shortname']?>0.jpg" title="<?=$p['title']?>">
</a>
</div>
Two Questions: the main one is, how do I avoid the double lookups in jquery $($(this).children("#element"))
to look up the child elements inside the current scope? It's pretty ugly in the second function, is there a better way?
The second question is what is the best way to check if this has been previously hovered over before and if the markup is there so I do not add it on subsequent hovers.
The first one is easy. You dont need the outer $
call. .find()
will already return a jQuery object. Just write it like this
$(this).children("#element")
As for detecting if it has been hovered over previously, you would have to set a flag somewhere. That might look like this:
var hoveredOver = false;
$('.port-item').hover(function(){
hoveredOver = true;
//continue event handler
}
You may need to get fancy with that depending on your specific circumstance. Perhaps setting the flag using .data()
would be better if you are hovering over a lot of things.
$('.port-item').hover(function(){
$(this).data('hoveredOver', true);
//continue event handler
}
EDIT Missed a question there. Third answer: to tell if the DOM object (markup) is there already you search for it and check the length like so:
if($(this).find('#port-item-cover').length>0)
{
//element exists
}
else
{
//element does not exist, add it
}
All jQuery traversal methods already return jQuery objects; you never need to write
$($this.children())
.No.
a. Mouseleave should never fire without mouseenter.
b. If there aren't any matching elements, nothing will happen; you won't get an error.
However, you need to remove the element after the animation finishes; right now, you're adding a separate element on every hover.
Note that you simplify your mouseenter
to
$('<div class="port-item-cover"><h3>' + name + '</h3><div>')
.appendTo(this)
.fadeIn();
For the first question, use this instead:
$(this).children("#element")
精彩评论