Creating a JavaScript function to automatically hide a dropdown menu after a specific duration

I'm currently working on a side menu that drops down when hovering over Section One within the <a> tag. I need some guidance on how to make the JavaScript code continuously check the state of the list after a set amount of time in order to automatically close the menu. Can anyone offer some assistance?

HTML

<div class = "sidebarwrap">
    <ul>
       <li>
        <a href="#" onmouseover="toggle(this); return true;" onmouseout="timer()">Section One</a>
            <ul>
               <li><a href="#" >link page</a></li>
               <li><a href="#" >link page</a></li>
               <li><a href="#" >link page</a></li>
               <li><a href="#" >link page</a></li>
            </ul>
       </li>
     </ul>
   </div>

CSS

.sidebarwrap{
    width:auto;
    height:auto;
}

.sidebarwrap ul{
    float:left;
    display:block;
    background:white;
    padding:10px;
    margin-right:30px;
    margin-left:10px;
    list-style-type:none;
    border:1px dotted #0099CC;
    border-radius:100px/10px;
}

.sidebarwrap ul ul{
    list-style-type:none;
    display:none;
    border:0px dotted #0099CC;
    border-radius:20px/60px;
}

.sidebarwrap li li{
    list-style-type:circle;
    border:0px dotted #0099CC;
    border-radius:20px/60px;
    padding:5px;
}

JavaScript

var cssNode = document.createElement('link');
cssNode.setAttribute('rel','stylesheet');
cssNode.setAttribute('type','text/css');
cssNode.setAttribute('href', 'javascript-overrides.css');
document.getElementsByTagName('head')[0].appendChild(cssNode);


function toggle(toggler) {

    if(document.getElementById){
        targetElement = toggler.nextSibling;

        if(targetElement.className == undefined){
            targetElement = toggler.nextSibling.nextSibling;
        }

        if (targetElement.style.display == "block") {
            targetElement.style.display = "none";
        } else {
            targetElement.style.display = "block";
            timer();
        }
    }
}

function timer(){
    var Time = setTimeout(function(){toggle(toggler)},1000);
}

Answer №1

To achieve this functionality in jQuery, you can utilize the .hover() method. Simply attach the event to the link when the page is loaded.

$(document).ready(function () {
    $("a").hover(function () {
       $(this).next().slideDown(); 
    },
    function () {
        $(this).next().delay(1000).slideUp();
    });
});

For a demonstration, refer to this working example: http://jsfiddle.net/WFN6q/

If you prefer using Vanilla JS, here is a sample implementation:

<ul>
    <li>
        <a href="#" onmouseover="showMenu(this)" onmouseout="hideMenu(this)">Section One </a>
        <ul>
            <li>text</li>
            <li>text</li>
            <li>text</li>
            <li>text</li>
        </ul>
    </li>
</ul>

Include the following JavaScript code:

function showMenu(myLink) {
    myLink.nextElementSibling.style.display = 'block';
}

function hideMenu(myLink) {
    var ulElem = myLink.nextElementSibling;
    if (ulElement.style.display === 'block') {
        setTimeout(function () { myLink.nextElementSibling.style.display = 'none' }, 1000);
    }
}

Answer №2

After analyzing your code, it came to my attention that you have set onmouseout to call timer(), creating an unnecessary timeout function without defining toggler. This leads to a continuous recursion every ~1000ms.

To address this issue, I recommend establishing a global Timers variable to manage your timer references. This will allow you to exit the function and manipulate or cancel the timer as needed. Additionally, implementing a Singleton model can help prevent multiple instances of timers from being created.

var Timers = {}; // initialize a Timers object to store timers.
function timer(target){
    Timers.sectionOne = setTimeout(function(){ toggle(target); }, 1000);
}

Furthermore, consider incorporating the approach suggested by @Bic for a more elegant solution.

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

The Discord.js guildMemberUpdate event: Everything you need to know

I am currently working on creating a welcome message bot using Discord.js. The goal is to have the bot send a welcome message through a webhook in a specific channel when a member gains access to it. Here's what I have so far: client.on("guildMe ...

Is there a way to seamlessly transition between different Angular components without having to refresh the entire webpage?

I'm currently working on implementing a navigation bar that allows users to switch between three components without having the navbar reload. The goal is for only the new component to load when the user clicks on a different section of the navbar, kee ...

Leveraging Webpack and Jest for seamless module importing in a development project

I've been working on a Node project and utilizing imports and exports extensively. To package the frontend code, I opted for Webpack. However, it seems to require running as common JS. Moreover, Jest is being used in my project, which led me to spec ...

Strange response received from $http GET request on Android device running Crosswalk

I am attempting to retrieve data in JSON format from an API using AngularJS. The process is successful on iOS and desktop browsers, but I'm encountering a strange response when trying it on my Android device. The request code looks like this: $http({ ...

Accessing a specific element within an array that has been nested within another array, using JavaScript

Here's what my code looks like: planets[0]= new THREE.Mesh( geometry, material ); planettexts[0]= new THREE.Mesh( textGeometry, textMaterial ); planets[0].add(planettexts[0]); Now, I am trying to hide the planettext, but every attempt results in an ...

Ways to retrieve information from a intricate JSON structure?

Can anyone help me understand why I am unable to access the data in the detail option of the JSON? My goal is to load the firstName, lastName, and age into a list for each object. var data = { "events": [{ "date": "one", "event": "", "info ...

Ways to display an error notification alongside another message

I have set up a validation directive that requires users to check a box. If the checkbox is left unchecked, an error message will be displayed. However, I am facing an issue where the message overlaps with the checkbox text. https://i.sstatic.net/iTKoo.jp ...

Learn the method for toggling images in HTML while simultaneously storing a 0 or 1 in a flag variable

In my design, I would like to have a star icon that displays two star icons at once - one blank and the other yellow. These stars will swap their appearance when clicked or tapped on touch screen devices. Additionally, I want to be able to store values as ...

Steps to make a pop-up window for text copying by users

On my website, I have a link that users need to copy for various purposes. I want to provide an easy way for them to see the link and then manually copy it to their clipboard. Instead of using code to copy to the clipboard, I am looking for a solution whe ...

"Addclass() function successfully executing in the console, yet encountering issues within the script execution

I dynamically created a div and attempted to add the class 'expanded' using jQuery, but it's not working. Interestingly, when I try the same code in the console, it works perfectly. The code looks like this: appending element name var men ...

Is there a way to determine if a value exists within an array of objects?

Is it possible to determine if a specific value is present in an array of objects? I've tried a method, but it always returns false. What would be the most effective way to solve this issue? My approach: var dog_database = [ {"dog_name": "Joey" ...

Creating an adjustable fixed footer using Bootstrap 3

Struggling with the application of bootstrap styling. I have a footer with columns set as col-md-3, 3, 2, 4 which sums up to a total of 12. The issue lies in the differing content within each column. My goal is to achieve equal spacing between each div in ...

How can I apply styling to Angular 2 component selector tags?

As I explore various Angular 2 frameworks, particularly Angular Material 2 and Ionic 2, I've noticed a difference in their component stylings. Some components have CSS directly applied to the tags, while others use classes for styling. For instance, w ...

AngularJS's ScrollTo function allows users to scroll to a specific

Trying to implement a quick nav that smoothly scrolls to different sections on the page when a link is clicked. Currently using a guide provided by Treehouse for reference. $("#quickNav a").click(function(){ var quickNavId = $(this).attr("href"); ...

Typing into the styled M-UI TextFields feels like a never-ending task when I use onChange to gather input field data in a React project

Having an issue where entering text into textfields is incredibly slow, taking around 2 seconds for each character to appear in the console. I attempted using React.memo and useCallback without success :/ Below is my code snippet: const [userData, setUserD ...

Safari iOS does not display any background for Buttons

Encountering an unusual problem with buttons on iOS devices specifically in Safari browser - the background color isn't being applied like it is on Desktop and Android devices. Here are the CSS properties for the button: export const Button = styled.b ...

I am working with an array of objects in React JavaScript, and I need to find a way to convert it into

Currently, I am in the process of creating this JavaScript function: export function convertArrayObjToFileDownload(data, filename, filetype = 'application/octet-stream') { const blob = new Blob(data, { type: filetype }); downloadBlob(blob ...

Issues with Content-Security-Policy Implementation in Next JS and AMP Technology

While developing an AMP application with Next JS, everything seems to work perfectly in localhost. However, upon moving to the production environment, I encountered errors related to AMP not being allowed to load its workers. The initial error message is: ...

Obtaining your CSGO inventory via Steam API using jsonp: A step-by-step guide

Hey there! I'm currently facing an issue while trying to access a player's CSGO inventory using Valve's API. Unfortunately, I keep running into the error message stating that no 'access-control-allow-origin' header is present on th ...

Exploring the functionality of Radar Chart within a React component

Within the index.html file that is being utilized, there exists a javascript code specifically designed for the chart function. <script src="js/plugins/chartJs/Chart.min.js"></script> var radarData = { labels: ["In Perso ...