ShoeLace1291
ShoeLace1291

Reputation: 4698

How to not add arrows to links in my submenu in jQuery?

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

Answers (4)

Lafif Astahdziq
Lafif Astahdziq

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');
                });
            });
        });
    });
});

DEMO

Upvotes: 2

Eternal1
Eternal1

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

Vishwajeet Bose
Vishwajeet Bose

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

marsh
marsh

Reputation: 1441

I guess you can do it by CSS, I have removed events mouseover, mouseout and added this styles:

li:hover ul {
    display: block;
}

li:hover a {
    background: #66cc00;
}

li:hover li a {
    background: #333;
}

DEMO

Upvotes: 1

Related Questions