Home > Mobile >  Problems displaying new div when onMouseOver event fires
Problems displaying new div when onMouseOver event fires

Time:01-22

I've made a CSS grid displaying a <p>{name}</p> element on each grid item. When an onMouseOver hover events I want to display a new div (contained within the react fragment), but in the same position.
Instead of using CSS, I've used JavaScript to code the logic for this - when a user hovers on the grid item, it flips a boolean (saved as state variable isMouseHovering) from false to true. I have a conditional statement that displays the 'new' div, when this state value is truthy.

The problem is that this logic applies for grid item container element, and not for the elements inside the grid container. So when I over over grid, it does what it's supposed to do and displays the new div. However when I hover over the p-tag within the grid item container element, it flickers between states.

How do I structure this so that the div changes on hover, no matter where on the grid item the user hovers the mouse?

Project.js

import { useState } from 'react'

const Project = ({name,url,techStack,image,blurb}) => {

  const [isMouseHovering, setMouseHovering] = useState(false);

  const handleOnMouseOver = () => setMouseHovering((isMouseHovering) => !isMouseHovering);  
  const handleMouseOut = () =>  setMouseHovering(false);
  
  return(
    <div className = 'grid-item' onm ouseOver={handleOnMouseOver} onm ouseOut = {handleMouseOut}>
      {
        isMouseHovering ? (
        // element I want to display when mouse hovering, in same position as <p>{name}</p> element
        <>
          <a href='https://xxxxxxxxxxxxxxxx'>
            <p>website</p>
          </a>
        </>
        )
        : 
        <p>{name}</p>
      }
    </div>
  )
}


export default Project

CodePudding user response:

The issue is you're using onm ouseOver and onm ouseOut instead of onm ouseEnter and onm ouseLeave.

onMouseOut will trigger when you hover over a children of the element you are in causing the bug you're describing.

Also you're toggling the state in your handleMouseOver function but from what I understood you want it to be set to true when you hover the div.

import { useState } from 'react';
const Project = ({ name, url, techStack, image, blurb }) => {
    const [isMouseHovering, setMouseHovering] = useState(false);

    const handleMouseEnter = () => setMouseHovering(true);
    const handleMouseLeave = () => setMouseHovering(false);

    return (
        <div
            className="grid-item"
            onm ouseEnter={handleMouseEnter}
            onm ouseLeave={handleMouseLeave}
        >
            {isMouseHovering ? (
                // element I want to display when mouse hovering, in same position as <p>{name}</p> element
                <>
                    <a href="https://xxxxxxxxxxxxxxxx">
                        <p>website</p>
                    </a>
                </>
            ) : (
                <p>{name}</p>
            )}
        </div>
    );
};

export default Project;

https://developer.mozilla.org/en-US/docs/Web/API/Element/mouseenter_event

CodePudding user response:

Try this:

import { useState } from 'react'

  const Project = ({name,url,techStack,image,blurb}) => {
    const handleOnMouseOver = (dir) => {
      const ele = document.getElementById('dev_span');
      if (dir === 'in' && ele) {
        ele.style.display = 'block';
      } else if (ele) {
        ele.style.display = 'none';
      }
    };
    return(
        <div
            className="grid-item"
            onm ouseEnter={() => handleOnMouseOver('in')}
            onm ouseLeave={() => handleOnMouseOver('out')}
        >
        <span id="dev_span" style={{ display: 'none' }}>
          <a href="https://xxxxxxxxxxxxxxxx">
            <p>website</p>
          </a>
        </span>
          <p>{name}</p>
        </div>
    )
  }

CodePudding user response:

You can check for the element that is trigger the event.

import { useState } from "react";

const Project = ({ name, url, techStack, image, blurb }) => {
  const [isMouseHovering, setMouseHovering] = useState(false);

  const handleOnMouseOver = (e) => {
    if (e.target.className === "grid-item") {
      setMouseHovering((isMouseHovering) => !isMouseHovering);
    }
  };

  const handleMouseOut = () => setMouseHovering(false);

  return (
    <div
      className="grid-item"
      onm ouseOver={(e) => handleOnMouseOver(e)}
      onm ouseOut={handleMouseOut}
    >
      {isMouseHovering ? (
        // element I want to display when mouse hovering, in same position as <p>{name}</p> element
        <>
          <a href="https://xxxxxxxxxxxxxxxx">
            <p>website</p>
          </a>
        </>
      ) : (
        <p>{name}</p>
      )}
    </div>
  );
};

export default Project;
  •  Tags:  
  • Related