팝, 잠금, (드래그) 앤 드롭



끌어서 놓을 수 있는 구성 요소를 만드는 방법을 배우고 싶다고 결정했을 때 구현하려면 거의 확실히 타사 라이브러리가 필요한 완전히 복잡한 리가 마롤이 될 것이라고 생각했습니다. 전체 "드래그 앤 드롭"개념에 자체 HTML API가 있고 사용하기가 전혀 어렵지 않다는 사실에 기분 좋게 놀랐습니다! 그렇다면 어떻게 작동하며 자신의 응용 프로그램에서 어떻게 사용할 수 있습니까?

HTML Drag and Drop API documentation - 스스로 문서를 파고들고 싶은 유형이라면 여기에서 할 수 있습니다!

무엇을 드래그하시겠습니까? 드래그 가능하게 만드세요!



우리의 경우 드래그 퀸 목록이 있고 즐겨찾기를 끌어서 놓아 새 목록을 만들고 싶습니다. 기본적으로 HTML 요소는 예상할 수 있듯이 드래그할 수 없습니다. 인터넷에 있는 오래된 것을 클릭하고 인터넷의 다른 오래된 장소로 드래그할 수 있다면 좀 이상할 것입니다. 그렇죠?

무엇을 드래그하시겠습니까? 우리의 경우, 이 정렬되지 않은 목록에서 목록 항목을 드래그할 수 있기를 원합니다.

  const QueensList = () => {
    const queens = [
      'Divine',
      'Lady Bunny',
      'Sasha Velour',
      'Vaginal Creme Davis',
      'The Fabulous Wonder Twins'
    ]

    return (
      <ul>
        {
          queens.map((queenName) => (
            <Queen name={queenName} />
          ))
        }
      </ul>
    )
  }

  const Queen = ({ name }) => (
    <li>
      {name}
    </li>
  )

이러한 항목을 드래그할 수 있도록 하려면 다음과 같이 표시해야 합니다.

    const Queen = ({ name }) => (
      <li draggable='true'>{name}</li>
    )

목록 항목의 텍스트를 다른 요소로 만들려면 드래그 이벤트의 드래그 데이터에도 항목을 추가해야 합니다. 드래그 이벤트의 setData() 속성에 dataTransfer 메서드를 사용하여 이 작업을 수행할 수 있으며 onDragStart 메서드(추측하셨겠지만 드래그 이벤트가 시작될 때 트리거됨)에서 이 작업을 수행할 수 있습니다.

  const onDragStart = (dragEvent) => {
    // I added a border at this point so I can 
    // clearly see what's being dragged
    dragEvent.currentTarget.style.border = '1px solid pink'
    dragEvent.dataTransfer.setData('text/plain', dragEvent.target.id)
  }

  const Queen = ({ name }) => (
    <li
      draggable='true'
      // also added a unique id so the list item can be "found"
      id={`source-${name.split(' ').join('-')}`}
      onDragStart={onDragStart}
    >
      {name}
    </li>
  )

어디로 드래그하시겠습니까?



다음으로, 우리는 이 여왕들을 어딘가에 떨어뜨려야 하기 때문에 드롭 타겟 역할을 할 또 다른 구성 요소를 만듭니다. 항목을 드래그하는 위치를 시각적으로 확인할 수 있도록 "Drop Target"이라는 매우 편리한 이름의 목록 항목이 있는 FavoriteQueens의 새로운 비순차 목록은 어떻습니까?

  const FavoriteQueens = () => (
    <ul
      id='target'
      onDragEnter={onDragEnter}
      onDragOver={onDragOver}
      onDrop={onDrop}
    >
      <li>Drop Target</li>
    </ul>
  )

항목을 드롭하려는 요소에 대해 다음을 수행합니다.
  • id로 식별
  • 은 세 가지 방법을 정의합니다.
  • onDragEnter 드래그할 수 있는 항목
  • 을 가지고 들어갈 때 발생하는 일을 정의합니다.
  • onDragOver 항목을 드래그할 때 발생하는 상황 정의
  • onDrop 어떤 일이 일어날지 정의하기 위해… 예, 다시 추측했습니다…

  • onDragEnter 의 경우 dragEvent.preventDefault() 를 호출하기만 하면 됩니다. 이것은 우리가 원하는 모든 것이 드래그 이벤트가 발생하지 않도록 하는 기본 동작을 방지하기 때문입니다. 우리는 확실히 드래그 이벤트가 일어나기를 원합니다!!!

          const onDragEnter = (dragEvent) => {
            dragEvent.preventDefault();
          }  
    
    onDragOver 의 경우 동일한 작업을 수행하고 기본 동작을 방지하려고 합니다. 재미를 위해 단색 녹색 테두리도 추가하여 시각적 피드백을 받고 드래그할 수 있는 영역 위에 도달했음을 알 수 있습니다.

        const onDragOver = (dragEvent) => {
            dragEvent.preventDefault();
            dragEvent.target.style.border = '1px solid green'
          }
    

    마지막으로 onDrop 이벤트의 경우 기본 동작을 (다시) 방지하는 것으로 시작합니다. 그런 다음 드래그 이벤트의 getData 속성에 dataTransfer 메서드를 사용하여 방금 드래그한 요소를 검색합니다. 해당 데이터를 사용하여 새 요소를 만들고 대상에 추가합니다. 이 시점에서 양쪽 끝의 테두리 스타일도 제거합니다. 클릭 및 드래그가 완료되어 시각적 피드백이 더 이상 필요하지 않기 때문입니다. 마지막으로 드래그 이벤트의 clearData 속성에서 dataTransfer 메서드를 호출하여… 데이터를…

          const onDrop = (dragEvent) => {
            dragEvent.preventDefault();
            const data = dragEvent.dataTransfer.getData('text');
            const newElement = document.getElementById(data)
            dragEvent.target.appendChild(newElement);
            dragEvent.target.style.border = 'none'
            newElement.style.border = 'none'
            dragEvent.dataTransfer.clearData();
          }
    

    모두 함께 봅시다! App.js의 드래그 앤 드롭 가능한 콘텐츠를 귀여운 릴create-react-app 애플리케이션으로 소개하겠습니다! 전체 코드는 https://github.com/julienfitz/drag-and-drop-queens에서 볼 수 있습니다.



    import React from 'react'
    
    const App = () => {
      const onDragStart = (dragEvent) => {
        // I added a border at this point so I can 
        // clearly see what's being dragged
        dragEvent.currentTarget.style.border = '1px solid pink'
        dragEvent.dataTransfer.setData('text/plain', dragEvent.target.id)
      }
    
      const onDragEnter = (dragEvent) => {
        dragEvent.preventDefault()
      }  
    
      const onDragOver = (dragEvent) => {
        dragEvent.preventDefault()
        dragEvent.target.style.border = '1px solid green'
      }
    
      const onDrop = (dragEvent) => {
        dragEvent.preventDefault()
        const data = dragEvent.dataTransfer.getData('text')
        const newElement = document.getElementById(data)
        dragEvent.target.appendChild(newElement)
        dragEvent.target.style.border = 'none'
        newElement.style.border = 'none'
        dragEvent.dataTransfer.clearData()
      }
    
      const Queen = ({ name }) => (
        <li
          draggable='true'
          // also added a unique id so the list item can be "found"
          id={`source-${name.split(' ').join('-')}`}
          onDragStart={onDragStart}
        >
          {name}
        </li>
      )
    
      const QueensList = () => {
        const queens = [
          'Divine',
          'Lady Bunny',
          'Sasha Velour',
          'Vaginal Creme Davis',
          'The Fabulous Wonder Twins'
        ]
    
        return (
          <ul>
            {
              queens.map((queenName) => (
                <Queen name={queenName} />
              ))
            }
          </ul>
        )
      }
    
      const FavoriteQueens = () => (
        <ul
          id='target'
          onDragEnter={onDragEnter}
          onDragOver={onDragOver}
          onDrop={onDrop}
        >
          <li>Drop Target</li>
        </ul>
      )
    
      return (
        <>
          <QueensList />
          <FavoriteQueens />
        </>
      )
    }
    
    export default App    
    

    좋은 웹페이지 즐겨찾기