Interactive sub-menu that only appears when hovered over

One of the issues I am facing is with a "sub-menu" that only appears on :hover. Check out the JSFiddle here for reference.

$('.prices').hover(function () {
    $('.sub-menu').fadeIn(150);
}, function () {
    $('.sub-menu').fadeOut(120);
});

Issue #1 - Whenever I hover over the main menu and try to click on a sub-menu link, it disappears.

Issue #2 - Resolving the first problem may lead to another concern: the sub-menu contains numerous links, so when a user tries to navigate to the last link by drawing a triangle (as seen in the illustration below), the sub-menu disappears again. How can this be avoided?

Note: While I understand that typically the sub-menu should be within an li element, in this case it does not work for what I am trying to achieve. The JSFiddle provided is just a simplified version of the actual scenario.

Answer №1

When dealing with situations where your sub-menu cannot be an actual child of its parent, there is a workaround that may be helpful. You can try implementing the following solution (View fiddle):

var priceTimeout;

function hide_prices() {
    clearTimeout(priceTimeout);
    $(".sub-menu").fadeOut(150);
}

$(".prices").on("mouseenter", function() {
    $(".sub-menu").fadeIn(150);
});

$(".prices").on("mouseleave", function() {
    clearTimeout(priceTimeout);
    priceTimeout = setTimeout(hide_prices, 1000);
});

$(".sub-menu").on("mouseenter", function() {
    clearTimeout(priceTimeout);
});

$(".sub-menu").on("mouseleave", hide_prices);

There are a couple of points to keep in mind:

  1. Since your .sub-menu is not a direct descendant of .prices, the mouseleave event on prices will always trigger when transitioning between them. To address this issue and prevent unexpected mouse movement behavior, we use a timeout mechanism to manage the visibility of the sub-menu. If we enter the sub-menu before the timeout triggers, we clear it to ensure continuous display.

  2. You have the option to condense this code by utilizing the shorthand .hover() method as you previously did, but for clarity purposes, I prefer employing the explicit .on() approach consistently.

Answer №2

The issue you are facing is caused by including the mouseout event handler (the second parameter in hover) which leads to hiding the sub menu every time it's triggered. A simple fix is to introduce a short delay of around 100 ms before actually hiding the submenu. This slight delay doesn't affect the visual appearance but allows the hovering on the submenu to interrupt the ongoing animation of the submenu, involving the delay and subsequent fadeOut functions. Therefore, the following snippet can be integrated:

// .prices:hover reveals .submenu
$('.prices').hover(function () {
    $('.sub-menu').stop(true,true).fadeIn(150);
}, function () {
    $('.sub-menu').stop(true,true).delay(100).fadeOut(120);
});
//
$('.sub-menu').hover(function(){        
    $(this).stop(true);  
    $(this).fadeIn(0);
}, function(){
    $(this).fadeOut(120);
});

Live Demo.

NOTE: The secondary issue doesn't require significant attention. Ideally, users should first hover over the submenu. Otherwise, we are left with no viable solution except keeping the submenu visible when the cursor moves away from the Prices menu.

Answer №3

Here is the answer, give this a try.

http://jsfiddle.net/iamrmin/tQcX9/3/

<ul class="menu">
    <li class="home">
        <a href="#">Home</a>
    </li>
    <li class="contact">
        <a href="#">Contact</a>
    </li>
    <li class="location">
        <a href="#">Location</a>
    </li>
    <li class="prices">
        <a href="#">Prices &raquo;</a>
        <ul class="sub-menu">
            <li>
                <a href="#">Year 2005</a>
            </li>
            <li>
                <a href="#">Year 2006</a>
            </li>
            <li>
                <a href="#">Year 2007</a>
            </li>
            <li>
                <a href="#">Year 2008</a>
            </li>
            <li>
                <a href="#">Year 2009</a>
            </li>
            <li>
                <a href="#">Year 2010</a>
            </li>
            <li>
                <a href="#">Year 2011</a>
            </li>
            <li>
                <a href="#">Year 2012</a>
            </li>
            <li>
                <a href="#">Year 2013</a>
            </li>
            <li>
                <a href="#">Year 2014</a>
            </li>
        </ul>
    </li>
    <li class="jobs">
        <a href="#">Jobs</a>
    </li>
</ul>


.sub-menu {
    display: none;
    position: absolute;
    left: 100px;
    background: #F4F4F4;
    list-style: none;
    padding: 10px;
}


a
{
    width: 101px;
    display: inline-block;
}

Answer №4

If nesting the ul elements is causing issues, here is an alternative solution to consider.

Show the menu by fading it in when hovering over .prices. To fade out, only do so when the mouse cursor is positioned to the left of .sub-menu. This approach addresses both concerns effectively.

$('.prices').hover(function () {
    $('.sub-menu').fadeIn(150);
});
$('.sub-menu').mouseleave(function () {
    $(this).fadeOut(150);
});

You might also want to automatically hide the sub menu after a set timeout period if the user does not enter the .sub-menu.

Fiddle Link

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can I modify my for loop with if else statements so that it doesn't just return the result of the last iteration in

Today is my first day learning JavaScript, and I have been researching closures online. However, I am struggling to understand how to use closures in the code I have written: function writeit() { var tbox = document.getElementById('a_tbox'). ...

Implement the ability for Hubot to create and publish posts

I'm currently in the process of integrating the http-post-say.coffee script into a hubot application that is running on Heroku. According to the documentation, after adding the script it should create the '/hubot/say' route which can accept ...

the message sent from a webpage to a Chrome extension using chrome.runtime.sendMessage does not receive

My Chrome extension, mv3, has the capability to receive messages from webpages and respond accordingly. Below are the code snippets that enable the webpage to send a message to the extension: chrome.runtime.sendMessage(chromeExtensionId, { ...

What is the method for condensing content using a Bootstrap toggle button (checkbox)?

Incorporating Bootstrap 5.1, I have a set of buttons that trigger the display or hide some content using the collapse plugin <div class="col m-2"> <button type="btn" class="btn btn-outline-primary m-1" d ...

MVC framework encountering unexpected behavior with jQuery ajax() function returning undefined object

Here is my jQuery function: $.ajax({ type: "POST", url: "/Accounting/Journal/SaveModal", data: varData, dataType: "json", contentType: "application/json; charset=utf-8", success: function (e) { alert(e); } ...

Can you tell me which specific font Adobe Edge Code (Brackets) uses in its code editor?

Can someone please help me? I'm trying to identify the syntax highlighter being used in this code. Is it Prettify or something else? ...

Reflection mask feature in Chrome for Android that uses Webkit technology

Chrome Reflection on Desktop Computers By using Chrome on a desktop computer, I am able to create an image reflection with the following CSS code: img { -webkit-box-reflect: below 0 -webkit-gradient( linear, left top, left bottom, from(tran ...

Inspired by the organization and depth provided by nested lists

I am facing an issue with my ul list where adding a nested ul causes the li items above to move. Can anyone explain why this is happening and suggest a solution? Here is an example: http://jsfiddle.net/y5DtE/ HTML: <ul> <li> first ...

A Node.js feature that enables atomic file replacement, triggering watchers only once

I have a unique scenario where I need to handle two types of processes. One process is responsible for writing a file, while the other processes are required to read it whenever there is a change. In my research, I came across fs.watch as a solution to ke ...

Update the information in the table with jQuery using AJAX

I have found a solution to refresh my table after deleting a row from it. The refreshing functionality works perfectly, however, the style and other associated JavaScript functions are not working as expected. before https://i.sstatic.net/dPUK0.jpg after ...

The lookAt method in THREE.js is not functioning properly when called after the rendering process

The code snippet below seems to be causing some issues. It requires jquery and three.js to function properly. The problematic lines are as follows: // change the view so looking at the top of the airplane views[1].camera.position.set( 0,5,0 ); views[1].ca ...

Trigger click events based on specific coordinates x and y in Fabric.js

While working on my project, I utilized three.js and fabric.js to manipulate textures on a 3D model. I managed to synchronize coordinates on the model with coordinates on the canvas in fabric js. However, I encountered an issue with simulating click events ...

What is the best way to identify specific strings within a given syntax and then separate them into an array without considering their original order

My task is to divide a string into separate parts. This is how I want it: I begin with an original string let allString = 'This is the test to replace the string'; I will convert the original string into an array based on another array. let to ...

AngularJS navigation structure

Here is the route setup I am currently using: .when('/stories/:action/:assetId', { templateUrl: 'sometpl.html', controller: 'ctrl' } My question is: How can I restrict the 'action' parameter to only accept spec ...

Rotating the face normal in ThreeJS, just not specifically on the floor

I am currently working on developing a house generator using a floorplan. The mesh generation process is running smoothly, but now I am faced with the task of flipping the normals on certain faces. buildRoomMeshFromPoints(planeScalar, heightScalar){ va ...

Utilizing JSON format, handling special characters, and storing data in a database

My friend approached me with a question and although I wanted to offer immediate help, I realized that seeking advice from others may provide better solutions. Situation: Imagine there is a Form that includes a RichText feature: DHTMLX RichText (). This R ...

Deleting a row from a table and then adding it back to the end of the table

My goal is to accomplish the following task: remove a row from a table that has the ID #emailTable, then reinsert the same row at the end of the table, and finally hide the reinserted row using JQuery. To remove the table row, I execute the following comm ...

Rails ajax request failing to convert embedded Ruby elements into HTML

Searching for a more suitable title, I am encountering an issue with an ajax call that appends a link to a div. The link includes erb code like #{post.comments.count} $('#comments_<%= @post.id %>').append("<%= escape_javascript (link_t ...

How to accentuate search results using Angular filters and conceal non-matching text?

Recently, I came across an interesting example of using Angular filter to highlight search results. It works well in highlighting the word 'suit', but I noticed that all non-matching text remains visible. If you'd like to see the example I ...

I designed my higher-order component to allow for dual invocations. How can I integrate Redux within this framework?

I have implemented my higher-order component (HOC) in such a way that it can be invoked twice, emphasizing the concept of "functional programming". However, I am facing challenges in connecting Redux to access state and certain functions. I would greatly ...