如何防止onmouseleave事件在浏览器外被触发?



我在下面做了一个小小的尝试。当我将鼠标放入篮子内时,会出现一个带按钮的下拉框。当我们点击按钮时,出现一个模态。我希望模态关闭只有当关闭模态按钮被点击。但是当我们把鼠标移出浏览器时,hideDropdown函数被触发,模态关闭。我将hideDropdown函数作为道具发送给其模态状态更新的组件,但这次只有hideDropdown函数工作,isModalShow状态没有更新。我该如何解决这个问题?

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

这是棘手的,但我终于得到了它。您必须像下面这样添加函数。副作用是打开模态按钮有时会切换,但如果你抬起模态,因为它取决于下拉菜单,我猜或者简单地使用CSS来实现,这将更容易。

但是回到onMouseleave的主要问题,你可以这样做。这基本上是检查浏览器的边界。添加了10而不是0,因为滚动条在某种程度上干扰了事件的触发。因此,作为保护措施添加。

同时,用onMouseOver代替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>

这是沙盒链接

你可以试着从isDropdownShow属性中取消模式的链接,这样它就可以只切换按钮OpenModal和CloseModal…只是一个变通

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>
);
}

基本的解决方案是检查用户是否在窗口与window。下面是工作代码和示例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>
);
}

最新更新