Question

I'm trying to get something like the navigation on the following site to work.link

I have the following code so far on JSFIDDLE and have it kind of working. The only issue is when hovering over the submenu li's for a second time (or cycling through them) the new background div does not drop down again.

Any suggestions much appreciated - thanks

EDIT:

I've simplified the demo here jsfiddle.net/XLZGP/11 to just the main menu items. I'm looking for the new colour to slide in while the old colour does NOT slideup.

code as follows

HTML

<header>
<div class="inner-header">
    <nav>
        <ul>
            <li class="parent"> <a href="#" title="bus">bus</a>

                <div class="locations-wrapper">
                    <ul class="sub-menu">
                        <li><a href="#" title="station">station</a>

                        </li>
                        <li><a href="#" title="stop">stop</a>

                        </li>
                    </ul>
                </div>
            </li>
            <li class="parent"> <a href="#" title="train">train</a>

                <div class="locations-wrapper">
                    <ul class="sub-menu">
                        <li><a href="#" title="station">station</a>

                        </li>
                        <li><a href="#" title="stop">stop</a>

                        </li>
                    </ul>
                </div>
            </li>
        </ul>
    </nav>
</div>
<div class="boxes">
    <div class="bus"></div>
    <div class="bus-station"></div>
    <div class="bus-stop"></div>
    <div class="train"></div>
    <div class="train-station"></div>
    <div class="train-stop"></div>
</div>
</header>

JS

var parentList = $('.parent');
var currentTitle;
var currentChildTitle;

parentList.on('mouseover', function () {
    $(this).find('.locations-wrapper').slideDown(400);
    currentTitle = $(this).find('a').attr('title');
    $('.' + currentTitle).addClass('open').slideDown(400);

});

parentList.on('mouseleave', function () {
    $(this).find('.locations-wrapper').slideUp(400);
    $('.boxes').children('div').removeClass('open').slideUp(400);
});

$('.sub-menu').on('mouseover', 'li', function () {
    currentChildTitle = $(this).find('a').attr('title');
    currentChildTitle = currentTitle + '-' + currentChildTitle;
    $('.boxes').children('div').removeClass('open');
    $('.' + currentChildTitle).addClass('open').slideDown(400);
});`
Was it helpful?

Solution 3

Took a different approach and decided to create the slide down div backgrounds dynamically through JS - creating each dom node and then assigning it to the dom, limiting the total number produced.

Overlaying each div with the next. WORKING JSFIDDLE

var parentList = $('.parent');

// declare variables
var currentChildTitle;
var currentTitle;
var banner;

// setup append div function
function dropBanner(currentTitle) {
    // create the banner variable dom node
    banner = $('<div class="' + currentTitle + '"/></div>');
    // add it to the dom
    $('.boxes').append(banner);
    // animate it
    $('.' + currentTitle).slideDown(300);
}

// setup a function to limit the number of divs appended
function chop() {
    if ($('.boxes div').length > 15) {
        $('.boxes div').eq(0).remove();
    }
}

// listen for mouseover the parent list items
parentList.on('mouseover', function (e) {

    if (!($(this).find('.locations-wrapper').is(':visible'))) {
        $(this).find('.locations-wrapper').slideDown(300);
    }

    // grab the current list item title
    currentTitle = $(this).find('a').attr('title');

    // call dropBanner passing the current list item title 
    dropBanner(currentTitle);
    chop();

});

// listen for mouseleave
parentList.on('mouseleave', function () {
    $(this).find('.locations-wrapper').delay(300).slideUp(300);
    $('.boxes div').delay(300).slideUp(300);
});

// listen for mouseover the submenu list items
$('.sub-menu').on('mouseover', 'li', function (e) {

    // grab the current list item title
    currentTitle = $(this).find('a').attr('title');

    // call dropBanner passing the current list item title 
    dropBanner(currentTitle);
    chop();

    // stop the bubbling up effect to parent list items
    e.stopPropagation();
});

OTHER TIPS

I think what you are looking for is something closer to this, http://jsfiddle.net/un5ke/1/

var mouseLeft = true;

$('.sub-menu').on('mouseleave', 'li', function () {
    mouseLeft = true;
    setTimeout(function() {
        if (mouseLeft) {
            var toClose = $('.boxes').children('div.open');
            toClose.slideUp();
            toClose.removeClass('open');
        }
    }, 500);
});

$('.sub-menu').on('mouseover', 'li', function () {
    mouseLeft = false;

    currentChildTitle = $(this).find('a').attr('title');
    currentChildTitle = currentTitle + '-' + currentChildTitle;
    var toOpen = $('.' + currentChildTitle);

    if (!toOpen.hasClass('open')){
        var toClose = $('.boxes').children('div.open');

        toOpen.addClass('open').slideDown(400, function completed () {
           $(toClose).slideUp();               
           $(toClose).removeClass('open');
        });
    }
});

There is a couple of things that I have done:

  1. Removed z-index from the open class
  2. Added a half-second delay to a mouse leave, so that if the person is mousing from one to another the background doesn't go crazy.
  3. Removed the mouseleave of the entire menu becuase that isn't the issue at the moment.
  4. Double-checking before opening that the current menu isn't already opened.

You don't have a mouseleave handler for your sub menu items, so once they're down, they're down.

I added a quick mouseleave for the sub-menu's too in a fiddle - should be a starter for the exact effect you want to achieve:

http://jsfiddle.net/XLZGP/

$('.sub-menu').on('mouseleave', 'li', function () {
    currentChildTitle = $(this).find('a').attr('title');
    currentChildTitle = currentTitle + '-' + currentChildTitle;
    $('.' + currentChildTitle).removeClass('open').slideUp(400);
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top