当用户点击可拖动的div时,将其置于React.js前端

4

我想在点击或拖动时将可拖动的框移到最前面。

我事先不知道这样的框的最大数量,因为我有一个按钮,当用户单击该按钮时,会创建一个新的可拖动框。

无论有多少个框,该按钮都应始终位于顶部,因此其z-index应始终是最大的。

所以这些是我的问题:

  1. 如何在用户单击它时将框移到最前面。
  2. 如何使按钮保持在最前面。

而我对ReactJS还很陌生。

这是我目前在MyComponent.js中拥有的内容。

import React, { useState }  from 'react';
import Draggable from 'react-draggable';

function MyComponent() {
    const [currZIndex, setZIndex] = useState(0);

    const bringForward = () => {
        setZIndex(currZIndex + 1);
    }

    return (
        <Draggable onMouseDown={bringForward}>
            <div className="mydiv" style={{zIndex: currZIndex}}></div>
        </Draggable>
    );
}

我目前实现的问题是每个组件只知道自己的z-index,但不知道当前最高的z-index。而且每当我点击任何div时,z-index都会增加,这使得z-index变得不必要地大。

如果div1的z-index为6,div2的z-index为2,则我必须点击div2 5次才能使其z-index变为7,以将div2置于最前面。

我仍然没有想出如何处理按钮的z-index的想法。

对于此,这是我在App.js中拥有的内容。

import React, { useState } from 'react';
import MyComponent from './MyComponent';

function App() {
  const [componentList, setComponentList] = useState([]);

  function addNewComponent() {
    setComponentList(componentList.concat(<MyComponent key={componentList.length} />));
  }

  return (
    <div>
      <button onClick={addNewComponent}>New Component</button>
      {componentList}
    </div>
  );
}
1个回答

1
让我们逐个解决这两个问题。首先是简单的一个:
1. 如何使按钮始终保持在顶部,无论有多少个框,使其z-index始终最大?
实现这个要求的一种方法是:
  1. 在按钮容器(
    )和MyComponent容器(
    )上都使用position: relative来建立独立的堆叠上下文。您可以参考这篇文章了解更多信息。
按照上述步骤,无论您创建多少可拖动元素,按钮始终位于顶部。
return (
    <div>
      <div style={{ position: "relative", zIndex: 2 }}>
        <button onClick={addNewComponent}>New Component</button>
      </div>
      <div style={{ position: "relative", zIndex: 1 }}>
        {componentList.map((item) => (
          <MyComponent
            key={item.id}
            zIndex={item.zIndex}
            bringToFront={() => bringToFront(item.id)}
          />
        ))}
      </div>
    </div>
  );

2. 当用户点击/拖动可拖动框时,如何将其置于顶部(但在按钮后面)?
现在,解决这个问题有多种方法。我会使用的一种方法是在视图中创建多个可拖动组件的数量。让我详细说明一下步骤。
  1. 在父组件中维护一个状态,用于跟踪可拖动组件的总数。

    const [componentList, setComponentList] = useState([]);
    
  2. 使<MyComponent />(逻辑上的每个可拖动框)接受两个属性:zIndexbringToFront

  3. 点击button时,在componentList中添加一个新条目(即setState),对象如下:

     {
        id: prevComponentList.length, 
        zIndex: 0,
      }
    
  4. 现在,当特定组件被点击并拖动时(触发mousedown事件),调用bringToFront回调函数并传入该框的id。现在,遍历componentList,找到当前拖动/点击元素的id,并将其z-index值增加到prevComponentList中可用元素的最大长度,否则(如果id与元素的id不匹配)将当前z-index减1。

     function bringToFront(id) {
      setComponentList((prevComponentList) =>
        prevComponentList.map((item) =>
          item.id === id
            ? { ...item, zIndex: prevComponentList.length }
            : { ...item, zIndex: item.zIndex - 1 },
        ),
      );
    }
    

代码演示

建议和进一步阅读:

  1. 为什么你的 z-index 不起作用的 4 个原因
  2. 使用 Styled components 进行样式化

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接