1.在HTML里面支持contextmenu事件(右键事件)。所以需要在组建加载完时添加此事件,销毁组建时移除此事件。

2. 需要增加一个state,名称为visible,用来控制菜单是否显示。在_handleContextMenu(右键事件)里面,它被设置为true,从而可以显示出来。那么,当鼠标点击其它位置或者滚动的时候,需要把 它设置为false。

例如代码:

class ContextMenu extends React.Component {
        constructor(props) {
               super(props);
               this.state = {
                   visible: false,
               };
         }

componentDidMount() {
             document.addEventListener('contextmenu', this._handleContextMenu);
             document.addEventListener('click', this._handleClick);
             document.addEventListener('scroll', this._handleScroll);
        };

componentWillUnmount() {
           document.removeEventListener('contextmenu', this._handleContextMenu);
           document.removeEventListener('click', this._handleClick);
           document.removeEventListener('scroll', this._handleScroll);
       }

_handleContextMenu = (event) => {

// this.setState({ visible:false });//当点击其他地方右键时可以根据需求来判断是否需要先关闭菜单
            event.preventDefault();

this.setState({ visible: true });

const clickX = event.clientX;
            const clickY = event.clientY;               //事件发生时鼠标的Y坐标
            const screenW = window.innerWidth;   //文档显示区的宽度
            const screenH = window.innerHeight;
            const rootW = this.root.offsetWidth;     //右键菜单本身元素的宽度
            const rootH = this.root.offsetHeight;

// right为true,说明鼠标点击的位置到浏览器的右边界的宽度可以放contextmenu。

// 否则,菜单放到左边。 // top和bottom,同理。

const right = (screenW - clickX) > rootW;
            const left = !right;
            const top = (screenH - clickY) > rootH;
            const bottom = !top;

if (right) {
                this.root.style.left = `${clickX + 15}px`;
             }

if (left) {
                  this.root.style.left = `${clickX - rootW - 15}px`;
            }

if (top) {
                this.root.style.top = `${clickY + 15}px`;
            }

if (bottom) {
                this.root.style.top = `${clickY - rootH - 15}px`;
             }
      };

_handleClick = (event) => {
             const { visible } = this.state;
             const wasOutside = !(event.target.contains === this.root);

if (wasOutside && visible) this.setState({ visible: false, });
      };

_handleScroll = () => {
             const { visible } = this.state;

if (visible) this.setState({ visible: false, });
        };

render() {
         const { visible } = this.state;

return

{ visible?
             <div ref={ref => {this.root = ref}} className="contextMenu">
                 <div>右键菜单内容</div>
          </div>: null}
    };
}

ReactDOM.render(<ContextMenu />, document.getElementById('root'));

react添加右键点击事件的更多相关文章

  1. 给ECharts添加右键点击事件,实现右键功能菜单

    由于项目的需要,使用ECharts 的力导向图来实现 整个EDW数据架构的血缘分析,由于ECharts并没有给组件定义有右键的事件,同时ECharts是开源的项目,所以研究了下源码,将ECharts2 ...

  2. 后台找到repeater里面的div并添加客户端点击事件

    public partial class Inv_SelectWorkservice : System.Web.UI.Page,IPostBackEventHandler{ } 通过OnItemCre ...

  3. 【读书笔记】iOS-storyBoard-为一个按钮添加一个点击事件

    按照故事板的用语,应用中的一个界面屏幕被称作一个”场景(Scene)",以后添加额外的场景时,停靠区中将有另一个部分. 一,新建立一个工程,如图所示. 二,选中Main.storyboard ...

  4. Echarts如何添加鼠标点击事件?防止重复触发点击事件

    Echarts如何添加鼠标点击事件? 1.通常我们只使用了以下代码,通过配置项和数据显示图表. var myChart = echarts.init(document.getElementById(' ...

  5. Android 高级UI设计笔记20:RecyclerView 的详解之RecyclerView添加Item点击事件

    1. 引言: RecyclerView侧重的是布局的灵活性,虽说可以替代ListView但是连基本的点击事件都没有,这篇文章就来详细讲解如何为RecyclerView的item添加点击事件,顺便复习一 ...

  6. angular5 自定义指令 输入输出 @Input @Output(右键点击事件传递)

    指令写法,angular5官网文档给的很详细. 首先要创建一个文件,需注意命名规范(后缀名为xxx.directive.ts): 今天要记录的是在多个li中,右键点击之后显示出对应的菜单,直接上图吧! ...

  7. jQuery添加options点击事件并传值

    说明: 根据选择不同店铺选项,上送不同id值,展示不同商品列表   var formStr = "{'supplierId':'供应链企业|%-jm-sprt-%|93794498-3'}& ...

  8. RecyclerView添加条目点击事件setOnItemClickListener,不是在Adapter中设置;

    RecyclerView不像ListView,可以直接写setOnItemClickListener,我们大部分都是在Adapter中的设置点击事件,这个是使用RecyclerView的addOnIt ...

  9. html 获取鼠标左键事件,滚轮点击事件,右键点击事件

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

随机推荐

  1. anshi

    env.js主要是帮助我们读取根目录下以.env开头的环境变量,并判断是否生效. 比如在根目录下创建一个.env.local文件 改写一个环境变量 而没有改之前,它是在3000端口打开 path.js ...

  2. 算法21----重塑矩阵 LeetCode566

    1.题目 在MATLAB中,有一个非常有用的函数 reshape,它可以将一个矩阵重塑为另一个大小不同的新矩阵,但保留其原始数据. 给出一个由二维数组表示的矩阵,以及两个正整数r和c,分别表示想要的重 ...

  3. BZOJ 1176/2683 Mokia (三维偏序CDQ+树状数组)

    题目大意: 洛谷传送门 三维偏序裸题.. 每次操作都看成一个三元组$<x,y,t>$,表示$x,y$坐标和操作时间$t $ 询问操作拆成$4$个容斥 接下来就是$CDQ$了,外层按t排序, ...

  4. [USACO17FEB] Why Did the Cow Cross the Road I P (树状数组求逆序对 易错题)

    题目大意:给你两个序列,可以序列进行若干次旋转操作(两个都可以转),对两个序列相同权值的地方连边,求最少的交点数 记录某个值在第一个序列的位置,再记录第二个序列中某个值 在第一个序列出现的位置 ,求逆 ...

  5. NOI 2011 阿狸的打字机 (AC自动机+dfs序+树状数组)

    题目大意:略(太长了不好描述) 良心LOJ传送门 先对所有被打印的字符串建一颗Trie树 观察数据范围,并不能每次打印都从头到尾暴力建树,而是每遍历到一个字符就在Trie上插入这个字符,然后记录每次打 ...

  6. poj 3254 Corn Fields (状压dp)(棋盘dp)

    状压dp入门题 因为当前行的状态只和上一行有关 所以可以一行一行来做 因为m <= 12所以可以用二进制来表示放了或者没有放 0表示没放,1表示放 f[i][state]表示第i行状态为stat ...

  7. 【Codeforces Round #476 (Div. 2) [Thanks, Telegram!] E】Short Code

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 先建立一棵字典树. 显然,某一些节点上会被打上标记. 问题就转化成求所有标记的深度的和的最小值了. (标记可以上移,但是不能在同一位 ...

  8. 高级函数-case

    case函数 (适合区间,>,<判断)    case when 判断表达式 then         when 判断表达式 then         .....    end     s ...

  9. Mybatis动态代理实现函数调用

    如果我们要使用MyBatis进行数据库操作的话,大致要做两件事情: 1. 定义DAO接口 在DAO接口中定义需要进行的数据库操作. 2. 创建映射文件 当有了DAO接口后,还需要为该接口创建映射文件. ...

  10. NYIST 677 碟战

    碟战时间限制:2000 ms | 内存限制:65535 KB难度:4 描述知己知彼,百战不殆!在战争中如果被敌人掌握了自己的机密,失败是必然的.K国在一场战争中屡屡失败,就想到自己的某些城市可能会有敌 ...