function onCLickHandler() {
...
}
return (
<button onClick={onCLickHandler} type="button">
demonstrate
</button>
);
const ref = useRef();
useEffect(() => {
if (!ref.current) return () => {};
function onMouseEnterHandler() {
...
}
const { current } = ref;
current.addEventListener('mouseenter', onMouseEnterHandler);
return () => {
current.removeEventListener('mouseenter', onMouseEnterHandler);
};
}, []);
return (
<div ref={ref} />
);
提供處理user互動dom元素的媒介
Wrapper
Items
使用情境分三步驟
1. 點擊
2. 拖拉
3. 放開
點擊
Wrapper
1. 記錄itemId
2. clone clicked dom node
3. 加入mousemove, mouseup listener
Items
1. 加入mouseenter, mouseup listener
拖拉
Wrapper
1. 透過初始與當前x y座標計算top, left值
Items
1. mouseenter個別item時觸發排序function
放開
Wrapper
1. 初始化,並拔除listener
Items
1. 拔除listener
1. 明確定義package功能,與未來擴充方向
針對element list做排序的package。
未來擴充:options-拖拉button功能、排序。animation-排序動畫、拖拉mode動畫
2. Guide doc ? demo example ? 使用工具?
為了加速開發,且套件規模不大,先緩
1. 明確定義package功能,與未來擴充方向
針對element list做排序的package。
未來擴充:options-拖拉button功能、排序。animation-排序動畫、拖拉mode動畫
2. Guide doc ? demo example ? 使用工具?
為了加速開發,且套件規模不大,先緩
3. 希望使用者如何使用package
<DraggableList>
{items.map(item => (
<CustomizeDraggableItem item={item} />
))}
<DraggableList>
DraggableElementsList:For user to use
DraggableElementsWrapper:For the dom clone and wrapper drag feature
...
...
DraggableElementPlacement:For the item drag feature
child
child
child
<DraggableElementsWrapper>
{({}) => draggableElements.map(({ returns, options }) => (
<DraggableElementPlacement>
{children({ returns })}
</DraggableElementPlacement>
))}
</DraggableElementsWrapper>
const mockItemBundle=[
...bundleData,
]
const { DraggableList, draggableElements } = useDraggableElementsList(mockItemBundle);
<DraggableList>
{({ item }) => (
<CustomizeDraggableItem item={item} />
)}
<DraggableList>
DraggableElementsList:For user to use
DraggableElementsWrapper:For the dom clone and wrapper drag feature
...
...
DraggableElementPlacement:For the item drag feature
child
child
child
hook
useDraggableElementsList:For input, output & options
1. 遮罩問題
DraggableElementPlacement
原本Item內的按鈕功能會被遮罩擋住
解法1:透過額外的button來控制拖拉模式,進入拖拉模式時將placement拉至上層
透過按鈕來決定能不能拖拉這件事不直觀
解法2:使用react portal將item child轉到不同層的dom
因為placement為absolute蓋在上面,所以依舊有層級問題
解法1:透過額外的button來控制拖拉模式,進入拖拉模式時將placement拉至上層
透過按鈕來決定能不能拖拉這件事不直觀
解法2:使用react portal將item child轉到不同層的dom
因為placement為absolute蓋在上面,所以依舊有層級問題
DraggableElementsList
DraggableElementsWrapper
...
...
DraggableElementPlacement
child
child
child
useDraggableElementsList
ChildPlacementContainer
...
...
Placement
child
最終解:解法2+在child container中定義其底下包含特定classname的dom套用定義好的z-index
function CustomizeDraggableItem() {
return (
<div>
<button
type="button"
className="react-draggable-element-list-triggerable">
triggerable-button
</button>
<div>
);
}
DraggableElementsList
DraggableElementsWrapper
...
...
DraggableElementPlacement
child
child
child
useDraggableElementsList
ChildPlacementContainer
...
...
Placement
child
2. 拖拉功能實作方式
Event Emitter 建立頻道執行不同層的溝通觸發function建立event ?
優點:完全不會有props傳遞,useEffect用於一開始訂閱所需頻道,不用擔心預期外rerender
Wrapper傳遞setState, Items透過給予className與querySelector的方式取得ref
優點:較為單純,也不會同時建立一大堆eventListener
Reference:無