1

I have this bit of HTML:

<div id="site-header-inner">
    <div id="header-logo">
    <?php echo wp_get_attachment_image(get_field('header_logo','options'),'full'); ?>
    </div>
    <div id="header-nav">
        <ul>
            <li class="header-nav-item">
            Articles 
            </li>
            <li class="header-nav-item">
            Art Space
            </li>
            <li class="header-nav-item">
            Job Board
            </li>
            <li class="header-nav-item">
            Calendar
            </li>
        </ul>
    </div>
</div>  
<div id="header-nav-dropdown"> 
    <div id="dropdown-inner">
    Dropdown Stuff
    </div>
</div>

When the <li class="header-nav-item"> is hovered, I want to show the <div id="header-nav-dropdown"> using javascript/jquery.

What is the simplest way to do that while also keep the <div id="header-nav-dropdown") visible as long as the mouse is over it or the <li>?

11
  • I'll have an answer out for you momentarily that will cover everything you are trying to do. Commented Jan 22, 2014 at 6:49
  • Have you even tried to search for this topic on stackoverflow and/or google? Commented Jan 22, 2014 at 6:51
  • I have indeed, which is how I find most answers to my problems. I've found many JS snippets and tried them, but I can't see to get them to work. I'm hoping a fresh solution tied to my specific code might do the trick. Commented Jan 22, 2014 at 6:52
  • Check my answer out, it's fully explained and a simple copy paste should do the trick for you. Commented Jan 22, 2014 at 6:59
  • Pft. jQuery. Reduce that 33kb load (minified) with some good ol' fashion javascript. Commented Jan 22, 2014 at 7:00

4 Answers 4

2

It would probably be easiest to maintain a small self-invoking function to manage this so it doesn't impact any other scripts.

All we're doing is binding mouseover events to the items we want to reveal the dropdown list to, and when we mouseout, we're giving the user 500ms (change the time

(function($){
    // Select the items you want to bind our mouse events to.
    var $hoverItems = $("#header-nav .header-nav-item, #header-nav-dropdown");
    // Dropdown list.
    var $dropdownList = $("#header-nav-dropdown");
    // This is a timeout variable so we can keep track of our mouse incomings/outgoings.
    var timeout;

    // Bind mouseover/mouseout events.
    $hoverItems.on("mouseover", function(){
        $dropdownList.show();
        clearTimeout(timeout);
    }).on("mouseout", function(){
        timeout = setTimeout(function(){
            $dropdownList.hide();
        }, 500);
    });
})(jQuery);
Sign up to request clarification or add additional context in comments.

Comments

2

Here is the vanilla way to do this. Add the CSS display:none to hide any element you want (in this case, your header elements that will be displayed when you hover the li).

Grab the li elements and give them an event.

var derp = document.getElementsByClassName("header-nav-item");
var herp = document.getElementsByClassName("header-nav-dropdown");
for (var i=0;i<derp.length;derp++) { //loop the array of dom elements
    derp[i].addEventListener('mouseover', function() {
        for (var x=0;x<herp.length;herp++) {
            herp[x].style.display = "block"; //or inline etc
        }
    });
    derp[i].addEventListener("mouseout", function() {
        for (var x=0;x<herp.length;herp++) {
            herp[x].style.display = "none"; //hide again
        }
    });
}

This loops the li elements, adds listeners for mouseout and mouseover and within them, hides/shows all elements with the header class. No need for jQuery!

4 Comments

I considered offering him vanilla JS, but for somebody who is more of a developer and not as experienced as a programmer, even concepts like loops can throw people off sometimes, so I figured just give him the JQuery version since he tagged it anyway. Good answer, though!
(Didn't edit your post to be a jerk, there was a typo and I wanted to just edit it for you in case you had left, and had to change another word so it would accept the typo)
I approved it, don't worry :)
@Mr.Lavalamp What?!? People being nice on SO?
0

I would use variables as flags and do something like this:

var liHover = false;
var dropdownHover = false;
$(document).ready(function() {

    $('.header-nav-item').mouseover(function() {
        liHover = true;
        $('#header-nav-dropdown").show();
    });
    $('#header-nav-dropdown').mouseover(function() {
        dropdownHover = true;
    });

    $('.header-nav-item').mouseout(function() {
        liHover = false;
    });
    $('#header-nav-dropdown').mouseout(function() {
        dropdownHover = false;
    });

    $('.header-nav-item, #header-nav-dropdown').mouseout(function() {
        if (!liHover && !dropdownHover) {
            $('#header-nav-dropdown").show();
        }
    });
});

Now I'll explain all the decisions there. The mouseovers are in separate method calls because it makes more sense than using an if statement and combining them. The li hover needs to show the dropdown and adjust its respective flag, while the dropdown hover only needs to adjust its flag. I chose to still separate the flag adjustments for the mouseouts, but you COULD put them both in the combined mouseout with an if statement. Then of course for the combined one, it is such because that is the functionality that will exist in either instance.

EDIT: Sorry, I had a typo, the last mouseout said mouseover. It's fixed.

Comments

0

I hope this is what you need!

Jquery:

$('#header-nav li.header-nav-item').hover(function () {
    $('#header-nav-dropdown').show(); 
}, function () {
    $('#header-nav-dropdown').hide();
});

css:

#header-nav-dropdown {
    display: none;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.