简体   繁体   中英

How to prevent the onmouseleave event from being triggered outside the browser?

I have a little try below. When i enter the mouse inside of the basket, a dropdown with a button appears. When we click the button a modal appears.I want the modal to close only when the close modal button is clicked. But when we take the mouse out of the browser the hideDropdown function is triggered and the modal closes. I sent the hideDropdown function as a prop to the component whose Modal state was updated, but this time only the hideDropdown function worked and the isModalShow state was not updated. How can i solve this?

Demo: https://codesandbox.io/s/jolly-buck-1lgmiu

This was tricky but i finally got it. You have to add the functions like below. The side effect is the open modal button will toggle sometime but that can be changed if you lift up the modal as it depends on the dropdown, I guess or implement simply using CSS instead which would be much easier.

But coming to your main question for onMouseleave you can do like following. This is basically checking the boundaries of the browser. Added 10 instead of 0 because the scrollbar was somehow messing with the event firing in codepen. So, added as a safeguard.

Also, used onMouseOver instead of onMouseEnter .

 const hideDropdown = (event) => {
    if (
      event.clientY <= 10 ||
      event.clientX <= 10 ||
      event.clientX >= window.innerWidth - 10 ||
      event.clientY >= window.innerHeight - 10
    ) {
      console.log("I'm out");
      return;
    } 
    setIsDropdownShow(false);
  };

  return (
    <div className="App" onMouseOver={showDropdown} onMouseLeave={hideDropdown}>
      <span className="basket">Basket</span>
      {isDropdownShow && <Dropdown hideDropdown={hideDropdown} />}
    </div>

Here is the sandboxlink

Can you try to unlink the Modal from the isDropdownShow property so that it can be toggled only the button OpenModal and CloseModal... Just a workaround

import "./styles.css";
import Dropdown from "./Dropdown";
import { useState } from "react";

export default function App() {
  const [isDropdownShow, setIsDropdownShow] = useState(false);
  const [isModalShow, setIsModalShow] = useState(false);
  
  const showDropdown = () => {
    setIsDropdownShow(true);
  };

const showModal = () => {
    setIsModalShow(true);
  };
const hideModal = () => {
    setIsModalShow(false);
  };

  const hideDropdown = () => {
    setIsDropdownShow(false);
  };

  return (
    <div
      className="App"
      
    >
  <div
      onMouseEnter={showDropdown}
      onMouseLeave={hideDropdown}>
      <span 
      
      className="basket">Basket</span>
      {isDropdownShow && <button onClick={()=>showModal}> Open 
     Modal<button/>}
  </div>
      <Dropdown hideModal={hideModal} IsModalShow={IsModalShow} />
    </div>
  );
}

Basic solution would be checking if user in window or not with window . Here is the working codesandbox sample https://codesandbox.io/embed/heuristic-pasteur-u4cd5e?fontsize=14&hidenavigation=1&theme=dark

import "./styles.css";
import Dropdown from "./Dropdown";
import { useState } from "react";

export default function App() {
  const [isDropdownShow, setIsDropdownShow] = useState(false);

  const showDropdown = () => {
    setIsDropdownShow(true);
  };

  const hideDropdown = (event) => {
    if( typeof window !== "undefined" &&
         window.document &&
         window.document.createElement ){
      return;
    }
    setIsDropdownShow(false);
  };

  return (
    <div
      className="App"
      onMouseEnter={showDropdown}
      onMouseLeave={hideDropdown}
    >
      <span className="basket">Basket</span>
      {isDropdownShow && <Dropdown hideDropdown={hideDropdown} />}
    </div>
  );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM