Reputation: 4698
I am writing my own jQuery navigation submenu script. When you hover over a link in the horizontal nav
that has a ul
tag, it makes that ul
appear. I have a bit of code that adds an arrow to the links in the horizontal nav
if it has a submenu. My problem is that it also adds the arrows to the links in the submenu. This is not a big deal functionally, but it does look bad.
The odd part is that if I use $(this).find('> a')
it screws up the appearance of the submenu. The submenu appears when I hover over the top-level link, but then disappears right away when the mouse leaves that link. So I can basically see the entire submenu when the mouse is hovered over the top level link. When the mouse leaves the top level link, the submenu disappears and I can't click on the submenu links. What am I doing wrong?
Here is a JSFiddle. Change $(this).find('a')
to $(this).find('> a')
and you'll see what I mean. Thanks for your time!
$(document).ready(function(){
$('nav ul li:has(ul)').each(function(){
var listItem = $(this);
$(this).find('> a').each(function(){
var aTag = $(this);
aTag.append('<img src="{img_url}/caret.png" width="8" height="8">');
aTag.on('mouseover', function(){
listItem.find('ul').each(function(){
$(this).css('display', 'block');
});
})
.on('mouseout', function(){
listItem.find('ul').each(function(){
$(this).css('display', 'none');
});
});
});
});
});
Upvotes: 5
Views: 202
Reputation: 3976
you have to pull out the first a
tag from your loop through .each
$(document).ready(function () {
$('nav ul li:has(ul)').each(function () {
var listItem = $(this);
// first a tag as new var
var aTagFirst = listItem.children('a');
aTagFirst.append('<img src="{img_url}/caret.png" width="8" height="8">');
$(this).find('a').each(function () {
var aTag = $(this);
aTag.on('mouseover', function () {
listItem.find('ul').each(function () {
$(this).css('display', 'block');
});
})
.on('mouseout', function () {
listItem.find('ul').each(function () {
$(this).css('display', 'none');
});
});
});
});
});
Upvotes: 2
Reputation: 5625
You need to add hover callbacks to your li
element, not a
element, so the code becomes:
var listItem = $(this);
listItem.find('> a').each(function(){
var aTag = $(this);
aTag.append('<img src="{img_url}/caret.png" width="8" height="8">');
});
listItem
.on('mouseover', function(){
listItem.find('ul').each(function(){
$(this).css('display', 'block');
});
})
.on('mouseout', function(){
listItem.find('ul').each(function(){
$(this).css('display', 'none');
});
});
Also, as marsh
answer goes, it is more proper performance-wise to do such things with css, not javascript.
Upvotes: 1
Reputation: 430
$(document).ready(function () {
$('nav ul li:has(ul)').each(function () {
var listItem = $(this);
$(this).find('> a,>ul').each(function () {
var aTag = $(this);
aTag.append('<img src="{img_url}/caret.png" width="8" height="8">');
aTag.on('mouseover', function () {
listItem.find('ul').each(function () {
$(this).css('display', 'block');
});
})
.on('mouseout', function () {
listItem.find('ul').each(function () {
$(this).css('display', 'none');
});
});
});
});
});
Here only update is:
$(this).find('> a,>ul')
Css:
only update is one:
nav > ul > li > a {
display: block;
margin: 0px;
border-bottom: 0;
color: #333;
height: 52px;
padding: 0px 25px 0px 25px;
font-size: 1.25em;
line-height:55px;
}
Update in padding and add line-height.
Demo: http://jsfiddle.net/fsrf5jw3/5/
Upvotes: 1