댓글 검색 목록

[javascript] JavaScript에서 기본 드래그 앤 드롭 기능을 만드는 방법

페이지 정보

작성자 운영자 작성일 21-03-01 16:56 조회 928 댓글 0

How to Create Native Drag and Drop Functionality in JavaScript 


끌어서 놓기 기능은 일반적인 기능입니다. 사용자가 원하는 위치에 개체를 잡고 놓을 수 있도록 하여 보다 직관적인 사용자 흐름을 만듭니다. 이 목적을 위해 수많은 JavaScript 라이브러리가 있습니다. 가능한 모든 프레임 워크에 대해 하나를 포함합니다. 그러나 이는 기본 Drag and Drop API를 사용하여 매우 간단하게 수행 할 수 있습니다. 이것이 우리가 살펴볼 것입니다.


이 자습서의 끝에서 Kanban 보드에 대해 다음과 같은 끌어서 놓기 기능을 만드는 방법을 배웁니다.


The output of this tutorial, drag and drop Kanban board 


DOM 설정 


먼저 DOM을 설정해 보겠습니다. 프로젝트의 루트 폴더에 index.html 파일을 만들고 다음을 추가합니다.


<main class="board">
    <div class="column column-todo">
        <h2>Todo</h2>
        <article class="card">
            <h3>Todo #1</h3>
        </article>
        <article class="card">
            <h3>Todo #2</h3>
        </article>
        <article class="card">
            <h3>Todo #3</h3>
        </article>
    </div>
    <div class="column column-ip">...</div>
    <div class="column column-done">...</div>
</main>

<script src="drag-n-drop.js"></script>


다른 두 열인 "In Progress"및 "Done"에 대해서도 동일한 구조가 적용됩니다. 보시다시피 본문 끝에 drag-n-drop.js가 드래그 앤 드롭 기능을 처리합니다.


드래그 앤 드롭 속성 추가 


그러나 드래그 앤 드롭으로 작업하려면 먼저 추가 속성으로 DOM 트리를 장식해야 합니다.


<div class="column column-todo" ondrop="drop(event)" ondragover="allowDrop(event)">
    <h2>Todo</h2>
    <article class="card" draggable="true" ondragstart="drag(event)" data-id="1">
        <h3>Todo #1</h3>
    </article>
    <article class="card" draggable="true" ondragstart="drag(event)" data-id="2">
        <h3>Todo #2</h3>
    </article>
    <article class="card" draggable="true" ondragstart="drag(event)" data-id="3">
        <h3>Todo #3</h3>
    </article>
</div>


다른 두 열은 정확히 동일한 속성을 갖게 됩니다. 데이터 ID를 제외하고. 각 기사마다 고유 한 ID가 필요합니다. 이것이 JavaScript에서 후크로 사용됩니다. 각 속성의 기능을 살펴 보겠습니다.


  • ondrop :이 이벤트는 유효한 놓기 대상에 요소를 놓을 때 시작됩니다. 드롭 기능을 처리하려는 곳입니다.
  • ondragover : 드롭 영역 위로 항목을 드래그 할 때마다 수백 밀리 초마다 실행됩니다. 이것은 많이 호출되므로 여기에 계산이 많은 함수를 배치하지 않는 것이 중요합니다.
  • draggable :이 속성은 요소를 드래그 할 수 있는지 여부를 설정합니다.
  • ondragstart :이 이벤트는 사용자가 요소를 끌기 시작할 때 시작됩니다.
  • data-id : 식별을 위해 이 속성을 사용합니다. 드래그 가능한 모든 요소는 어떤 식으로든 식별 가능해야 합니다. 이를 위해 ID 또는 맞춤 데이터 속성을 사용하는 것이 좋습니다. 어쨌든 각 항목에는 고유 한 이름이 필요합니다.

The grabbing mouse effect created with CSS 


이 단계에서 이제 요소를 드래그 할 수 있습니다. 일부 CSS의 도움으로 항목을 잡을 때마다 다른 커서 아이콘을 표시하도록 설정할 수 있습니다.


.card {
    cursor: grab;
}

.card:active {
    cursor: grabbing;
}


효과를 얻으려면 요소가 활성 상태 일 때만 커서 속성을 변경하면 됩니다. 



요소 끌기 


이제 모든 설정이 완료되었으므로 요소 드래그 기능 작성을 시작할 수 있습니다. 첫째, 작업에 대해 사용자에게 항상 시각적 인 피드백을 제공해야 합니다. 사용자가 항목을 드래그 할 때 이를 표시하려고 합니다.


1*Aev153Mq5hHqECO0xuo9NQ.gif 



요소를 이동하고 싶을 때 요소에 추가 클래스를 추가하여 이 작업을 수행 할 수 있습니다. 이를 위해 drag-n-drop.js에 다음 함수를 추가합니다.


const dragStart = event => {
    event.currentTarget.classList.add('dragging');
};

const dragEnd = event => {
    event.currentTarget.classList.remove('dragging');
};

document.querySelectorAll('.card').forEach(card => {
    card.addEventListener('dragstart', dragStart);
    card.addEventListener('dragend', dragEnd);
});


HTML과 달리 여기서는 이벤트 리스너 이름에서 "on"단어를 생략해야 합니다. 


이렇게 하면 각 카드에 두 개의 이벤트 리스너가 추가됩니다. 배열 메서드를 사용하려면 querySelectorAll에서 가져온 NodeList를 배열로 변환해야 할 수 있습니다. 글을 쓰는 시점에서 지원은 약 93 %입니다. 그리고 이러한 이벤트는 무엇을 합니까?


  • dragstart :이 이벤트는 사용자가 항목을 드래그 하기 시작할 때 시작됩니다.
  • dragend :이 이벤트는 사용자가 항목 드래그를 중지하면 시작됩니다. 이것은 사용자가 마우스 버튼을 눌렀거나 Esc 키를 눌렀다는 것을 의미합니다.

giving visual feedback to the user when dragging items 

항목을 드래그 할 때마다 드래그 클래스가 적용됩니다. 



dragging 클래스는 카드에 어떤 역할을 합니까? 불투명도와 비율을 80 %로 설정합니다.


.card {
    transition: all 0.3s cubic-bezier(0.4, 0.0, 0.2, 1);
}

.card.dragging {
    opacity: .5;
    transform: scale(.8);
}


애니메이션을 부드럽게 만들려면 전환 속성을 추가하는 것이 중요합니다. 


드래그 앤 드롭이 작동하는 이유는 무엇인가요? 


여기에서 모든 dragstart 이벤트에서 실행되는 드래그 기능도 설정해 보겠습니다. 이 함수의 유일한 책임은 항목이 삭제 될 때 나중에 사용할 수 있는 일부 데이터를 설정하는 것입니다.


const drag = event => {
    event.dataTransfer.setData('text/html', event.currentTarget.outerHTML);
    event.dataTransfer.setData('text/plain', event.currentTarget.dataset.id);
};


dataTransfer 객체는 드래그 된 객체에 대한 데이터를 보유 할 수 있습니다. setData 메소드는 MIME 유형과 페이로드라는 두 가지 매개 변수를 사용합니다. 여기에서 드래그 한 요소의 HTML 콘텐츠와 해당 ID를 저장하려고 합니다. 일을 작동 시키기 위해 우리는 다음을 원합니다.


  • 이 HTML을 놓을 때 새 열에 추가하십시오. 이를 위해 outerHTML 콘텐츠를 사용할 것입니다.
  • 원래 열에서 원래 요소를 제거하십시오. 이를 위해 ID를 사용합니다.


Dropping Elements 


이제 우리는 아이템을 떨어 뜨릴 수 있습니다. 다시 한 번, 사용자가 카드를 열 위로 드래그 할 때 시각적 단서를 추가하여 먼저 시작하겠습니다.


const dragEnter = event => {
    event.currentTarget.classList.add('drop');
};

const dragLeave = event => {
    event.currentTarget.classList.remove('drop');
};

document.querySelectorAll('.column').forEach(column => {
    column.addEventListener('dragenter', dragEnter);
    column.addEventListener('dragleave', dragLeave);
});


이번에는 dragenter 및 dragleave 이벤트를 사용하려고 합니다. dragstart 및 dragend와 매우 유사하지만 용도가 다릅니다.


  • dragenter :이 이벤트는 드래그 가능한 요소가 유효한 드롭 영역에 들어갈 때 시작됩니다.
  • dragleave :이 이벤트는 드래그 가능한 요소가 유효한 드롭 영역을 벗어날 때 시작됩니다.

Highlighting columns when dragging items over it 

항목을 열 위로 드래그 하면 파선 테두리로 강조 표시됩니다. 



CSS 측에서 전환을 다시 설정하고 점선 테두리를 추가해야 합니다.


.column {
    transition: all 0.3s cubic-bezier(0.4, 0.0, 0.2, 1);
}

.column.drop {
    border: 2px dashed #FFF;
}

.column.drop article {
    pointer-events: none;
}


또 다른 중요한 것은 카드에서 포인터 이벤트를 제거하는 것입니다. 이렇게 하면 카드를 다른 카드 위로 드래그 하더라도 열이 모든 이벤트를 수신하고 점선 테두리를 얻을 수 있습니다.


이제 남은 일은 실제로 새 열에 항목을 추가하는 것입니다. 이를 위해서는 두 가지 추가 기능이 필요합니다.


const drop = event => {
    document.querySelectorAll('.column').forEach(column => column.classList.remove('drop'));
    document.querySelector(`[data-id="${event.dataTransfer.getData('text/plain')}"]`).remove();

    event.currentTarget.innerHTML = event.currentTarget.innerHTML + event.dataTransfer.getData('text/html');
};

const allowDrop = event => {
    event.preventDefault();
};


allowDrop 함수는 브라우저의 기본 동작을 방지하는 데 사용되므로 실제로 항목을 열에 놓을 수 있습니다.


드롭 함수에서 먼저 모든 곳에서 드롭 클래스를 제거하려고 합니다 (점선 테두리를 담당 함). 그런 다음 dataTransfer.setData로 설정 한 데이터를 사용할 수 있습니다. 순서대로 :


  • 데이터 ID 속성을 기반으로 선택한 원래 카드를 제거합니다.
  • 열 끝에 새 카드를 추가합니다.

Dragging and dropping items 


요약 


그리고 그게 다야! 드래그 앤 드롭 기능이 있는 첫 번째 Kanban 보드를 방금 만들었습니다. 네이티브 드래그 앤 드롭 API에 대해 자세히 알아 보려면 MDN 웹 문서의 공식 문서를 확인하세요. 여기에는 끌어서 놓기 수명주기의 여러 단계에서 사용할 수 있는 사용 가능한 모든 끌기 이벤트가 포함됩니다.


완성 된 제품을 가지고 놀고 싶다면 이 GitHub 저장소에서 복제 할 수 있습니다. 이전에 Drag and Drop API를 사용한 적이 있습니까? 아래 댓글에 귀하의 생각을 알려주십시오! 이 기사를 읽어 주셔서 감사합니다. 즐거운 코딩 되세요!


https://www.webtips.dev/how-to-create-native-drag-and-drop-functionality-in-javascript



댓글목록 0

등록된 댓글이 없습니다.

웹학교 로고

온라인 코딩학교

코리아뉴스 2001 - , All right reserved.