react 按下鼠标移动监听不到onMouseMove事件,松开时也监听不到onMouseUp

<img alt="" src={Url}
  onMouseDown={handleMouseDown}
  onMouseMove={handleMouseMove}
  onMouseUp={handleMouseUp}
/>

事件

  let flag = false
  const handleMouseDown = () => {
    flag = true
    console.log('down')
  }
  const handleMouseMove = () => {
    if (flag) {
      console.log('move')
    }
  }
  const handleMouseUp = () => {
    console.log('up')
    flag = false
  }

想要实现从图片中选取一个区域,当按下鼠标时可以监听到,按着移动和松开都监听不到。在原地按下松开可以监听到。
请大家帮忙看看

import React from 'react'
import PropTypes from 'prop-types'
import styles from './Poster.less'

class PosterDemo extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
    }
  }

  handleMouseDown = (event) => {
    let target = event.target
    console.log('down')
    document.onmousemove = () => {
      event.preventDefault()
      console.log('move')
    }
    target.onmouseup = () => {
      console.log('up')
      document.onmousemove = null
      target.onmouseup = null
    }
  }

  render () {
    return (
      <div className={styles.posterDemo}>
        <div id="phone" className={styles.phone}>
          <div className={styles.Content}>
            <div className={styles.Image}>
              <img id="poster" alt="" src={this.props.url}
                onMouseDown={(e) => this.handleMouseDown(e)}
              />
            </div>
          </div>
        </div>
      </div>
    )
  }
}

PosterDemo.propTypes = {
  url: PropTypes.string,
}

export default PosterDemo
阅读 10.2k
3 个回答

首先onmousemove的对象应该是document,其次onMouseMove和onMouseUp应该都是写在onMouseDown里面的
给你个拖拽的小例子吧,大致原理一样的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
    <script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
    <title>Document</title>
    <style>
        .box{
            width:100px;
            height:100px;
            background: #000;
            position: absolute;
        }
    </style>
</head>
<body>
    <div class="ccc"></div>
    <script type="text/babel">
        class Box extends React.Component{
            constructor(props){
               super(props);         
            }
            mousedown(event){
                var target = event.target;
                var disX = event.pageX - target.offsetLeft;
                var disY = event.pageY - target.offsetTop;
                var W = this.props.w-target.offsetWidth;
                var H = this.props.h-target.offsetHeight;
                document.onmousemove = function(event){
                    event.preventDefault();
                    var l = event.pageX - disX;
                    var t = event.pageY - disY;
                    if(l<0){
                        l = 0;
                    }
                    if(l>W){
                        l = W ;
                    }
                    if(t<0){
                        t = 0;
                    }
                    if(t>H){
                        t = H;
                    }
                    target.style.top = t+ 'px';
                    target.style.left = l+'px';
                }
                target.onmouseup = function(){
                    document.onmousemove = null;
                    target.onmouseup = null;
                }
            }
            render(){
                return <div className="box" onMouseDown={(e)=>this.mousedown(e)}></div>
            }
        }
        ReactDOM.render(
            <Box h={document.documentElement.clientHeight} w={document.documentElement.clientWidth}/>,
            document.querySelector('.ccc')
        )
    </script>
</body>
</html>
新手上路,请多包涵

我的解决方法是在div中监听mousedown和mouseup和mouseleave事件,在触发mouseleave后直接绑定mouseup事件,这样就可以解决当鼠标离开元素后不触发mouseup事件的问题

startDrug = e => {

e.stopPropagation();

e.preventDefault();

const left = e.clientX;

this.setState({ initLeft: left });

document.onmousemove = this.moveDrug.bind(this);

};

moveDrug = e => {

e.stopPropagation();

e.preventDefault();

const { initLeft, moveLeft } = this.state;

const data = this.renderTimeSelect();

const move = e.clientX;

const moveLength = move - initLeft;

const tmp = moveLeft + moveLength;

const labelIndex = Math.floor(tmp / 3.64);

const showLabel = this.timeFormat(data[labelIndex]);

this.setState({ moveLength, activeKey: labelIndex, showLabel });

};

upDrug = e => {

e.stopPropagation();

e.preventDefault();

const { moveLeft, moveLength, activeKey } = this.state;

const tmp = moveLeft + moveLength;

this.setState({ moveLeft: tmp });

document.onmousemove = null;

const data = this.renderTimeSelect();

const selectTime = data[activeKey];

};

leaveDrug = e => {

e.stopPropagation();

e.preventDefault();

document.onmouseup = this.upDrug.bind(this);

};

render() {

const { showLabel, activeKey } = this.state;

let { moveLength } = this.state;

let tmp = null;

if (moveLength === undefined) {

moveLength = 0;

}

tmp = activeKey * 3.64;

return (

<div className="time-axis">

<div className="time-select">{this.renderTimeLine()}</div>

{showLabel !== "" && (

<div style={{ left: ${tmp}px }} className="time-label">

<div className="time-drug-line"></div>

<div

className="time-drug"

onMouseDown={this.startDrug}

onMouseUp={this.upDrug}

onMouseLeave={this.leaveDrug}

{showLabel}

</div>

</div>

)}

<div className="time-HHMM">{this.renderTime()}</div>

</div>

);

}

}

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏