【问题标题】:How to drag and drop in between divs in reactjs?如何在reactjs中的div之间拖放?
【发布时间】:2022-01-20 23:16:15
【问题描述】:

我尝试使用香草HTML/js API 在reactjs 中实现拖放功能。我几乎完成了它,但我不能将它放在现有的divs 之间。我想在两个 div 中添加拖放功能(即,我应该能够拖动第一列中的任何 divs 并拖放到第二列中的任何位置,反之亦然)。到目前为止,我只能在最后一个index 拖放,而不是介于两者之间

这是我到目前为止所尝试的。请附上代码。如果您提出建议,我不会那么强烈地追随

 <div id="app"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
      const App = () => {
        const drop = (e) => {
          e.preventDefault();
          const div_id = e.dataTransfer.getData("div_id");
          const block = document.getElementById(div_id);
          e.target.appendChild(block);
        };
        const dragOver1 = (e) => {
          e.preventDefault();
        };

        const dragStart = (e) => {
          const target = e.target;
          e.dataTransfer.setData("div_id", target.id);
        };

        const dragOver = (e) => {
          e.stopPropagation();
        };

        return (
          <div
            style={{
              display: "flex",
              justifyContent: "space-between",
              padding: "50px",
            }}
          >
            <div
              onDrop={drop}
              onDragOver={dragOver1}
              id="board-1"
              style={{
                border: "1px solid #222",
                padding: 20,
              }}
            >
              <div
                id="firstfirst"
                draggable
                onDragStart={dragStart}
                onDragOver={dragOver}
              >
                <div>
                  <h1>First Column First Row</h1>
                </div>
              </div>
              <div
                id="firstsecond"
                draggable
                onDragStart={dragStart}
                onDragOver={dragOver}
              >
                <div>
                  <h1>First Column Second Row</h1>
                </div>
              </div>
              {Array.from(Array(2)).map((_, index) => {
                return (
                  <div
                    key={index}
                    id={`first${index}`}
                    draggable
                    onDragStart={dragStart}
                    onDragOver={dragOver}
                  >
                    <h1>First Column Row {index}</h1>
                  </div>
                );
              })}
            </div>
            <div
              id="board-2"
              onDrop={drop}
              onDragOver={dragOver1}
              style={{
                border: "1px solid #222",
                padding: 20,
              }}
            >
              <div
                id="secondfirst"
                draggable
                onDragStart={dragStart}
                onDragOver={dragOver}
              >
                <h1>Second Column First Row</h1>
              </div>
              <div
                id="secondsecond"
                draggable
                onDragStart={dragStart}
                onDragOver={dragOver}
              >
                <h1>Second Column Second Row</h1>
              </div>

              {Array.from(Array(2)).map((c, index) => {
                return (
                  <div
                    key={index}
                    id={`second${index}`}
                    draggable
                    onDragStart={dragStart}
                    onDragOver={dragOver}
                  >
                    <h1> Second Column Row {index} </h1>
                  </div>
                );
              })}
            </div>
          </div>
        );
      };
      ReactDOM.render(<App />, document.getElementById("app"));
    </script>

【问题讨论】:

  • 直接修改 DOM 可能会干扰 React 自己对 DOM 的管理。 dnd 最好使用一些特定于 React 的包。
  • @tromgy 有什么例子吗?而且我看到它已经正常工作了。只是顺序不对
  • 这可能正是问题所在。一方面你让 React 使用Array.map 管理&lt;div&gt;s 的列表,另一方面你直接通过appendChild 修改DOM。

标签: javascript reactjs drag-and-drop


【解决方案1】:

appendChild 总是将项目添加到目标 div 的末尾。您可以使用孩子的位置 (child.getBoundingClientRect().bottom) 和鼠标放置位置 (e.clientY) 进行简单的计算来确定要放置的位置。

如下更改drop 处理程序

const drop = e => {
    e.preventDefault();
    const div_id = e.dataTransfer.getData("div_id");
    const block = document.getElementById(div_id);
    // get the child div index where to drop
    let dropIndex = Array.from(e.target.children).findIndex(
        // find the first child index where
        // a child bottom (vertical viewport height to the bottom of child div)
        // is greater than mouse Y position
        child => child.getBoundingClientRect().bottom > e.clientY
    );
    if (dropIndex === -1) {
        // drop at the end
        e.target.appendChild(block);
    } else {
        // drop at start or in between
        e.target.insertBefore(block, e.target.children[dropIndex]);
    }
};

<div id="app"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
      const App = () => {
        const drop = (e) => {
          e.preventDefault();
          const div_id = e.dataTransfer.getData("div_id");
          const block = document.getElementById(div_id);
          let dropIndex = Array.from(e.target.children).findIndex(
            (child) => child.getBoundingClientRect().bottom > e.clientY
          );
          if (dropIndex === -1) {
            e.target.appendChild(block);
          } else {
            e.target.insertBefore(block, e.target.children[dropIndex]);
          }
        };
        
        const dragOver1 = (e) => {
          e.preventDefault();
        };

        const dragStart = (e) => {
          const target = e.target;
          e.dataTransfer.setData("div_id", target.id);
        };

        const dragOver = (e) => {
          e.stopPropagation();
        };

        return (
          <div
            style={{
              display: "flex",
              justifyContent: "space-between",
              padding: "50px",
            }}
          >
            <div
              onDrop={drop}
              onDragOver={dragOver1}
              id="board-1"
              style={{
                border: "1px solid #222",
                padding: 20,
              }}
            >
              <div
                id="firstfirst"
                draggable
                onDragStart={dragStart}
                onDragOver={dragOver}
              >
                <div>
                  <h1>First Column First Row</h1>
                </div>
              </div>
              <div
                id="firstsecond"
                draggable
                onDragStart={dragStart}
                onDragOver={dragOver}
              >
                <div>
                  <h1>First Column Second Row</h1>
                </div>
              </div>
              {Array.from(Array(2)).map((_, index) => {
                return (
                  <div
                    key={index}
                    id={`first${index}`}
                    draggable
                    onDragStart={dragStart}
                    onDragOver={dragOver}
                  >
                    <h1>First Column Row {index}</h1>
                  </div>
                );
              })}
            </div>
            <div
              id="board-2"
              onDrop={drop}
              onDragOver={dragOver1}
              style={{
                border: "1px solid #222",
                padding: 20,
              }}
            >
              <div
                id="secondfirst"
                draggable
                onDragStart={dragStart}
                onDragOver={dragOver}
              >
                <h1>Second Column First Row</h1>
              </div>
              <div
                id="secondsecond"
                draggable
                onDragStart={dragStart}
                onDragOver={dragOver}
              >
                <h1>Second Column Second Row</h1>
              </div>

              {Array.from(Array(2)).map((c, index) => {
                return (
                  <div
                    key={index}
                    id={`second${index}`}
                    draggable
                    onDragStart={dragStart}
                    onDragOver={dragOver}
                  >
                    <h1> Second Column Row {index} </h1>
                  </div>
                );
              })}
            </div>
          </div>
        );
      };
      ReactDOM.render(<App />, document.getElementById("app"));
    </script>

【讨论】:

  • @Grand Whiz,看看这个!!
猜你喜欢
  • 2017-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多