如何让Tippy组件内的HTML元素可点击?文件分享应用右键菜单问题
解决Tippy.js右键菜单无法点击的问题
针对你遇到的右键菜单正常显示但无法点击选项的问题,可从以下几个方向排查修复:
1. 开启Tippy的交互权限
Headless模式的Tippy默认不允许弹窗内交互,需要显式添加interactive属性:
<Tippy allowHTML visible={visible} onClickOutside={() => setVisible(false)} render={() => <Options onClose={() => setVisible(false)} />} followCursor="initial" placement="right-start" plugins={[followCursor]} interactive={true} // 关键:允许弹窗内元素接收交互 interactiveBorder={10} // 可选:扩大交互判定范围,避免边缘点击误触发outside事件 > {child} </Tippy>
2. 修正右键菜单的显示逻辑
原代码用setVisible(!visible)切换状态,容易导致状态混乱(比如菜单已显示时右键点击会关闭而非更新位置),改为直接设置为true:
const child = cloneElement(children, { onContextMenu: (e: React.MouseEvent) => { e.preventDefault(); setVisible(true); // 右键点击直接显示菜单,关闭逻辑交给onClickOutside处理 }, })
3. 给菜单选项绑定关闭逻辑
需要将关闭菜单的方法传递给Options组件,确保点击选项后能正常关闭弹窗并执行对应操作:
修改SubMenu的render逻辑:
render={() => <Options onClose={() => setVisible(false)} />}
在Options组件中接收并使用onClose:
// Options.tsx type OptionsProps = { onClose: () => void } const Options = ({ onClose }: OptionsProps) => { const handleDelete = () => { // 执行删除逻辑 console.log("执行删除操作"); onClose(); // 操作完成后关闭菜单 } const handleShare = () => { // 执行分享逻辑 console.log("执行分享操作"); onClose(); } return ( <div className="context-menu"> <button onClick={handleDelete}>删除文件</button> <button onClick={handleShare}>分享文件</button> </div> ) } export default Options
4. 排查CSS影响
检查菜单元素的CSS是否设置了pointer-events: none,这个属性会完全阻止点击事件,确保菜单及其子元素的pointer-events为默认的auto:
.context-menu, .context-menu button { pointer-events: auto; }
5. 测试followCursor插件影响
如果以上步骤无效,可暂时移除followCursor插件测试:
<Tippy allowHTML visible={visible} onClickOutside={() => setVisible(false)} render={() => <Options onClose={() => setVisible(false)} />} placement="right-start" interactive={true} > {child} </Tippy>
若移除后点击正常,说明插件与交互存在冲突,可尝试调整followCursor的配置(比如改为"horizontal"或"vertical"),或自定义光标跟随逻辑。
内容的提问来源于stack exchange,提问作者Hưng Lâm
相关产品推荐
相关产品推荐

