Commit 3e5d554b authored by Yoon, Daeki's avatar Yoon, Daeki 😅
Browse files

drag and drop react 예제

parent 0150d3d8
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>CDN을 이용한 리엑트 드래그 앤 드롭 예제</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<h2 class="title">리엑트 드래그 앤 드롭</h2>
<!-- We will put our React component inside this div. -->
<div id="root"></div>
<!-- 리엑트 로드. -->
<!-- 노트: 배포할 때는 "development.js" 를 "production.min.js"로 변경해야 합니다. -->
<script
src="https://unpkg.com/react@18/umd/react.development.js"
crossorigin
></script>
<script
src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"
crossorigin
></script>
<script src=" https://unpkg.com/@babel/standalone/babel.min.js"></script>
<!-- 바벨을 이용하여 JSX 사용. -->
<script type="text/babel">
const questions = [
{ id: 1, name: "jiwon", order: 0 },
{ id: 2, name: "jisoo", order: 1 },
{ id: 3, name: "yeeun", order: 2 },
];
function array_move(arr, old_index, new_index) {
// 참고: https://stackoverflow.com/a/5306832
if (new_index >= arr.length) {
var k = new_index - arr.length + 1;
while (k--) {
arr.push(undefined);
}
}
arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
return arr; // for testing
}
function DragAndDropContainer({ contents }) {
const [items, setItems] = React.useState(contents);
const currentItem = React.useRef(null);
const [currentItemId, setCurrentItemId] = React.useState(null);
const onDragStart = (e) => {
currentItem.current = e.currentTarget;
const { id } = e.currentTarget;
const index = items.findIndex((item) => item.id === Number(id));
console.log(id, "drag start, ", "start index: ", index);
setCurrentItemId(Number(id));
};
const onDrop = (e) => {
e.preventDefault();
// const { id } = e.target;
const { id } = e.currentTarget;
const currentItemIndex = items.findIndex(
(item) => item.id === Number(currentItem.current.id)
);
const dropIndex = items.findIndex((item) => item.id === Number(id));
console.log(
id,
"drop, ",
"current item:",
currentItem.current.id,
", drop index:",
dropIndex,
", currentItem index:",
currentItemIndex
);
const newArray = array_move(items, currentItemIndex, dropIndex);
newArray.forEach((item, index) => {
item.order = index;
});
console.log("new array=", newArray);
setItems([...newArray]);
};
return items.map((item) => (
<DraggableItem
key={item.id}
currentItemId={currentItemId}
item={item}
onDragStart={onDragStart}
onDrop={onDrop}
>
<Question question={item} />
</DraggableItem>
));
}
function DraggableItem({
children,
currentItemId,
item,
onDragStart,
onDrop,
}) {
console.log("current item id:", currentItemId);
let counter = 0;
const handleDragStart = (e) => {
const { id } = e.target;
console.log(id, "drag start");
onDragStart(e);
};
const handleDragEnter = (e) => {
const { id } = e.currentTarget;
console.log(id, "drag enter");
counter++;
console.log("counter:", counter);
if (currentItemId !== Number(id)) {
e.currentTarget.classList.add("active");
}
};
const handleDragLeave = (e) => {
const { id } = e.currentTarget;
console.log(id, "drag leave");
counter--;
console.log("counter:", counter);
if (counter == 0) {
console.log("counter in handle drag leave", counter);
e.currentTarget.classList.remove("active");
}
};
const handleDragEnd = (e) => {
const { id } = e.currentTarget;
console.log(id, "drag end");
e.currentTarget.classList.remove("active");
e.currentTarget.classList.remove("hint");
};
const handleDragOver = (e) => {
e.preventDefault();
const { id } = e.target;
console.log(id, "drag over");
};
const handleDrop = (e) => {
e.preventDefault();
const { id } = e.target;
console.log(id, "drop");
onDrop(e);
e.currentTarget.classList.remove("active");
e.currentTarget.classList.remove("hint");
};
return (
<div
draggable={true}
className={`draggable-item`}
onDragStart={handleDragStart}
onDragEnter={handleDragEnter}
onDragLeave={handleDragLeave}
onDragEnd={handleDragEnd}
onDragOver={handleDragOver}
onDrop={(e) => handleDrop(e)}
id={item.id}
>
{children}
</div>
);
}
function Question({ question }) {
return (
<div
draggable={false}
className="question"
onDragStart={(e) => {
e.preventDefault();
e.stopPropagation();
}}
>
<h3>질문</h3>
<p>이름: {question.name}</p>
<input
type="text"
draggable={true}
onDragStart={(event) => event.preventDefault()}
/>
</div>
);
}
function QuestionsList({ questions }) {
return questions.map((question) => (
<Question key={question.id} question={question} />
));
}
function Main() {
return (
<div>
<DragAndDropContainer contents={questions} />
</div>
);
}
const domContainer = document.querySelector("#root");
const root = ReactDOM.createRoot(domContainer);
root.render(<Main />);
</script>
</body>
</html>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment