我已经用react-dnd创建了一个简单的可排序列表,使用的代码类似于codesandbox中的react-dnd的可排序示例。
但是,我在尝试概念化如何调整此示例并利用react-dnd的custom drag layer来自定义拖动预览时遇到了一些困难。具体地说,我希望在开始拖动组件时更改组件的背景色。不要太复杂。
为什么我需要使用一个自定义的拖动层?因为由于浏览器API和react-dnd的HTML5后端的限制,我不能使用CSS设置拖动预览的样式(这就是我正在使用的)。
我在可排序列表中找不到任何使用自定义拖动层的示例,因此如果有任何帮助,我将不胜感激。
发布于 2021-10-27 07:14:51
我最近确实遇到了同样的问题,我不得不同意这一点的文档并不存在,这给了我相当多的悲痛来弄清楚事情。
Create CustomDragLayer
我已经使用了这个example (它工作得很好,当您刚接触这个库时,它就有点让人应接不暇了),并创建了一个简单的CustomDragLayer组件:
import { DragLayerMonitor, useDragLayer } from 'react-dnd'
const CustomDragLayer: React.FC = () => {
const {isDragging, currentOffset, item} = useDragLayer(
(monitor: DragLayerMonitor) => {
return {
isDragging: monitor.isDragging(),
currentOffset: monitor.getSourceClientOffset(),
item: monitor.getItem()
};
}
);
return isDragging && currentOffset
? <div style={{
// functional
transform: `translate(${currentOffset.x}px, ${currentOffset.y}px)`,
position: 'fixed',
top: 0,
left: 0,
pointerEvents: 'none',
// design only
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '150px',
height: '50px',
border: '1px solid red',
color: 'red'
}}>
Dragging {item.id}
</div>
: null;
};
export default CustomDragLayer;它期望被拖动的项有一个名为id的属性(在它显示时)。大多数样式属性并不重要,您需要确保设置了transform、position、top和left。
坐标对于窗口是绝对的,因此position: fixed使工作变得更容易,否则可能需要一些额外的计算。
由于这个issue,你必须添加pointerEvents: 'none',否则在火狐中的悬停/拖放检测不能正常工作,我也注意到Chrome中的一些奇怪的行为(无法在带有点击处理程序的元素上拖动项目)。添加此属性似乎可以解决这些问题。
隐藏原始元素
现在,您已经渲染了自定义的拖动元素,但是,原始的源元素也是可见的,并随鼠标移动。这使得这种体验变得相当丑陋。在这里,我采用了example的方法,向我的Draggable对象添加了一个没有依赖项的useEffect钩子(在类组件中使用componentDidMount ),该对象利用了来自html5后端的一个空图像呈现函数,并隐藏了原始预览。
我决定做的最后一件事是在被拖动时隐藏源项目。我使用visibility风格的属性,它保留了dom中的原始位置,并使其看起来像项目实际上正在被移动。这也取决于上下文,您可能决定以不同的方式处理它。
以下是Draggable代码摘录:
import { getEmptyImage } from 'react-dnd-html5-backend';
const Draggable: React.FC = () => {
// ...
const [{ isDragging }, drag, dragPreview] = useDrag(() => ({
// ...
}));
useEffect(() => {
dragPreview(getEmptyImage())
}, []);
return <div ref={drag} style={{ visibility: isDragging ? 'hidden' : 'inherit'}}>
{/* your draggable content here*/}
</div>;
};
export default Draggable;将CustomDragLayer添加到dom
最后,一旦你拥有了所有这些,你需要在dnd根组件的dom树中的某个地方挂载你的定制的拖动元素。
return <div ref={drop}>
<Draggable ref={drag} />
<CustomDragLayer />
</div>希望这有助于理解它是如何在基础上工作的。
发布于 2020-04-06 16:05:54
你可以在Card上悬停时添加css。不确定这是你需要的.
import Radium from "radium";
import "./style.css";
const style = {
border: "1px dashed gray",
padding: "0.5rem 1rem",
marginBottom: ".5rem",
backgroundColor: "white",
cursor: "move",
":hover": {
background: "purple"
}
};
export default Radium(Card);检查此处CodeSandBox
https://stackoverflow.com/questions/61052932
复制相似问题