React 例子

来源:互联网 发布:电脑监控软件 编辑:程序博客网 时间:2024/06/05 10:07

代码并非原创,忘了从哪里找到的,如有人知道,可博客留言。
效果点击链接:
https://codepen.io/Anyicheng2015/pen/jaayMw

首先,你要对React有点了解。其次,你要明白HTML的事件处理机制。

我先贴代码的框架,然后逐步完善。

class ContextMenu extends React.Component {    constructor(props) {        super(props);    }      componentDidMount() {    }    componentWillUnmount() {    }    render() {    }}ReactDOM.render(<ContextMenu />, document.getElementById('root'));

鼠标右击事件,通常的‘click’事件是针对鼠标左键,mousedown是鼠标左键和右键及中间键都可以。那么有没有鼠标右键的事件呢?
有的,在HTML里面支持contextmenu事件。
https://developer.mozilla.org/en-US/docs/Web/Events/contextmenu
添加contextmenu事件处理:

document.addEventListener('contextmenu', this._handleContextMenu);

当然也需要移除:

document.removeEventListener('contextmenu', this._handleContextMenu);

当鼠标点到其它地方,或者滚动的时候,不要显示右键菜单,需要添加其他事件。反应到代码上面:

    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) => {        event.preventDefault();        this.setState({ visible: true });        const clickX = event.clientX;        const clickY = event.clientY;        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 + 5}px`;        }        if (left) {            this.root.style.left = `${clickX - rootW - 5}px`;        }        if (top) {            this.root.style.top = `${clickY + 5}px`;        }        if (bottom) {            this.root.style.top = `${clickY - rootH - 5}px`;        }    };

从上面的代码中,我们看到,需要增加一个state,名称为visible,用来控制菜单是否显示。在_handleContextMenu里面,它被设置为true,从而可以显示出来。那么,当鼠标点击其它位置或者滚动的时候,需要把它设置为false。

    _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, });    };

最后,右键菜单 context menu 的内容:

    render() {        const { visible } = this.state;        return(visible || null) &&             <div ref={ref => {this.root = ref}} className="contextMenu">                <div className="contextMenu--option">Share this</div>                <div className="contextMenu--option">New window</div>                <div className="contextMenu--option">Visit official site</div>                <div className="contextMenu--option contextMenu--option__disabled">View full version</div>                <div className="contextMenu--option">Settings</div>                <div className="contextMenu--separator" />                <div className="contextMenu--option">About this app</div>            </div>    };

完整代码:

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) => {        event.preventDefault();        this.setState({ visible: true });        const clickX = event.clientX;        const clickY = event.clientY;        const screenW = window.innerWidth;        const screenH = window.innerHeight;        const rootW = this.root.offsetWidth;        const rootH = this.root.offsetHeight;        const right = (screenW - clickX) > rootW;        const left = !right;        const top = (screenH - clickY) > rootH;        const bottom = !top;        if (right) {            this.root.style.left = `${clickX + 5}px`;        }        if (left) {            this.root.style.left = `${clickX - rootW - 5}px`;        }        if (top) {            this.root.style.top = `${clickY + 5}px`;        }        if (bottom) {            this.root.style.top = `${clickY - rootH - 5}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 || null) &&             <div ref={ref => {this.root = ref}} className="contextMenu">                <div className="contextMenu--option">Share this</div>                <div className="contextMenu--option">New window</div>                <div className="contextMenu--option">Visit official site</div>                <div className="contextMenu--option contextMenu--option__disabled">View full version</div>                <div className="contextMenu--option">Settings</div>                <div className="contextMenu--separator" />                <div className="contextMenu--option">About this app</div>            </div>    };}ReactDOM.render(<ContextMenu />, document.getElementById('root'));
原创粉丝点击