【问题标题】:Element stop dragging when cursor leaves div area react光标离开div区域时元素停止拖动反应
【发布时间】:2019-04-11 07:25:55
【问题描述】:

我一直在尝试在 react 中实现一个可拖动的 div,如果我在移动设备上,基本上我会使用鼠标单击并拖动元素,甚至是手指。 问题是当我将鼠标移动得太快并且光标离开 div 的区域时,元素停止被拖动。这就像我没有足够快地更新 div 的位置以跟上光标速度。 知道如何解决这个问题吗?

我也一直在使用顶部和左侧位置来更新 div 的位置,使用 css translatex/y 有什么好处吗? 会有什么不同?

import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';

class App extends Component {
  constructor() {
    super();
    this.state = {
      pos: {
        x:0,
        y:0,
      },
      rel: {
        x:0,
        y:0
      },
      dragging : false
    };
    this.draggable = React.createRef()
  }

  onTouchStart = e => {
    const touch = e.touches[0]
    const posTop = this.draggable.current.offsetTop
    const posLeft = this.draggable.current.offsetLeft

    this.setState({
      dragging: true,
      rel: {
        x: touch.clientX - posLeft,
        y: touch.clientY - posLeft
      }
    })
    e.stopPropagation()
  }

  onTouchMove = e => {
    if (!this.state.dragging) return
    const touch = e.touches[0]
    this.setState({
      pos: {
        x: touch.clientX - this.state.rel.x,
        y: touch.clientY - this.state.rel.y
      }

    })
    e.stopPropagation()
    e.preventDefault()
  }

  onTouchEnd = e => {
    this.setState({dragging: false})

  }

  onMouseDown =  (e) => {
    // only left mouse button
    if (e.button !== 0) return
    const posTop = this.draggable.current.offsetTop
    const posLeft = this.draggable.current.offsetLeft
    console.log(e.pageX,': pagex   ', e.pageY, ' : and pagey')
    console.log(posTop, ': posTop', posLeft, ' : posY')
    console.log('resultLeft :', e.pageX - posLeft, 'resultTop  :',  e.pageY - posTop)
    this.setState({
      dragging: true,
      rel: {
        x: e.pageX - posLeft,
        y: e.pageY - posTop
      }     
    })
    e.stopPropagation()
    e.preventDefault()
  }

  onMouseUp =  (e)  => {
    this.setState({dragging: false})
    e.stopPropagation()
    e.preventDefault()
  }

  onMouseMove = (e) => {
    if (!this.state.dragging) return
    this.setState({
      pos: {
        x: e.pageX - this.state.rel.x,
        y: e.pageY - this.state.rel.y    
      }        
    })
    e.stopPropagation()
    e.preventDefault()
  }

  render() {
    return (
      <div style={{position:'relative', backgroundColor:'green', height:'100%', width:'100%'}}>
          <div style={{position:'absolute',backgroundColor:'red',
          height: '100px', width:'100px',
           left: this.state.pos.x + 'px', top: this.state.pos.y + 'px'}}
           onTouchStart={this.onTouchStart}
           onTouchMove={this.onMouseMove}
           onTouchEnd={this.onTouchEnd}
            onMouseDown={this.onMouseDown}
            onTouchMove={this.onTouchMove}
            onMouseMove={this.onMouseMove}
            onMouseUp={this.onMouseUp}
            ref={this.draggable}
          > draggable div 
        </div>
      </div>
    );
  }
}

render(<App />, document.getElementById('root'));

您可以将代码放在 stackblitz 上,它会起作用,因此您可以尝试。 任何建议都非常受欢迎!

Stackblitz 链接:https://stackblitz.com/edit/react-draggable-test-oezlsk

【问题讨论】:

标签: javascript css reactjs draggable


【解决方案1】:

好的, 发现了问题。 我将事件 onMouseUp onMouseMove 分配给 div 而不是父亲。 此外,由于根 div 没有任何尺寸,父亲没有适当的高度和宽度。

更新后的工作代码如下

import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';

class App extends Component {
  constructor() {
    super();
    this.state = {
      pos: {
        x:0,
        y:0,
      },
      rel: {
        x:0,
        y:0
      },
      dragging : false
    };
    this.draggable = React.createRef()
  }

  onTouchStart = e => {
    const touch = e.touches[0]
    const posTop = this.draggable.current.offsetTop
    const posLeft = this.draggable.current.offsetLeft

    this.setState({
      dragging: true,
      rel: {
        x: touch.clientX - posLeft,
        y: touch.clientY - posLeft
      }
    })
    e.stopPropagation()
  }

  onTouchMove = e => {
    if (!this.state.dragging) return
    const touch = e.touches[0]
    this.setState({
      pos: {
        x: touch.clientX - this.state.rel.x,
        y: touch.clientY - this.state.rel.y
      }

    })
    e.stopPropagation()
    e.preventDefault()
  }

  onTouchEnd = e => {
    this.setState({dragging: false})

  }

  onMouseDown =  (e) => {
    // only left mouse button
    if (e.button !== 0) return
    const posTop = this.draggable.current.offsetTop
    const posLeft = this.draggable.current.offsetLeft
    console.log(e.pageX,': pagex   ', e.pageY, ' : and pagey')
    console.log(posTop, ': posTop', posLeft, ' : posY')
    console.log('resultLeft :', e.pageX - posLeft, 'resultTop  :',  e.pageY - posTop)
    this.setState({
      dragging: true,
      rel: {
        x: e.pageX - posLeft,
        y: e.pageY - posTop
      }     
    })
    e.stopPropagation()
    e.preventDefault()
  }

  onMouseUp =  (e)  => {
    this.setState({dragging: false})
    e.stopPropagation()
    e.preventDefault()
  }

  onMouseMove = (e) => {
    if (!this.state.dragging) return
    this.setState({
      pos: {
        x: e.pageX - this.state.rel.x,
        y: e.pageY - this.state.rel.y    
      }        
    })
    e.stopPropagation()
    e.preventDefault()
  }

  render() {
    return (
      <div onMouseUp={this.onMouseUp} onMouseMove={this.onMouseMove} style={{position:'relative', backgroundColor:'green', height:'120%', width:'120%'}}>
          <div style={{position:'absolute',backgroundColor:'red',
          height: '100px', width:'100px',
           left: this.state.pos.x + 'px', top: this.state.pos.y + 'px'}}
           onTouchStart={this.onTouchStart}
           onTouchMove={this.onMouseMove}
           onTouchEnd={this.onTouchEnd}
            onMouseDown={this.onMouseDown}
            onTouchMove={this.onTouchMove}          

            ref={this.draggable}
          > draggable div 
        </div>
      </div>
    );
  }
}

render(<App />, document.getElementById('root'));

【讨论】:

  • “父母” ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-29
  • 2015-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多