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. linux下安装Tomcat和java jdk

    1:上传jdk的gz文件到linux’系统 2:解压缩这个文件 tar –zxvf  文件名.tar.gz –C  指定目录 比如我这里解压到 /root/apps/jdk tar –zxvf  jd ...

  2. SELECT使用子查询

    SELECT使用子查询   SELECT使用子查询,该子查询会执行多次,  次数是由记录数量决定.效率比较低,不推荐使用.  //查询部门编号,工资大于等于2000的人数,  //工资小于2000的人 ...

  3. Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?

    Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别? 1.什么是Set?(what) Set是Collection容器的一个子接口,它不允许出现 ...

  4. jQuery fadeOut无效

    $(this).fadeOut("fast"), var nowele = $(this); nowele.fadeOut("fast")

  5. C++11时间具体解释

    转载请注明出处:http://blog.csdn.net/luotuo44/article/details/46854229 C++ 11添加了三个与时间相关的类型:时间段.时钟.时间点. 以史为鉴 ...

  6. Nginx系列(四)--工作原理

    上篇文章介绍了Nginx框架的设计之管理进程以及多个工作进程的设计.master进程用来管理通过fork子进程与子进程通信.子进程通过处理进程信号接到master的通信去处理请求. Nginx工作原理 ...

  7. STL 之 iterator traits 备忘

    //5种迭代器.为了激活重载机制,定义的5个类型.每种迭代器就是一个类型. struct input_iterator_tag{}; struct output_iterator_tag{}; str ...

  8. IP地址正則表達式

    正則表達式对字符进行格式化匹配.一句指令完毕推断. IP地址格式   x.x.x.x x 表示0~255的数字 分三种情况 A.          250-255:特点:三位数,百位是2,十位是5,个 ...

  9. 对Shell几个冷知识的总结(IFS,数组,替换,分割,查找)

    IFS: 对IFS的用处直接进行说明,详细IFS是干什么的...自行谷歌 首先创建一个 "a a",和"a"的文件: 然后我们 ls查看一下: --> l ...

  10. ubuntu 搜狗输入法的安装

    本文主要解决的是,通过安装搜狗网站提供的*.deb安装文件,使用ctrl+shift/space无法切换搜狗输入法的问题. 搜狗输入法 for linux:搜狗输入法 for linux,这还不算完: ...