Issue
I am trying to add a modal that shows up with a delay when hovering over a div. However, it's getting a bit tricky because, for example, if the timeout interval is 1000ms, and you hover over said div and then hover away from that div within the 1000ms, the modal will still show up. What I want to happen is for the modal to show up after the delay (e.g. 1000ms) only if you have maintained mouseover over the div for that delay period. How can I create this effect instead of the side effects I'm seeing now? Thanks!
index.tsx:
import * as React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
const Modal: React.FC = () => {
const divRef = React.useRef<HTMLDivElement>(null);
const [showModal, setShowModal] = React.useState<boolean>(false);
React.useEffect(() => {
const divNode = divRef.current;
const handleEvent = (event: Event): void => {
if (divNode) {
if (divNode.contains(event.target as Node)) {
setTimeout(() => setShowModal(true), 1000);
} else {
setShowModal(false);
}
}
};
document.addEventListener("mouseover", handleEvent);
return () => {
document.removeEventListener("mouseover", handleEvent);
};
}, [divRef]);
return (
<div className="container">
<div className="div" ref={divRef}>
Hover Me
</div>
{showModal && <div className="modal">modal</div>}
</div>
);
};
const App: React.FC = () => (
<>
<Modal />
<Modal />
<Modal />
<Modal />
</>
);
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Solution
You should add a mouse out event that will hide the modal.
Call a funtion on 'mouseout' event listener and set the showModal to false. In that way, it will hide the modal if you move your mouse any time.
setShowModal(false)
Updated: Can you also set timeout to a variable and then on mouseout fire clearTimeout(variable_that_set_to_timeout)
React.useEffect(() => {
const divNode = divRef.current;
let timeout = null;
const handleEvent = (event: Event): void => {
if (divNode) {
if (divNode.contains(event.target as Node)) {
timeout = setTimeout(() => setShowModal(true), 1000);
} else {
setShowModal(false);
}
}
};
const hideModal = (event: Event): void => {
clearTimeout(timeout);
setShowModal(false);
};
divNode.addEventListener("mouseover", handleEvent);
divNode.addEventListener("mouseout", hideModal);
return () => {
document.removeEventListener("mouseover", handleEvent);
};
}, [divRef]);
Answered By - Niloy
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.