What is the JavaScript mouseenter/out event all about?

My goal is to create a hover effect using JavaScript. I am utilizing the mouseenter and mouseout events to display the content when the mouse hovers over a button and remove the content when the mouse moves out. However, I am facing an issue where the content disappears on mouse enter if it contains elements, but it works fine when the content does not contain any elements.

 const button = document.querySelector("button"),
                dropdown = document.querySelector(".dropdown");

            button.addEventListener("mouseenter", (e) => {
                dropdown.classList.add("active")

                dropdown.addEventListener("mouseenter", (e) => {
                    dropdown.classList.add("active")
                })

                button.addEventListener('mouseout', () => {
                    dropdown.classList.remove("active")

                    dropdown.addEventListener("mouseout", () => {
                        dropdown.classList.remove("active")
                    })
                })
            })
 * {
                padding: 0;
                margin: 0;
                box-sizing: border-box;
            }

            body {
                display: grid;
                place-items: center;
                height: 100vh;
                font-family: sans-serif;
            }

            button {
                padding: 1em;
                cursor: pointer;
            }

            .dropdown {
                position: absolute;
                width: 100PX;
                height: 200px;
                background-color: red;
                bottom: 52%;
                display: none;
            }

            .dropdown.active {
                display: block;
            }
<html lang="en">
    <head>
        <title>Document</title>
    </head>
    <body>
        <button>
            Hover Me
        </button>
        <div class="dropdown">
            <li>content</li>
            <li>content</li>
            <li>content</li>
            <li>content</li>
            <li>content</li>
            <li>content</li>
            <li>content</li>
            <li>content</li>
            <li>content</li>
            <li>content</li>
            <li>content</li>
        </div>
    </body>
</html>

Answer №1

Feel free to swap out mouseenter for mouseover - it will still work perfectly fine. Are you okay with that?

 const button = document.querySelector("button"),
                dropdown = document.querySelector(".dropdown");

            button.addEventListener("mouseover", (e) => {
                dropdown.classList.add("active")

                dropdown.addEventListener("mouseover", (e) => {
                    dropdown.classList.add("active")
                })

                button.addEventListener('mouseout', () => {
                    dropdown.classList.remove("active")

                    dropdown.addEventListener("mouseout", () => {
                        dropdown.classList.remove("active")
                    })
                })
            }) 
* {
                padding: 0;
                margin: 0;
                box-sizing: border-box;
            }

            body {
                display: grid;
                place-items: center;
                height: 100vh;
                font-family: sans-serif;
            }

            button {
                padding: 1em;
                cursor: pointer;
            }

            .dropdown {
                position: absolute;
                width: 100PX;
                height: 200px;
                background-color: red;
                bottom: 52%;
                display: none;
            }

            .dropdown.active {
                display: block;
            }
<html lang="en">
    <head>
        <title>Document</title>
    </head>
    <body>
        <button>
            Hover Me
        </button>
        <div class="dropdown">
            <li>content</li>
            <li>content</li>
            <li>content</li>
            <li>content</li>
            <li>content</li>
            <li>content</li>
            <li>content</li>
            <li>content</li>
            <li>content</li>
            <li>content</li>
            <li>content</li>
        </div>
    </body>
</html>

Answer №2

Instructions are provided in the example

// Access the <section>
const dropDown = document.querySelector(".dropdown");

// Bind the "mouseenter/leave" events to <section>
dropDown.addEventListener("mouseenter", drop);
dropDown.addEventListener("mouseleave", drop);

/**
 * Event handler automatically passes the (e)vent object
 * >> If "mouseenter" event occurs, add "active" class to current element,
 * which is linked to the "mouseenter" event 
 * (<section> aka .dropdown), and then exit function
 * >> Else, remove "active" class.
 */
function drop(e) {
  if (e.type === "mouseenter") {
    return this.classList.add("active");
  }
  this.classList.remove("active");
}
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

:root {
  /* rem unit references font-size on <html> tag */
  font: 300 2ch/1.25 "Segoe UI"
}

body {
  display: grid;
  place-items: center;
  min-height: 100vh;
  padding: 1rem;
  /* 
  Apply this to parent of .dropdown to avoid abrupt left shifts 
  */
  overflow: scroll;
}

.dropdown {
  /* 
  Allows all absolutely positioned children to refer to
  the borders of <section> regarding their own position (eg <menu>)
  */
  position: relative;
}

button {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100px;
  height: 50px;
  padding: 1em;
  font: inherit;
  cursor: pointer;
}

menu {
  /*
  As a child of <section>, its positioning
  (top, bottom, left, right, z-index) is relative to <section>
  */
  position: absolute;
  top: 50px;
  list-style: none;
  width: 100px;
  background-color: red;
}

li {
  /* default setting for each <li> - flat and invisible */
  height: 0;
  opacity: 0;
  /* Animation for expanding and compressing */
  transition: 0.4s ease-in;
}

.active menu {  
  padding: 0.25rem;
}

.active li {
  /* 
  When <section> has the "active" class, each <li> expands
  and becomes visible
  */
  height: 1.25rem;
  opacity: 1;
}
<!--
  Surround everything with a block-level tag and consider it as the "dropdown"
-->
<section class="dropdown">
  <button>Hover</button>
  <menu>
    <!-- 
      Only <ul>, <ol>, and <menu> can contain <li> elements 
    -->
    <li>content</li>
    <li>content</li>
    <li>content</li>
    <li>content</li>
    <li>content</li>
    <li>content</li>
    <li>content</li>
    <li>content</li>
    <li>content</li>
    <li>content</li>
    <li>content</li>
  </menu>
</section>

Answer №3

To achieve your desired outcome, you can rely on these two essential functions:

 button.addEventListener("mouseenter", (e) => {
    dropdown.classList.add("active")
 })
 dropdown.addEventListener("mouseleave", (e) => {
     dropdown.classList.remove("active")
 })

Experiment with using mouseleave within the dropdown layer to deactivate the class.

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

Inspect the render function in the 'RestApi' class

I encountered the following error: Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined ...

Converting a nested JSON array into a flat structure with Elastic Search and JavaScript

I am struggling to flatten my elastic query response and extract only the _source details into a single-level array. Below is an example of the elastic response: Although I can access an array of data using (response.hits.hits), I am having trouble flatt ...

Why does Next.js throw an error when using an additional <div></div>?

I'm new to exploring Next.js and I'm encountering an error when using the html tag twice. It works fine with just one container, but as soon as I add another one, this error pops up: Error: error: Unexpected token "div". Expected jsx i ...

Incorporate several websites into a React application without using iframes

After developing a React application with create-react-app, I attempted to embed another website onto the app using an iframe. Everything worked perfectly until I wanted to resize the iframe to fit the page, resulting in a Blocked a frame with origin from ...

Node.js: App crashed, standing by for file changes to initiate restart

While I was in the middle of a nodejs course on Udemy, I encountered an issue where the code suddenly started breaking and throwing errors. Even after attempting to replicate the instructor's code, the problem persisted. I sought guidance from this a ...

Send a PUT request using Ajax

I am a beginner when it comes to Ajax requests and I have crafted the code shared in this Pastie. On line 107, my $.PUT function is causing an error in Firebug stating that $.PUT is not a recognized function. I acknowledge that there are issues with my aja ...

Decoding top-level JSON arrays in Go

Currently, I'm delving into Go by creating a basic http server and I find myself needing to manage JSON responses. When dealing with an object response, handling it idiomatically only requires 2 lines of code: structResult := Foo{} json.Unmar ...

Issue with loading the main.css file

Getting Started Managing two domains can be a challenge, especially when trying to make them appear as one seamless website. In this case, I have ownership of and . Goal My goal is to merge the content of https://mauricevandorst.com/personal-page/index ...

Having trouble retrieving data from json_encode using jQuery AJAX and php

Having issues with an AJAX call from jQuery to PHP. The PHP responds with a JSON-encoded array, but the values are not accessible in jQuery. The status shows as OK, but the responseText is coming up as undefined. $(document).ready(function () { $( ...

Next.js triggers the onClick event before routing to the href link

Scenario In my current setup with Next.js 13, I am utilizing Apollo Client to manage some client side variables. Objective I aim to trigger the onClick function before navigating to the href location. The Code I'm Using <Link href={`/sess ...

How can I use AJAX to read an image file and display it on a Canvas?

Is there a way to read an image from my server using Ajax and then display it on Canvas? I am aware that this can be achieved by using normal image tags and canvas draw methods, as shown below: <img id="myImage" src="./ColorTable.PNG" style="display:n ...

What is the best way to link validation error messages sent from the server to the appropriate `EditText` on a layout

I received a validation response from the server (generated by symfony2): { "code":400, "message":"Validation Failed", "errors":{ "children":{ "username":{ "errors": [ "This value should not be blank." ] ...

jQuery Refuses to Perform Animation

I'm facing an issue with animating a specific element using jQuery while scrolling down the page. My goal is to change the background color of the element from transparent to black, but so far, my attempts have been unsuccessful. Can someone please pr ...

Implementing location functionality in Nextjs 13+ for both server-side rendering and client-side components

I need help displaying an active link in the header navigation. Previously, I used useRoute() for versions under 13, but it stopped working in version 13 and above. Additionally, useRoute is not mounted when using SSR. To work around this issue, I ensured ...

What causes the immediate firing of the DOM callback in Angular 1.2.9?

Check out a live demo here View the source code on GitHub here Angular 1.2.9 brought in DOM callbacks with the introduction of $animate:before and $animate:after events triggered during animations. However, it seems that the $animate:after event is trigg ...

Understanding the request URL in Ajax when receiving a response

How can the URL of a jQuery request be retrieved from the response received? Perhaps something like this: function retrieveUrlFromResponse(response, url){ requestUrl = url; } ...

Is there a way to transform a regular CommonJS declaration into an ECMAScript import when it is making multiple requires in a single line?

As a beginner in JavaScript, I am interested in converting this line into an import statement: var sass = require('gulp-sass')(require('sass')); I have successfully converted the other requires into imports but I'm struggling wit ...

Communication between nodes using serial ports in Node.js fails to receive a response from the connected Arduino board

I've been attempting to establish communication between a computer and an Arduino board using node.js. Despite having a simple program, it just doesn't seem to work as expected. The Arduino program (which seems to be working fine) is as follows: ...

Enabling Server-Side Control to Halt AJAX Requests in Node.js

After searching through various SO posts, I finally found a solution to make a Node.js server notify a client to stop uploading once a certain file size is reached. The approach proposed by ed-ta in their answer on Avoiding further processing on busyboy fi ...

Transfer all HTML variables using AJAX with jQuery

Is it possible to pass all HTML tag values to another file using AJAX? $.ajax({ url:"myp.php", type:'POST', data: //here I want to include all possible element values in the current HTML document }); Any suggestions or ideas on how to ...