思路:阻止默认事件,展示自定义选项。
react实例
import { useState, useEffect, useRef } from "react"
export default () => {
const [menuVisible, setMenuVisible] = useState(false)
const [menuPosition, setMenuPosition] = useState({ x: 0, y: 0 })
const menuRef = useRef(null)
const handleContextMenu = (event) => {
event.preventDefault()
setMenuPosition({ x: event.clientX, y: event.clientY })
setMenuVisible(true)
}
const handleClick = () => {
setMenuVisible(false)
}
useEffect(() => {
document.addEventListener("click", handleClick)
return () => {
document.removeEventListener("click", handleClick)
}
}, [])
const appStyles = {
fontFamily: "sans-serif",
textAlign: "center",
height: "100vh",
display: "flex",
justifyContent: "center",
alignItems: "center",
backgroundColor: "#f0f0f0",
}
const contextMenuStyles = {
position: "absolute",
backgroundColor: "white",
border: "1px solid #ccc",
boxShadow: "0 2px 5px rgba(0, 0, 0, 0.2)",
zIndex: 1000,
padding: "10px 0",
}
const listItemStyles = {
padding: "8px 16px",
cursor: "pointer",
}
const listItemHoverStyles = {
backgroundColor: "#f0f0f0",
}
return (
<div className="App" onContextMenu={handleContextMenu} style={appStyles}>
<h1>右键点击任意位置显示自定义菜单</h1>
{menuVisible && (
<div
ref={menuRef}
className="context-menu"
style={{
...contextMenuStyles,
top: menuPosition.y,
left: menuPosition.x,
}}
>
<ul style={{ margin: 0, padding: 0, listStyleType: "none" }}>
<li
onClick={() => alert("选项 1")}
style={listItemStyles}
onMouseEnter={(e) =>
(e.target.style.backgroundColor =
listItemHoverStyles.backgroundColor)
}
onMouseLeave={(e) => (e.target.style.backgroundColor = "white")}
>
选项 1
</li>
<li
onClick={() => alert("选项 2")}
style={listItemStyles}
onMouseEnter={(e) =>
(e.target.style.backgroundColor =
listItemHoverStyles.backgroundColor)
}
onMouseLeave={(e) => (e.target.style.backgroundColor = "white")}
>
选项 2
</li>
<li
onClick={() => alert("选项 3")}
style={listItemStyles}
onMouseEnter={(e) =>
(e.target.style.backgroundColor =
listItemHoverStyles.backgroundColor)
}
onMouseLeave={(e) => (e.target.style.backgroundColor = "white")}
>
选项 3
</li>
</ul>
</div>
)}
</div>
)
}