I find my self doing this but not sure if this is the best way. Here an example.
<ul id="menubar">
<li><a class="menu_item">File</a>
<ul>
<li><a id="menu_file_new">New</a></li>
<li><a id="menu_file_open">Open</a></li>
</ul>
</li>
<li><a class="menu_item">Run</a>
<ul>
<li><a id="menu_run_preview">Preview</a></li>
<li><a id="menu_run_compile">Compile</a></li>
</ul>
</li>
</ul>
JQuery
$('.menu_item').hover(function(){
$(this).find('ul').show();
});
Just wondering is this the best way, find seems a bit overkill?
EDIT: I can't use css because of this: Fails in Opera/IE when an item is clicked/hover it fails in those two browsers. http://jsfiddle.net/cJsn2/1/ this is because of html standard.
5 Answers 5
You can do this with CSS only
.menu_item ul { display: none; }
.menu_item:hover ul {display: block; }
as for the JavaScript, it's fine, you can use $.children instead of $.find to traverse less nodes
4 Comments
ul in an a-tag. (nor should it)This would be a simple hover script:
// I'm purposely using `toggleClass`, instead of show/hide, to
// have more flexibility with styling
$('.menu_item').each(function () {
var $li = $(this).closest('li');
$(this).hover(function () {
$li.toggleClass('hover');
});
});
with the following css:
ul ul {
display: none;
}
li.hover > ul {
display: block;
}
5 Comments
toggleClass) is essentially the same. I think the added complexity of my example comes from the fact, that I like to cache my selectors. E.g. only executing $(this).closest('li'); once for each .menu_item instead of constantly evaluting it inside the hover-callback.li once per .menu_item. Without caching it, it would look every time a mouseover/mouseout happens.Try doing this with just css
the catch is that you're going to apply the "hover" on the li and not in the a
#menubar li ul{
display:none;
}
#menubar li:hover > ul{
display:block;
}
1 Comment
What you want to use is closest. It travels up the DOM-tree to find the first parent element matching the selector: (削除)
$('.menu_item').hover(function(){
$(this).closest('ul').show();
});
(削除ここまで)
$(".menu_item").hover(function() {
$(this).next().show();
});
Comments
You can use CSS (this is under the assumption that the ul element is contained within the .menu_item element):
.menu_item:hover > ul {
display: block;
}
Demo: http://jsfiddle.net/maniator/cJsn2/
Using the following HTML:
<ul id="menubar">
<li class="menu_item"><a>File</a>
<ul>
<li><a id="menu_file_new">New</a></li>
<li><a id="menu_file_open">Open</a></li>
</ul>
</li>
<li class="menu_item"><a>Run</a>
<ul>
<li><a id="menu_run_preview">Preview</a></li>
<li><a id="menu_run_compile">Compile</a></li>
</ul>
</li>
</ul>
$('ul', this).show()$(this).find('>ul').show();in case you want to do multiple levels in the future. Also remember that not everyone uses a mouse. Pick a menu library from the net that does all of the hard work for you.$('#menubar, #menubar ul).attr('display','block');