使用 React JS 的右键菜单

Posted

技术标签:

【中文标题】使用 React JS 的右键菜单【英文标题】:Right Click Menu using React JS 【发布时间】:2015-04-23 06:31:37 【问题描述】:

我想知道是否有最佳实践/正确方法来为 React 组件设置右键菜单。

我现在有这个...

// nw is nw.gui from Node-Webkit
componentWillMount: function() 
    var menu = new nw.Menu();
    menu .append(new nw.MenuItem(
        label: 'doSomething',
        click: function() 
            // doSomething
        
    ));

    // I'd like to know if this bit can be done in a cleaner/more succinct way...
    // BEGIN
    var that = this;
    addEventListener('contextmenu', function(e)
        e.preventDefault();
        // Use the attributes property to uniquely identify this react component 
        // (so different elements can have different right click menus)
        if (e.target.attributes[0].nodeValue == that.getDOMNode().attributes[0].nodeValue) 
            menu.popup(e.x, e.y);
        
    )
    // END
,

这行得通,但感觉有点乱,我想知道是否有另一种方法我可以使用,任何信息将不胜感激,

谢谢!

【问题讨论】:

看看这个article,我想对你有帮助。 @pabolmiranda 非常感谢,之前没看过这篇文章。我发现了这个视频 (youtube.com/watch?v=ecc0JopiZe4),它包含有关 node-webkit 的信息,但与 React 没有任何关系。我只是不知道是否有更好的方法。我想我可以使用一个唯一的 id 和一个 div 来引用这个项目,这可能会稍微干净一些,我不确定。不过谢谢! 【参考方案1】:

更新:

想通了——这就是你可以做的事情

var addMenu;

componentWillMount: function() 
    addMenu = new nw.Menu();
    addMenu.append(new nw.MenuItem(
        label: 'doSomething',
        click: function() 
            // doSomething
        
    ));
,

contextMenu: function(e) 
    e.preventDefault();
    addMenu.popup(e.clientX, e.clientY);
,

render: function()
    return <button onClick=this.handleClick onContextMenu=this.contextMenu>SomethingUseful</button>

在渲染中,您可以将一个函数传递给 onContextMenu,以便在此反应组件发生右键单击时。

【讨论】:

能否添加 JSFiddle 示例? 嘿,这里有一些可能有用的东西 - (jsfiddle.net/q09xkja9/3) 我正在使用的右键菜单 (addMenu = new nw.Menu()) 来自提供访问权限的 Node-Webkit到本地菜单。希望这个例子能给你一个想法! @Tom 这个 JSFiddle 应该可以工作吗?我所看到的只是一个应该发生输出/点击事件的白色区域。 @kojow7 恐怕自从我看到这个以来已经很久了,我不知道我在 2015 年尝试过的方法是否仍然有效? 很抱歉没有提供更多帮助! @kojow7 这是一个更新的小提琴:jsfiddle.net/ejtkn8x1(必须将“语言”设置从“使用 jQuery”切换到“使用 JSX 的 Babel”)【参考方案2】:

弹出式菜单需要注意的事项很少:

    它应该远离其父级和兄弟级呈现 - 最好在作为 document.body 的最后一个子级的叠加层中 特殊逻辑应注意它始终显示在屏幕上,并且不会被屏幕边缘裁剪 如果涉及层次结构,则子弹出窗口应与上一个弹出窗口(开启器)中的项目对齐。

我创建了一个库,您可以使用它来完成所有这些:

http://dkozar.github.io/react-data-menu/

【讨论】:

【参考方案3】:

在使用 Material UI 时,我也在寻找解决方案,所以您要做的是首先禁用浏览器在右键单击时的默认行为,然后添加您想要的菜单,这是工作代码:

import React from 'react';
import  withStyles  from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import InboxIcon from '@material-ui/icons/MoveToInbox';
import DraftsIcon from '@material-ui/icons/Drafts';
import SendIcon from '@material-ui/icons/Send';

const StyledMenu = withStyles(
  paper: 
    border: '1px solid #d3d4d5',
  ,
)((props) => (
  <Menu
    elevation=0
    getContentAnchorEl=null
    anchorOrigin=
      vertical: 'bottom',
      horizontal: 'center',
    
    transformOrigin=
      vertical: 'top',
      horizontal: 'center',
    
    ...props
  />
));

const StyledMenuItem = withStyles((theme) => (
  root: 
    '&:focus': 
      backgroundColor: theme.palette.primary.main,
      '& .MuiListItemIcon-root, & .MuiListItemText-primary': 
        color: theme.palette.common.white,
      ,
    ,
  ,
))(MenuItem);

export default function CustomizedMenus() 
  const [anchorEl, setAnchorEl] = React.useState(null);

  const handleClick = (event) => 
    event.preventDefault();
    setAnchorEl(event.currentTarget);
  ;

  const handleClose = () => 
    setAnchorEl(null);
  ;

  return (
    <div>
      <Button
        aria-controls="customized-menu"
        aria-haspopup="true"
        variant="contained"
        color="primary"
        onContextMenu=handleClick
      >
        Open Menu
      </Button>
      <StyledMenu
        id="customized-menu"
        anchorEl=anchorEl
        keepMounted
        open=Boolean(anchorEl)
        onClose=handleClose
      >
        <StyledMenuItem>
          <ListItemIcon>
            <SendIcon fontSize="small" />
          </ListItemIcon>
          <ListItemText primary="Sent mail" />
        </StyledMenuItem>
        <StyledMenuItem>
          <ListItemIcon>
            <DraftsIcon fontSize="small" />
          </ListItemIcon>
          <ListItemText primary="Drafts" />
        </StyledMenuItem>
        <StyledMenuItem>
          <ListItemIcon>
            <InboxIcon fontSize="small" />
          </ListItemIcon>
          <ListItemText primary="Inbox" />
        </StyledMenuItem>
      </StyledMenu>
    </div>
  );

还有sandbox project

【讨论】:

以上是关于使用 React JS 的右键菜单的主要内容,如果未能解决你的问题,请参考以下文章

webview 的右键菜单

用JS自制表格软件玩数据8. 设计单元格中的右键菜单

用JS自制表格软件玩数据8. 设计单元格中的右键菜单

js模拟点击鼠标右键

Adobe air(HTML + JS)阻止图像,输入和文本区域的右键单击事件

如使用原生js自定义右键菜单