右键菜单contextMenu封装

自己封装的一套右键菜单组件,id必须唯一且一致,不能以数字开头,否则queryselector会报错。

contextmenu.js

import React, { Fragment, useEffect, useMemo } from "react";
import "./contextMenu.less";

//的id必须唯一且一致,id必须以字母开头,如果以数字开头,querySelector会有问题
function ContextMenu(props) {

    const { id, options } = props;

    const handleClick = (ev, onClick) => {
        if (onClick && typeof onClick == "function") {
            onClick(ev);
        };
        if (/^\d+/.test(id)) {
            console.warn("ID should be start with string!");
            return;
        }
        let dom = document.querySelector(`#${id}`);
        if (dom) {
            dom.style.display = "none";
        }
    }

    const renderLi = useMemo(() => {
        return options && options.map((item, index) => {
            const { label, onClick } = item;
            return 
  • handleClick(ev, onClick)}> {label}
  • }) }, [options]); return (
      {renderLi}
    ) } let clickIds = {}; function ContextMenuTrigger(props) { const { children, id } = props; useEffect(() => { if (!clickIds[id]) { document.addEventListener("mousedown", onMouseDown, false); clickIds[id] = 1; } return () => { document.removeEventListener("mousedown", onMouseDown, false); clickIds = {}; } }, []) const onMouseDown = (ev) => { if (/^\d+/.test(id)) { console.warn("ID should be start with string!"); return; } let dom = document.querySelector(`#${id}`); if (dom) { let clientRect = dom.getBoundingClientRect(); const { clientX, clientY } = ev; const { x, y, width, height } = clientRect; if (!(clientX >= x && clientX <= x + width && clientY >= y && clientY <= y + height)) { dom.style.display = "none"; } } } const onContextMenu = (ev) => { if (/^\d+/.test(id)) { console.warn("ID should be start with string!"); return; } let dom = document.querySelector(`#${id}`); if (dom) { dom.style.display = "block"; dom.style.left = ev.clientX + "px"; dom.style.top = ev.clientY + "px"; } ev.preventDefault(); } const newChildren = React.cloneElement(children, { onContextMenu: onContextMenu }); return {newChildren} } ContextMenu.defaultProps = { options: [], } export { ContextMenu, ContextMenuTrigger };

    contextmenu.less

    .contextMenu {
        position        : fixed;
        background-color: white;
        border          : 1px solid #888888;
        box-shadow      : 2px 2px 3px 0px #888888;
        z-index         : 999;
        cursor          : default;
    
        ul {
            li {
                padding: 5px;
    
                &:hover {
                    background-color: #dddddd;
                }
            }
        }
    }

    作者:点墨
    版权:本文版权归作者所有
    转载:欢迎转载,但未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任

    你可能感兴趣的:(右键菜单contextMenu封装)