Display a single submenu on mouseover using Javascript

Hello there,

I have been working on creating a small menu using only Javascript, but I am facing an issue where the onmouseover event is displaying all submenus instead of just one.

Below is the section of code that is supposed to change style.display to block:

var ul = document.getElementById("navMainId"),
    var liDropdown = ul.getElementsByClassName("dropdown");

for (var i = 0; i < liDropdown.length; i++) {
    liDropdown[i].style.display = "inline-block";

    liDropdown[i].onmouseover = function () {
        var ul = document.getElementById("navMainId"),
            dropdown = ul.getElementsByClassName("dropdown-content");


        for (var i = 0; i < dropdown.length; i++) {
            dropdown[i].style.display = "block";                
        }
    }
    liDropdown[i].onmouseleave = function () {
        var ul = document.getElementById("navMainId"),
            dropdown = ul.getElementsByClassName("dropdown-content");

        for (var i = 0; i < dropdown.length; i++) {
            dropdown[i].style.display = "none";
        }
    }
}

Any ideas on how I can modify the code to make it function correctly?

You can view the complete code on Fiddle here (apologies for the mess): https://jsfiddle.net/apvsnzt5/1/

Answer №1

I have made some necessary changes to the fiddle:

https://jsfiddle.net/qwerty123/5/

The key adjustment required was modifying

        dropdown = ul.getElementsByClassName("dropdown-content");

to

        dropdown = this.getElementsByClassName("dropdown-content");

This change ensures that it selects "this" (which is the LI being hovered over) instead of searching for "dropdown-content" within the UL element.

Remember to apply the same modification to the onmouseleave event as well.

Answer №2

It appears that there is a mistake in referencing the container when hovering over with the mouse. Ensure you provide specific content based on the position of your mouse.

var dropdown = this.getElementsByClassName("dropdown-content");

Check out the revised fiddle here

Answer №3

Make sure to include the following in your CSS section

.dropdown-content{
      display:none ! important;
    }
    a:hover+.dropdown-content{
      display:block ! important;
    }

Your code should now be working properly.

var menuCont = document.createElement("div");
    document.body.appendChild(menuCont);


    var ulMain = document.createElement("ul");
    menuCont.appendChild(ulMain); 
    ulMain.className = "navMain";
    ulMain.id = "navMainId";

    /****** MENU  ******/


    // Software
    var liSoftware = document.createElement("li");
    liSoftware.className = "menu dropdown";
    ulMain.appendChild(liSoftware);
    var aSoftware = document.createElement("a");
    aSoftware.className = "menuName dropbtn";
    aSoftware.href = "#";
    aSoftware.textContent = "Test1";
    liSoftware.appendChild(aSoftware);

    // GeCoSoft
    var liGeco = document.createElement("li");
    liGeco.className = "menu dropdown";
    ulMain.appendChild(liGeco);
    var aGeco = document.createElement("a");
    aGeco.className = "menuName dropbtn";
    aGeco.href = "#";
    aGeco.textContent = "Test2";
    liGeco.appendChild(aGeco);


    /******* Submenu *******/

    // Software Sub

    var divSubSoft = document.createElement("div");
    divSubSoft.className = "dropdown-content";
    liSoftware.appendChild(divSubSoft);

    var aSub1 = document.createElement("a"),
        aSub2 = document.createElement("a");

    aSub1.className = "menuSubName";
    aSub1.textContent = "SubMenu1";
    aSub1.href = "#";
    aSub2.className = "menuSubName";
    aSub2.textContent = "SubMenu2";
    aSub2.href = "#";

    divSubSoft.appendChild(aSub1);
    divSubSoft.appendChild(aSub2);

    // Gecosoft Sub

    var divSubGeco = document.createElement("div");
    divSubGeco.className = "dropdown-content";
    liGeco.appendChild(divSubGeco);

    var aSub3 = document.createElement("a"),
        aSub4 = document.createElement("a");

    aSub3.className = "menuSubName";
    aSub3.textContent = "Submenu3";
    aSub3.href = "#";
    aSub4.className = "menuSubName";
    aSub4.textContent = "SubMenu4"
    aSub4.href = "#";

    divSubGeco.appendChild(aSub3);
    divSubGeco.appendChild(aSub4);

    /****** MENU STYLE ******/

    var i = "";


    ulMain.style.listStyleType = "none"; 
    ulMain.style.margin = "0px";  
    ulMain.style.padding = "0px";     
    ulMain.style.overflow = "hidden";
    ulMain.style.backgroundColor = "rgb(232, 225, 225)";

    var ul = document.getElementById("navMainId"),
        li = ul.getElementsByTagName("li");

    for (var i = 0; i < li.length; i++) { 
        li[i].style.cssFloat = "left";
    }

    var a = ul.getElementsByTagName("a"); 

    for (var i = 0; i < a.length; i++) {
            a[i].style.display = "inline-block";
            a[i].style.color = "black";
            a[i].style.textAlign = "center"; 
            a[i].style.padding = "14px 16px";  
            a[i].style.textDecoration = "none";
            a[i].onmouseover = function () { 
                this.style.backgroundColor = "rgb(174, 170, 170)";            
            }
            a[i].mouseleave = function () {
                this.style.backgroundColor = "rgb(232, 225, 225)";
            }
    }

/************ Not sure what to do here **************/
    var liDropdown = ul.getElementsByClassName("dropdown"); 

    for (var i = 0; i < liDropdown.length; i++) {
        liDropdown[i].style.display = "inline-block";

        liDropdown[i].mouseover = function () {
            var ul = document.getElementById("navMainId"),
                dropdown = ul.getElementsByClassName("dropdown-content");


            
            for (var i = 0; i < dropdown.length; i++) {
                dropdown[i].style.display = "block";                
            }
        }
        liDropdown[i].mouseleave = function () {
            var ul = document.getElementById("navMainId"),
                dropdown = ul.getElementsByClassName("dropdown-content");

            for (var i = 0; i < dropdown.length; i++) {
                dropdown[i].style.display = "none";
            }
        }
    }

    var divDropCont = ul.getElementsByClassName("dropdown-content");

    for (var i = 0; i < divDropCont.length; i++) {
        divDropCont[i].style.display = "none";
        divDropCont[i].style.position = "absolute";
        divDropCont[i].style.backgroundColor = "#f9f9f9";
        divDropCont[i].style.minWidth = "160px";
        divDropCont[i].style.boxShadow = "0px 8px 16px 0px rgba(0,0,0,0.2)";
    }

    var aDropCont = ul.getElementsByClassName("menuSubName");   

    for (var i = 0; i < aDropCont.length; i++) {
        aDropCont[i].style.color = "black";
        aDropCont[i].style.padding = "12px 16px";
        aDropCont[i].style.textDecoration = "none";
        aDropCont[i].style.display = "block";
        aDropCont[i].style.textAlign = "left";
        aDropCont[i].onmouseover = function () {
            this.style.backgroundColor = "rgb(174, 170, 170)";
        }
        aDropCont[i].mouseleave = function () {
            this.style.backgroundColor = "rgb(249, 249, 249)";
        }
    }
.dropdown-content{
  display:none ! important;
}
a:hover+.dropdown-content{
  display:block ! important;
}

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

What could be causing the npm install command to not save packages in the /node_modules directory?

After running npm install to add a package, npm indicates that the installation was successful. However, upon checking the node_modules folder, I'm unable to locate the installed package. In order to access the package, I have resorted to using npm in ...

AngularJS field array

Is it possible to create an array that contains references to the fields in a form (such as input, textarea, etc.) and then run a function on them in my code, like addClass()? To clarify my objective - I am looking to add a red border color to any invalid ...

Building interactive web forms with real-time validation using CodeIgniter

I'm looking for a way to use ajax (jquery library) to validate my forms. Specifically, I have a form that requires a minimum password length of 6 characters. Currently, I have implemented the validation rule as follows, $this->form_validation-> ...

What is causing the page to not load in my development environment (MAMP PRO) when using header()?

Has anyone experienced the issue where suddenly on MAMP PRO, the page will only load up to the header() function? For example, here is a header call I am using: header('Location: /index_signedIn.php'); exit(); I have tested my other sites and ...

Troubleshooting: Inline Styles not displaying Background Div Images in Next.Js

I am currently attempting to display images in a component by using a map and an external JS file to store the images as objects. I then loop through them to set each one as a background image for every created div. However, it seems like my current implem ...

Equal vertical alignment in the center using flexbox

My flexbox layout is set up as shown in the code snippet below: html { height:100%; width:100%; } body { display:flex; flex-direction:column; align-items:stretch; height:100%; width:100%; margin:0; background-color:grey; } header { b ...

After extended periods of use, the website experiences frequent crashes

Currently, I am developing a website using a free provider (000webhost) and focusing on integrating a chat feature. To achieve this, I have implemented an interval every 500 milliseconds that reads a file to check for new messages. When a new message is de ...

It is important to ensure that the user returned by the onAuthStateChanged function in

server admin.auth().createCustomToken(uuid) .then((customToken) => { admin.auth().createUser({ email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ed989e889fad88958c809d8188c38e8280">[email protected] ...

Images in SCSS distorted due to styling issues

I am encountering an issue with a round image displaying properly on a browser, but appearing distorted after building the apk and running it on my android phone. The image's width is greater than its height. How can I ensure that it remains round? M ...

Email the jQuery variable to a recipient

I'm facing an issue with sending a jQuery variable containing HTML and form values via email using a separate PHP file with the @mail function. My attempt involves using the jQuery $.ajax function on form submit to send this variable, but unfortunate ...

Can a file be transferred from an Electron application to an Express server by supplying the file path?

This is my current objective: A user drags and drops a file into Electron Electron uses a python script via child_process.exec to convert the file The conversion process generates a new file in the same directory as the original With knowledge of the path ...

Revise the calculation output when a specific input is missing

As I work on creating a basic web page for computing values based on selected options, I've encountered an issue with the calculation process. The result does not immediately appear; instead, I have to input a value like 0 and then delete it in order ...

Sending data from a parent component to a child component through a function

In the process of developing an app, I have implemented a feature where users must select options from four dropdown menus. Upon clicking the "OK" button, I aim to send all the selections to a child component for chart creation. Initially, I passed the sel ...

Utilizing React with Material UI, implement a Select component while disabling the scroll lock and ensuring the menu is positioned relative to

import React from "react"; import "./styles.css"; import Input from "@material-ui/core/Input"; import MenuItem from "@material-ui/core/MenuItem"; import FormControl from "@material-ui/core/FormControl"; import Select from "@material-ui/core/Select"; cons ...

Exploring AngularJS tab navigation and injecting modules into the system

Two separate modules are defined in first.js and second.js respectively: first.js var app = angular.module('first',['ngGrid']); app.controller('firstTest',function($scope)) { ... }); second.js var app = angular.mo ...

I'm experiencing an "existing database with different casing already exists" error, even though I have no intention of creating a new database

My goal is to include a new word in a database called "wordsDb" within a collection named "wordsCollection": dbName = "wordsDb"; collectionName = "wordsCollection"; connectionUri = //... (secret) async add(word) { try { ...

Issue with Element Not Displaying During Page Load with Quick AJAX Request

I attempted to display a loading gif while making an ajax request that takes a long time to respond, and then hide the loading gif once the response is received. Here is the code snippet : $('.loading-gif').show(); $ajax({url:'',async ...

What is the best way to ensure that my $.ajax POST call works seamlessly with SSL?

Below is the JavaScript code I am using: parameter = "name=" + name + "&email=" + email + "&phone=" + phone + "&comments=" + comments; $.ajax({ url: 'sendEmail.php?' + parameter, success: ...

Is there a way to remove a value from the search bar while updating the table at the same time?

Although I can successfully search the table based on the values in my search bar, I am having trouble with updating the state when deleting a value. To see my code in action, check out my sandbox here. ...

Error Message: Expecting an Object - Microsoft JScript Runtime Error in Node.js

I am starting my journey with Node JS and I encountered an unexpected error while running my code. Microsoft Jscript Runtime Error appeared, stating that "Object expected at line number 1". const fs = require('fs'); function FileObject () { thi ...