ngplayground
ngplayground

Reputation: 21617

jQuery only add class if element exists

How could I adapt the code below to work as its needed?

At the moment .active adds to both the home <a> tag and services <a> tag. But I only want it to add if .submenu exists

html

<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Services</a><div class="submenu">menu contents</div></li>
</ul>

jQuery

$(document).ready(function(){
    $('.nav li').mouseenter(function(){
        $(this).find('a').addClass('active');
        $(this).find('.submenu').fadeIn();
    }).mouseleave(function(){
        $(this).find('.submenu').stop().fadeOut();
        $(this).find('a').removeClass('active');
    });
});

Upvotes: 0

Views: 999

Answers (2)

adeneo
adeneo

Reputation: 318182

$(function(){
    $('.nav li').on('mouseenter mouseleave', function(e){
        var sub   = $(this).find('.submenu'),
            state = e.type == 'mouseenter';

        if (sub.length) {
            $(this).find('a').toggleClass('active', state);
            sub[state ? 'fadeIn' : 'fadeOut']();
        }
    });
});

Upvotes: 2

Giona
Giona

Reputation: 21114

Here you go:

$(document).ready(function(){
    $('.nav li').mouseenter(function(){
        var $this = $(this),
            $submenu = $this.find('.submenu');
        if($submenu.length>0){
            $this.find('a').addClass('active');
            $submenu.fadeIn();
        }
    }).mouseleave(function(){
        var $this = $(this),
            $submenu = $this.find('.submenu');
        if($submenu.length>0){
            $this.find('a').removeClass('active');
            $submenu.fadeOut();
        }
    });
});

BUT an easier way would be to work this out in CSS:

.nav li .submenu { display:none; }
.nav li:hover .submenu { display:block; }
.nav li:hover a { /* equivalent to a.active */ }

Or, to make a "softer" transition:

.nav li .submenu { height:0; overflow:hidden; transition:height 250ms linear; }
.nav li:hover .submenu { height:auto; }

Upvotes: 1

Related Questions