ํ์์ ์ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ! ๊ทธ๊ฒ์ ๋ชจ์ผ๋ ๋ชจ๋ ๋ ธ๋ ฅ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ๋น ๋ฅธ ์ง๋ฌธ์ด ์์ต๋๋ค. ๋๋๊ทธ ์์ ์ค์ ์ปค์๊ฐ ํญ์ ๋์ผํ ๊ฒ์ผ๋ก ์ค์ ๋๋๋ก ์ปค์๋ฅผ ์ฌ์ฉ์ ์ง์ ํ ์ ์์ต๋๊น (ํนํ _dragging_ ์์ด์ฝ์ผ๋ก ์ค์ ํ๊ณ ์ถ์ต๋๋ค)?
์ฆ, ๋๊ธฐ ์์ญ ์์ ์๋์ง ์ฌ๋ถ์ ๊ด๊ณ์์ด ์ปค์๋ ๋์ผํ๊ฒ ์ ์ง๋ฉ๋๋ค. ์ด๋ ์๋ฅผ ๋ค์ด Trello๊ฐ ๋ ธํธ๋ฅผ ๋๋๊ทธํ๋ ๋์ ์ปค์๋ฅผ ๊ฐ๋ ๋ฐฉ์๊ณผ ์ ์ฌํฉ๋๋ค.
๋ฏธ๋ฆฌ ๊ฐ์ฌ๋๋ฆฝ๋๋ค!
isDragging
๊ฐ true
๋์ ์ ์ฒด ๋ณธ๋ฌธ (๋๋ ์์ฉ ํ๋ก๊ทธ๋จ ๋ฃจํธ div
)์ cursor
์คํ์ผ์ ์ค์ ํ ์ ์์ต๋๋ค. DragLayer
๋ฅผ ์ฌ์ฉํ์ฌ isDragging
๋ณ๊ฒฝ ์ฌํญ์๋ค์ ์ ์์ต๋๋ค.
๊ฐ์ฌํฉ๋๋ค. ํจ๊ณผ๊ฐ ์์์ผ๋ฉดํฉ๋๋ค. ๋ถํํ๋ ์ปค์ ์คํ์ผ์ document.body๋ก ์ค์ ํ๊ณ "! important"๋ก ํ์ํ๋๋ผ๋ ์ปค์ ์คํ์ผ์ ๋ฌด์์ธ๊ฐ (๋๋ Chrome์ ์์)์ ์ํด ์ฌ์ ์๋ฉ๋๋ค. ๋ค๋ฅธ ์์ด๋์ด๊ฐ ์์ต๋๊น?
HTML5 ๋๋๊ทธ ์ค ๋๋กญ API๊ฐ ์๋ํ๋ ๋ฐฉ์ ์ผ ์๋ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ ์ ์ผํ ํด๊ฒฐ์ฑ ์ HTML5 ๋๋๊ทธ ์ค ๋๋กญ ์ด๋ฒคํธ ๋์ ๋ง์ฐ์ค ์ด๋ฒคํธ๋ฅผ ์ฌ์ฉํ๋ ์ฌ์ฉ์ ์ง์ ๋ฐฑ์๋๋ฅผ ๋ง๋๋ ๊ฒ์ ๋๋ค.
๋๋ ๋น์ ์ด ๊ทธ๋ ๊ฒ ๋งํ์ง ์๊ธฐ๋ฅผ ๋ฐ๋ฌ์ต๋๋ค :) ๊ฐ์ฌํฉ๋๋ค!
์ด ๋ฌธ์ ์ ๋ํด ๋ฐฉ๊ธ ์๊ฒ๋์์ต๋๋ค. ์ํ๊น๊ฒ๋ ๋๋๊ทธํ๋ ๋์ ์์ด์ฝ์ ๋ณ๊ฒฝํ ์์๋ ๊ฒ ๊ฐ์ต๋๋ค.
๋๊ตฌ๋ ์ง์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์์ต๋๊น?
๋ํ ๊ฐ์ ์ด๊ฒ์ ์กฐ์ฌํ์ต๋๋ค. ์, DataTransfer.effectAllowed
์ฉ API๊ฐ ๋ช ๊ฐ์ง ์ต์
๋ง ์ง์ํ๋ค๋ ์ ์์ ์ฌํ๊ฒ๋ ๋ธ๋ผ์ฐ์ ์ ํ ์ฌํญ ์ธ ๊ฒ ๊ฐ์ต๋๋ค.
https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/effectAllowed
๋ฐ๋ผ์์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ์ ์ผํ ๋ฐฉ๋ฒ์ @gaearon์ด ์ธ๊ธํ๋ฏ์ด ๋ค๋ฅธ ์ฌ์ฉ์ ์ ์ ๋ฐฑ์๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค. / ์ด๊ฒ์ ์ฌ๋๋ค์๊ฒ ์ง๊ด์ ์ด์ง ์์ ์ ์์ผ๋ฏ๋ก HTML5 ๋ฐฑ์๋ ๋ฌธ์์ ํฌํจ ํ ๊ฐ์น๊ฐ์์ ์ ์์ต๋๋ค.
๋งค์ฐ ์๋ชป๋์์ง๋ง ์๋ํ๋ ์๋ฃจ์
์ ๋ณธ๋ฌธ์ dragging
ํด๋์ค๋ฅผ ์ถ๊ฐํ์ฌ ๋ณธ๋ฌธ๊ณผ ๋ณธ๋ฌธ ๋ด๋ถ์ ๋ชจ๋ DOM ๊ฐ์ฒด๊ฐ cursor: grabbing !important
์ป๋๋กํ๋ ๊ฒ์
๋๋ค. ๊ทธ๊ฒ์ ๋ฌด์ํ๋ ๊ฒ ์ธ์๋ ์๋ฌด๊ฒ๋ ์์ต๋๋ค.
์ด๊ฒ์ ๋๋ฅผ ์ํด ์ผํ ๊ฒ์
๋๋ค.
:global {
body.dragging,
body.dragging * {
cursor: url('./assets/cursors/grabbing.cur'), move !important;
}
}
JS๋ฅผ ์ฌ์ฉํ๋ ๋ ๋ค๋ฅธ ์ ๊ทผ ๋ฐฉ์์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
window.addEventListener('drag', () => {
document.body.style.cursor = 'grabbing';
}, true)
๊ทธ๋๋ ์ผ๊ด๋๊ฒ ์๋ํ์ง ์๋ ๊ฒ ๊ฐ์ต๋๋ค ...
์ฌ๊ธฐ์์ ์ ์ ๋ ์๋ฃจ์ ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด๊ฒ์ ๋ํ ์ ๋ฐ์ดํธ๊ฐ ์์ต๋๊น?
TouchBackend๋ก ์ ํํ๊ณ CSS๋ฅผ ์ฌ์ฉํ์ฌ ์ปค์๋ฅผ ์ค์ ํ์ต๋๋ค.
<DndProvider backend={TouchBackend} options={{ enableTouchEvents: false, enableMouseEvents: true }}>
<div className=`my-app ${isDragging ? 'dragging' : ''}`>
.... draglayers here
</div>
</DndProvider>
.dragging {
cursor: grabbing
}
TouchBackend๋ก ์ ํํ๊ณ CSS๋ฅผ ์ฌ์ฉํ์ฌ ์ปค์๋ฅผ ์ค์ ํ์ต๋๋ค.
<DndProvider backend={TouchBackend} options={{ enableTouchEvents: false, enableMouseEvents: true }}> <div className=`my-app ${isDragging ? 'dragging' : ''}`> .... draglayers here </div> </DndProvider>
.dragging { cursor: grabbing }
๋๋ฅผ ์ํด ์ผํ์ง ์๋๋ค
+1
๋๊ตฐ๊ฐ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์์ต๋๊น?
TouchBackend๋ก ์ ํํ๊ณ CSS๋ฅผ ์ฌ์ฉํ์ฌ ์ปค์๋ฅผ ์ค์ ํ์ต๋๋ค.
<DndProvider backend={TouchBackend} options={{ enableTouchEvents: false, enableMouseEvents: true }}> <div className=`my-app ${isDragging ? 'dragging' : ''}`> .... draglayers here </div> </DndProvider>
.dragging { cursor: grabbing }
TouchBackend๋ก ์ ํํ๋ ๊ฒ์ด ์ ์๊ฒ ํจ๊ณผ์ ์ด์์ต๋๋ค.
DnD ๊ณต๊ธ์ :
import { DndProvider } from 'react-dnd';
import { TouchBackend } from 'react-dnd-touch-backend';
...
<DndProvider backend={TouchBackend} options={{enableMouseEvents: true}}>
...
</DndProvider>
๋๋๊ทธ ํธ๋ค๋ฌ ๊ตฌํ :
import { useDrag, useDrop } from 'react-dnd';
....
const [...] = useDrag({
...
begin: () => {
document.body.classList.add('dragging');
...
},
end: () => {
document.body.classList.remove('dragging');
...
},
});
css ํ์ผ
body.dragging: {
cursor: crosshair !important;
},
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
๋๊ตฌ๋ ์ง์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์์ต๋๊น?