案例样式

React 代码
import React from 'react'
import c from 'classnames'
import s from './test.module.styl'
class Test 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={c('hand', s.continer)}>
<div className={c('fbh', s.option)}><div className={c('fb1')}>前进</div><div>➡️</div></div>
<div className={s.option}>后退</div>
<div className={s.option}>重新加载</div>
<div className={s.group}>
<div className={c('opcity10', s.option, s.disable)}>删除</div>
<div className={s.option}>复制</div>
<div className={s.option}>移动(Space Bar)</div>
<div className={s.option}>缩放(⌥)</div>
</div>
<div className={s.option}>基本配置</div>
<div className={s.option}>属性</div>
</div>
)
}
}
export default Test
stylus代码
.continer
position fixed
background rgba(45,45,45,.9)
border-radius 3px
padding 8px 0
box-shadow 0 0 15px rgba(0,0,0,.1)
.option
min-width 200px
padding 4px 14px
&:hover
background rgb(20,20,20)
.disable
color #999
cursor default
&:hover
background none
.group
border-bottom 1px solid rgb(60,60,60)
border-top 1px solid rgb(60,60,60)