【问题标题】:Implementing a basic drag functionality in ReactJS在 ReactJS 中实现一个基本的拖动功能
【发布时间】:2019-01-07 15:46:50
【问题描述】:

基于 create-react-app 模板,我正在尝试实现一个非常基本的拖放场景。我的App.js 目前看起来像这样:

import React, { Component } from 'react';
import './App.css';

class App extends Component {
  render() {
    const myStyle = {
      height: '100px',
      width: '200px',
      top: '50px',
      left: '100px',
      position: 'absolute',
      borderStyle: 'solid',
      borderColor: 'blue',      
    };

    return (

      <div className="App">        
          <div style={myStyle} draggable>test</div>
          <div>test2</div>        
      </div>
    );
  }
}

export default App;

我的问题是,从我看到的所有教程和文档中,我了解到添加 draggable 属性会导致元素可拖动,但事实并非如此。

需要设置哪些附加属性才能创建对象draggable? (我对在这个阶段放弃任何东西不感兴趣。)

【问题讨论】:

标签: javascript reactjs


【解决方案1】:

这可以是 React 中拖动行为的核心实现。它当然需要增强,而且还不能处理掉线:

const { useRef } = React

const App = () => {
  const elemRef = useRef(null)
  const dragProps = useRef()
  
  const initialiseDrag = event => {
    const { target, clientX, clientY } = event
    const { offsetTop, offsetLeft } = target
    const { left, top } = elemRef.current.getBoundingClientRect()
    
    dragProps.current = {
      dragStartLeft: left - offsetLeft,
      dragStartTop: top - offsetTop,
      dragStartX: clientX,
      dragStartY: clientY
    }
    window.addEventListener('mousemove', startDragging, false)
    window.addEventListener('mouseup', stopDragging, false)
  }
  
  
  const startDragging = ({ clientX, clientY }) => {    
    elemRef.current.style.transform = `translate(${dragProps.current.dragStartLeft + clientX - dragProps.current.dragStartX}px, ${dragProps.current.dragStartTop + clientY - dragProps.current.dragStartY}px)`
  } 

  const stopDragging = () => {
    window.removeEventListener('mousemove', startDragging, false)
    window.removeEventListener('mouseup', stopDragging, false)
  }
  
  return (
    <div
      onMouseDown={initialiseDrag}
      ref={elemRef}
      >
      DragMe
    </div>
  )
}

ReactDOM.render(<App />, document.getElementById('root'));
div {
  cursor: grab;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>

【讨论】:

  • 我意识到我可以推出自己的实现,但我认为应该可以使用 draggable 属性。你是说 React 不适用于 HTML5 内置的 draggable 属性?
  • draggable 也可以在 react 中工作,但此实现让您可以更好地控制拖动坐标以进行进一步处理。
  • 我已经意识到我可能需要以这样的方式结束,所以它非常有用......我仍然想知道为什么 draggable 不起作用,虽然
  • 不错。如果您对答案感到满意,请点赞。如果完全解决了您的问题,请将其标记为已接受的答案。提前致谢。不幸的是,我没有太多经验,但由于它是本机浏览器功能,我认为它不允许通过 javascript 进行太多控制。
  • 这帮助我实现了自定义范围滑块(不使用输入类型范围),谢谢!
【解决方案2】:

由于我无法运行您当前的 ReactJS 应用程序,我拼凑了一个简短的示例来展示拖放功能的不同实例。

从示例中可以看出,将draggable 属性设置为您的元素应该使元素可拖动,就像在典型网页上拖动图像一样。

您能否确认在拖动元素时,它根本没有移动,如 不可拖动 框的代码 sn-p 所示?

var draggable = document.getElementById('draggable');

function onDragStart(event) {
    event.dataTransfer.setData('text/html', null); //cannot be empty string
    var counter = document.getElementById('counter');
    counter.innerText = parseInt(counter.innerText, 10) + 1;
}

draggable.addEventListener('dragstart', onDragStart, false);
#draggable{
    width: 100px;
    height: 100px;
    background: blue;
    margin: 10px 5px;
}

#notdraggable{
    width: 100px;
    height: 100px;
    background: red;
    margin: 10px 5px;
}

#draggableNDT{
      width: 100px;
    height: 100px;
    background: green;
    margin: 10px 5px;
} 
   <div>Draggable (<span id='counter'>0</span>)</div>
    <div id='draggable' draggable='true'></div>
    
    <div><pre>Draggable (No DataTransfer)</div>
    <div id='draggableNDT' draggable></div>
    
    <div><pre>Not Draggable</div>
    <div id='notdraggable' draggable='false'></div>

【讨论】:

  • 我只是提供一个完整的答案。在提供的链接中,您还可以看到您需要为拖动事件处理程序创建一个方法以及将可拖动标记添加到 HTML
  • 这不是一个完整的答案。指向外部网站的答案根本不是答案。它们应该是 cmets
  • 你是说你/需要/来创建那个处理程序吗?我已经尝试过了,它没有任何区别,但我的印象是没有必要。
  • 我已将答案更新为更完整的答案,您能否确认拖动元素时,它根本没有移动,如不可拖动框的代码 sn-p 所示?
  • 我不明白为什么要对这个答案投反对票。这是一种可能的方法。如果不完全符合问题所有者的需求,仍然给我们提供了宝贵的意见。如果其中有实际错误,请评论您的修复建议,不要投反对票。
【解决方案3】:

您可以签出react-draggable库,只需将组件包装在Draggable组件中

安装 npm i react-draggable

进口 import Draggable from 'react-draggable'

用法:

<Draggable 
   axis="both"
   cancel="input, textarea, span, label"
>
  <div style={myStyle}>test</div>
</Draggable>

【讨论】:

    猜你喜欢
    • 2012-12-10
    • 2023-03-05
    • 2022-01-20
    • 1970-01-01
    • 2017-10-14
    • 2020-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多