본문 바로가기
dev/javascript

[javascript] jquery-ui 드래그 앤 드롭 (drag and drop)

by 최연탄 2023. 5. 27.
728x90
반응형

참고: https://www.elated.com/drag-and-drop-with-jquery-your-essential-guide/

드래그 앤 드롭은 사용자가 웹 사이트와 상호 작용하는 매우 직관적인 방법입니다. 대부분의 사람들은 다음과 같은 작업에 드래그 앤 드롭을 사용합니다.

  • 이메일 메시지를 특정 폴더로 이동할 때
  • 목록의 항목 순서를 변경할 때
  • 카드나 퍼즐 조각 같은 게임 내 객체 이동

크로스 브라우징 문제 때문에 순수 JavaScript 만으로 드래그 앤 드롭을 구현하기는 매우 어렵습니다. 하지만 최신 브라우저와 약간의 jQuery를 사용하면 간단히 구현할 수 있습니다.

이 포스트에서는 jQuery로 드래그 앤 드롭 인터페이스를 만드는 방법을 살펴보고 드래그 앤 드롭 예제인 숫자 카드 게임을 만들어보고 마무리하겠습니다.

jQuery UI

페이지에 드래그 앤 드롭 기능을 추가하려면 jQuery 라이브러리jQuery UI 플러그인을 모두 추가해야합니다. jQuery UI는 드래그 앤 드롭 기능을 포함해 다양한 위젯, 이펙트 등을 추가할 수 있는 jQuery용 플러그인 입니다.

이 두개의 라이브러리를 추가하는 가장 쉬운 방법은 다음과 같이 Google의 CDN을 사용하는 것 입니다:

<head>
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js"></script>
</head>

요소를 드래그 가능하게 만들기

div 또는 image와 같은 요소를 웹 페이지에 추가하면 해당 요소가 페이지에 고정됩니다. 그러나 jQuery UI를 사용하면 쉽게 마우스로 모든 요소를 드래그 가능하도록 할 수 있습니다.

요소를 드래그할 수 있게 하려면 요소에서 draggable() 메소드를 호출하기만 하면 됩니다. 다음은 간단한 예제입니다:

<!doctype html>
<html lang="en">

<head>
  <style>
    #makeMeDraggable {
      width: 300px;
      height: 300px;
      background: red;
    }
  </style>

  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js"></script>

  <script type="text/javascript">
    $(init);

    function init() {
      $('#makeMeDraggable').draggable();
    }
  </script>
</head>

<body>
  <div id="content" style="height: 400px;">
    <div id="makeMeDraggable"> </div>
  </div>
</body>

</html>

 

 

draggable 옵션 추가하기

다음과 같이 draggable()에 다양한 옵션을 추가하여 요소의 드래그 동작을 커스터마이즈할 수 있습니다:

$('#makeMeDraggable').draggable({
  option1: value1,
  option2: value2,
  ...
});

다음은 자주 사용하는 옵션의 속성입니다:

containment

기본적으로 드래그 가능해진 요소는 페이지의 어느 부분으로도 드래그할 수 있습니다. 하지만 요소를 특정 영역에서만 드래그되도록 하고 싶을 것 입니다. 이를 containment 옵션을 사용하여 설정할 수 있습니다.

  • parent: 요소의 드래그 영역을 부모 요소 내부로 제한합니다.
  • document: 드래그 영역을 페이지 내부로 제한합니다.
  • window: 드래그 영역을 브라우저 윈도우 내로 제한합니다.
  • a selector: 선택한 요소의 내부로 드래그 영역을 제한합니다.
  • 4개의 값을 가진 배열 ([x1, y1, x2, y2]): 좌표로 지정된 사각형 영역으로 제한합니다.

cursor

드래그 하는 동안 마우스 커서를 변경합니다. 예를 들면 이 옵션을 "move"로 설정하면 요소를 드래그할 때 마우스 포인터가 이동 커서로 바뀝니다.

snap

CSS 선택자(예: #snapToMe)로 설정하여 드래그 가능한 요소를 선택한 요소의 가장자리에 스냅(자석처럼)합니다. 이 옵션을 true로 설정하면 요소를 페이지의 다른 드래그 요소에 맞출 수도 있습니다.

stack

카드 뭉치 같은 요소의 그룹을 드래그할 수 있게 만드는 경우 일반적으로 현재 드래그된 요소가 그룹의 다른 요소 위에 나타나면 좋을 것 입니다. stack 옵션을 요소 그룹과 동일한 선택자로 설정하면 이를 수행할 수 있습니다. jQuery UI는 현재 드래그된 요소가 맨 위에 오도록 요소의 z-index 속성을 조정합니다.

draggable 옵션의 전체 목록을 알고 싶으면 jQuery UI documentation을 확인해보길 바랍니다.

위의 드래그 가능한 사각형 예제에 몇 가지 옵션을 설정해 보겠습니다. 변경된 코드는 다음과 같습니다:

function init() {
  $('#makeMeDraggable').draggable({
    containment: '#content',
    cursor: 'move',
    snap: '#content'
  });
}

See the Pen jquery-ui draggable by shinyks (@shinyks) on CodePen.

이제 박스의 드래그 영역이 어떻게 제한되고 #content div의 가장자리에 스냅하는지 확인할 수 있습니다. 드래그 하는 동안 커서도 이동 모양 커서로 바뀝니다.

헬퍼 사용

헬퍼는 원본 요소 대신 드래그되는 요소입니다. 사용자가 드래그할 때 원본 요소는 제자리에 두면서 페이지의 다른 위치로 무언가를 드래그하려 하는 경우에 유용합니다. 예를 들어 사용자가 객체 위에 있는 색상 팔레트에서 색상을 드래그 하여 색상을 지정하도록 하는 경우에 사용할 수 있습니다.

헬퍼 옵션을 사용하여 드래그 작업에 대한 헬퍼 요소를 설정합니다. 사용할 수 있는 값은 다음과 같습니다.

  • original: 기본 값 입니다. 원본 요소가 사실상 헬퍼가 되며 사용자가 드래그하면 그냥 이동됩니다.
  • clone: 요소의 복사본을 만듭니다. 원본 요소가 아닌 복사본을 이동시킵니다.
  • 함수: 사용자 지정 헬퍼를 만들 수 있습니다. 이벤트 객체를 받아 헬퍼 요소를 리턴하는 함수를 지정합니다. 그러면 원본 대신 이 요소가 이동합니다.
'clone' 이나 '함수'를 이용하여 헬퍼를 만들었다면 드래그 작업이 끝난 직후 헬퍼가 소멸됩니다. 하지만 헬퍼가 소멸되기 전에 stop 이벤트를 사용하여 헬퍼의 위치 같은 정보를 얻어낼 수도 있습니다.

다음 예제는 함수를 사용하여 드래그 작업에 대한 사용자 지정 헬퍼 요소를 만듭니다. 이는 이전 예제를 기반으로한 변경 코드입니다:

<style>
  #makeMeDraggable {
    width: 300px;
    height: 300px;
    background: red;
  }

  #draggableHelper {
    width: 300px;
    height: 300px;
    background: yellow;
  }
</style>

...

<script type="text/javascript">
  $(init);

  function init() {
    $('#makeMeDraggable').draggable({
      cursor: 'move',
      containment: 'document',
      helper: myHelper
    });
  }

  function myHelper(event) {
    return '<div id="draggableHelper">I am a helper - drag me!</div>';
  }
</script>

See the Pen jquery-ui draggable helper by shinyks (@shinyks) on CodePen.

이벤트: 드래그에 응답

사용자가 요소를 드래그할 때 드래그가 시작되고 중지된 시점과 요소의 새 위치를 알고 싶을 때가 있습니다. 다음과 같이 드래그 작업에 의해 트리거되는 다양한 이벤트에 이벤트 핸들러를 바인딩하여 이를 수행할 수 있습니다.

$('#makeMeDraggable').draggable({
  eventName: eventHandler,
  ...
});

다음은 이벤트 목록입니다:

  • create: 요소에 draggable()을 호출하여 요소가 드래그 가능하게 되었을 때 발생합니다.
  • start: 사용자가 처음으로 드래그 시작 했을 때 발생합니다.
  • drag: 요소가 드래그 중일 때 계속 발생합니다.
  • stop: 마우스를 놔서 드래그가 끝났을 때 발생합니다.

여기에 사용할 이벤트 핸들러는 두 개의 매개변수를 받습니다:

  • 이벤트 객체(event)
  • 드래그 요소를 나타내는 jQuery UI 객체

jQuery UI 객체의 다음 세 가지 속성에서 드래그한 요소에 대한 정보를 얻을 수 있습니다:

  • helper: 드래그 중인 헬퍼를 나타내는 jQuery 객체입니다. 헬퍼 옵션을 사용하지 않은 경우 이 객체는 요소 자체입니다.
  • position: 요소의 원래 위치를 기준으로 드래그한 요소 또는 헬퍼의 위치를 가지는 객체입니다. 이 객체에는 left(요소의 왼쪽 끝 x 위치), top(요소의 위쪽 끝 y 위치) 두 개의 속성이 있습니다.
  • offset: document를 기준으로 드래그한 요소 또는 헬퍼의 위치를 가지는 객체입니다. position과 마찬가지로 이 객체는 left, top 속성을 가지고 있습니다.

사용자가 마우스 버튼을 놓을 때 document를 기준으로 드래그한 요소의 최종 위치를 표시하도록 예제를 수정해 보겠습니다. 관련 코드는 다음과 같습니다:

<script type="text/javascript">
  $(init);

  function init() {
    $('#makeMeDraggable').draggable({
      cursor: 'move',
      containment: 'document',
      stop: handleDragStop
    });
  }

  function handleDragStop(event, ui) {
    var offsetXPos = parseInt(ui.offset.left);
    var offsetYPos = parseInt(ui.offset.top);
    alert("Drag stopped!nnOffset: (" + offsetXPos + ", " + offsetYPos + ")n");
  }
</script>

드래그 요소의 스타일링

때로는 드래그하는 동안 요소에 다른 모양을 보이는 것이 좋습니다. 예를 들어 드래그한 요소를 강조 표시하거나 그림자를 추가하여 페이지에서 들어 올려지는 것 처럼 보이게 할 수 있습니다.

요소가 실제로 드래그되는 동안 jQuery UI는 요소에 ui-draggable-dragging 클래스를 추가합니다. 이를 활용해 사용자가 드래그하는 동안 이 클래스의 CSS 룰을 추가해 스타일을 지정할 수 있습니다.

드래그하는 동안 빨간색에서 녹색으로 변경되도록 예제를 수정해 보겠습니다:

<style>
  #makeMeDraggable { width: 300px; height: 300px; background: red; }
  #makeMeDraggable.ui-draggable-dragging { background: green; }
</style>

droppable: 드래그 요소 받기

지금까지는 요소를 드래그 가능하게 만드는 방법을 알아봤습니다. 그리고 드래그 앤 드롭에 응답하기 위해 이벤트를 사용하는 방법도 살펴보았습니다.

하지만 드롭을 처리하는 더 쉬운 방법이 있습니다. 이는 droppable 요소를 만드는 것 입니다. droppable 요소는 드래그 앤 드롭된 draggable 요소를 받을 수 있는 요소입니다.

draggable 요소가 droppable 요소에 놓이면 droppable 요소는 drop 이벤트를 발생시킵니다. drop 이벤트에 대한 이벤트 핸들러 함수를 작성하면 어떤 draggable이 droppable에 떨어졌는지 확인할 수 있습니다.

또한 draggable이 droppable에 over 하고 out 했는지도 이벤트를 통해 알 수 있습니다. droppable 이벤트의 자세한 정보는 jQuery UI docs를 참고하기 바랍니다.

요소를 드롭 가능하게 만들려면 droppable() 메소드를 호출하면 됩니다.

위의 예제를 수정하여 드래그 가능한 요소을 드롭하기 위해 droppable 요소를 추가해보겠습니다:

<!doctype html>
<html lang="en">

<head>
  <style>
    #makeMeDraggable {
      float: left;
      width: 300px;
      height: 300px;
      background: red;
    }

    #makeMeDroppable {
      float: right;
      width: 300px;
      height: 300px;
      border: 1px solid #999;
    }
  </style>

  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js"></script>

  <script type="text/javascript">
    $(init);

    function init() {
      $('#makeMeDraggable').draggable();
      $('#makeMeDroppable').droppable({
        drop: handleDropEvent
      });
    }

    function handleDropEvent(event, ui) {
      var draggable = ui.draggable;
      alert('The square with ID "' + draggable.attr('id') + '" was dropped onto me!');
    }
  </script>
</head>

<body>
  <div id="content" style="height: 400px;">
    <div id="makeMeDraggable"> </div>
    <div id="makeMeDroppable"> </div>
  </div>
</body>

</html>

See the Pen jquery-ui draggable droppable by shinyks (@shinyks) on CodePen.

위의 codepen에서 보다시피 droppable의 drop 이벤트에 응답하기 위해 handleDropEvent() 라는 이벤트 핸들러 함수를 만들었습니다. draggable 이벤트와 마찬가지로 핸들러는 이벤트 jQuery UI 객체를 받습니다.

이 ui 객체에는 draggable 속성이 있는데 이는 droppable 요소로 드래그된 draggable 요소입니다. 우리의 함수는 jQuery attr() 메소드와 이 객체를 사용하여 드롭된 요소("makeMeDraggable")의 ID를 찾아 alert()을 사용하여 표시합니다.

예제: 드래그 앤 드롭 숫자 카드 게임

실질적인 예제가 작동하는 것을 보면 위의 많은 개념을 더 이해하기 쉬울 것 입니다. 이 예제는 어린이를 위한 간단한 숫자 카드 게임입니다. 사용자에게는 무작위로 10 개의 숫자 카드와 카드를 놓을 수 있는 10 개의 슬롯이 제공됩니다. 게임의 목표는 10 장의 카드를 모두 올바른 슬롯에 놓은 것 입니다.

step 1: markup

게임의 HTML은 간단합니다:

<!doctype html>
<html lang="en">

<head>
  <title>A jQuery Drag-and-Drop Number Cards Game</title>
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
  <link rel="stylesheet" type="text/css" href="style.css">

  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js"></script>

  <script type="text/javascript">
    // JavaScript will go here
  </script>
</head>

<body>
  <div id="content">
    <div id="cardPile"></div>
    <div id="cardSlots"></div>

    <div id="successMessage">
      <h2>You did it!</h2>
      <button onclick="init()">Play Again</button>
    </div>
  </div>
</body>

</html>

head 영역에서 jQuery 및 jQuery UI 라이브러리를 추가하고 step 4에서 만들 style.css 파일을 연결했습니다. 또한 JavaScript 코드에 대한 script 요소를 추가했습니다. body에는 다음과 같은 요소가 있습니다:

  • 게임을 포함하는 "#content" div
  • 무작위의 10 개 카드를 가질 "#cardPile" div
  • 카드를 드롭할 10 개의 슬롯을 가지는 "#cardSlots" div
  • "You did it!" 메지시와 "play again" 버튼을 표시할 "#successMessage" div

step 2: init() 함수

게임을 설정하는 첫 번째 JavaScript 코드:

var correctCards = 0;
$(init);

function init() {
  $('#successMessage').hide();
  $('#successMessage').css({
    left: '580px',
    top: '250px',
    width: 0,
    height: 0
  });

  correctCards = 0;
  $('#cardPile').html('');
  $('#cardSlots').html('');

  var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
  numbers.sort(function () { return Math.random() - .5 });

  for (var i = 0; i < 10; i++) {
    $('<div>' + numbers[i] + '</div>').data('number', numbers[i]).attr('id', 'card' + numbers[i]).appendTo('#cardPile').draggable({
      containment: '#content',
      stack: '#cardPile div',
      cursor: 'move',
      revert: true
    });
  }

  var words = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten'];
  for (var i = 1; i <= 10; i++) {
    $('<div>' + words[i - 1] + '</div>').data('number', i).appendTo('#cardSlots').droppable({
      accept: '#cardPile div',
      hoverClass: 'hovered',
      drop: handleCardDrop
    });
  }
}

위의 코드를 분석해 보겠습니다:

  1. correctCards 변수 초기화: 먼저 올바르게 드롭된 카드의 수를 알아내기 위해 correctCards 라는 변수를 설정했습니다. 이 값이 10에 도달하면 사용자가 게임에서 승리한 것 입니다.
  2. document가 ready 상태일 때 init() 호출: $(init)을 실행해 DOM이 로드되면 init() 함수를 실행하게 했습니다.
  3. 성공 메시지 숨기기: init() 함수 내에서 먼저 #successMessage div를 숨기고 이 성공 메시지 div의 가로와 세로 길이를 0으로 설정해 게임 승리 시 튀어나오도록 했습니다.
  4. 게임 리셋: 게임이 이미 시작된 후에 init()을 호출할 수 있으므로 게임을 다시 시작할 수 있도록 correctCards를 0으로 설정하고 #cardPile 및 #cardSlots div를 지웁니다.
  5. 무작위 카드 생성: 카드 더미를 만들기 위해 먼저 1에서 10까지의 숫자를 가지는 숫자 배열을 만든 다음 무작위 정렬 기능으로 배열을 정렬하여 숫자를 섞습니다.
    그런 다음 숫자 배열의 각 요소를 루프돌아 각 숫자에 대한 div 카드 요소를 만듭니다. div 안에 숫자를 배치하여 카드에 표시되도록 합니다. div 객체를 생성했으면 jQuery의 data() 메서드를 사용하여 객체 내부의 'number' 키에 카드의 번호를 저장합니다.
    또한 카드 div에 'cardn'이라는 id를 부여합니다. 여기서 n은 카드 번호입니다. 이렇게 하면 CSS에서 각 카드에 다른 색상을 지정할 수 있습니다. 그런 다음 카드를 #cardPile div에 추가합니다.
    가장 흥미로운 부분은 draggable() 메소드 호출입니다:
    • 카드를 draggable로 만들기
    • containment를 사용해 #content div 내로만 드래그 가능하게 하기
    • stack을 사용해 드래그된 카드가 항상 다른 것의 위에 가도록 하기
    • cursor로 드래그하는 동안 마우스 커서를 이동 커서로 바꾸기
    • revert 옵션을 true로 하여 카드를 드롭했을 때 원래 위치로 돌아도록 하기. 올바른 슬롯에 드롭했다면 이 옵션 끄기
  6. 카드 슬롯 생성: init() 함수의 마지막 부분은 카드를 드래그할 10개의 슬롯을 만드는 것입니다. "one"에서 "ten" 까지의 단어를 가지는 words라는 배열을 만든 다음 words 배열의 요소를 루프돌아 각 숫자에 대한 슬롯 div를 만듭니다. 이전과 마찬가지로 data()를 사용하여 슬롯 번호를 기록하므로 사용자가 올바른 카드를 올바른 슬롯으로 드래그했는지 확인할 수 있으며 슬롯을 #cardSlots div에 추가합니다.
    그 다음 슬롯이 드래그된 카드를 받을 수 있도록 droppable() 메소드를 호출합니다. "#cardPile div" 선택자와 accept 옵션을 사용하여 슬롯이 다른 드래그 가능한 요소가 아닌 숫자 카드만 받도록 합니다. hoverClass 옵션은 draggable이 위에 있을 때 droppable에 CSS 클래스를 추가합니다. 이 옵션을 사용하여 강조 표시할 요소에 'hovered' 클래스를 추가합니다. 마지막으로 사용자가 카드를 드롭 가능 항목에 드롭할 때 트리거되는 handleCardDrop()이라는 드롭 이벤트 핸들러를 설정합니다.

step 3: handleCardDrop() 이벤트 핸들러

droppable의 드롭 이벤트를 처리할 JavaScript의 마지막 부분인 handleCardDrop() 핸들러입니다:

function handleCardDrop(event, ui) {
  var slotNumber = $(this).data( 'number' );
  var cardNumber = ui.draggable.data( 'number' );

  if ( slotNumber == cardNumber ) {
    ui.draggable.addClass( 'correct' );
    ui.draggable.draggable( 'disable' );
    $(this).droppable( 'disable' );
    ui.draggable.position( { of: $(this), my: 'left top', at: 'left top' } );
    ui.draggable.draggable( 'option', 'revert', false );
    correctCards++;
  } 

  if ( correctCards == 10 ) {
    $('#successMessage').show();
    $('#successMessage').animate( {
      left: '380px',
      top: '200px',
      width: '400px',
      height: '100px',
      opacity: 1
    } );
  }
}

1. 슬롯 번호와 카드 번호 가져오기

가장 먼저 할 일은 카드가 드롭된 슬롯의 번호와 드롭된 카드의 번호가 일치하는지 확인하는 것 입니다.

우리의 함수는 droppaable 요소에 대한 이벤트 핸들러이므로 this 변수를 통해 요소를 가져올 수 있습니다. 그런 다음 요소를 $() 함수로 감싸서 jQuery 객체로 바꾼 다음 data() 메소드를 사용하여 'number' 키의 값을 검색하고 그 값을 slotNumber에 저장합니다.

마찬가지로 ui 객체의 draggable 속성에는 드래그된 카드를 나타내는 jQuery 객체가 포함되어 있습니다. data()를 사용하여 'number' 키를 읽음으로써 cardNumber에 저장하는 카드 번호를 얻습니다.

2. 카드와 슬롯이 매치되면 슬롯에 넣기

두 개의 숫자가 일치하면 올바른 카드를 슬롯에 넣습니다. 먼저 CSS로 색상을 변경할 수 있게 'correct' 클래스를 카드에 추가합니다. 그런 다음 disable 메소드를 호출하여 draggable 및 droppable을 모두 비활성화합니다. 이렇게 하면 사용자가 이 카드를 드래그하거나 다른 카드를 이 슬롯으로 다시 드래그할 수 없습니다.

카드와 슬롯을 비활성화한 후 position() 메소드를 호출하여 슬롯 바로 위에 카드를 배치합니다. 이 방법을 사용하면 다른 요소를 기준으로 요소를 배치할 수 있으며 droppable 요소와도 잘 어울립니다. 이 경우 카드(ui.draggable)의 왼쪽 상단 모서리(my: 'left top')를 슬롯($this)의 상단 왼쪽 모서리(at: 'left top')에 배치합니다.

마지막으로 카드의 revert 옵션을 false로 설정합니다. 이렇게 하면 카드를 드롭한 후 원래 위치로 다시 원복되는 것을 방지할 수 있습니다. 또한 올바르게 드롭된 카드의 수를 추적하기 위해 correctCards 변수를 증가시킵니다.

3. 승리 확인

correctCards의 값이 10 이면 승리하게 됩니다. 성공 메시지를 표시한 다음 너비와 높이를 0에서 최대 너비와 높이까지 애니메이션을 적용하여 확대/축소 효과를 만듭니다. 성공 메시지에는 클릭 시 init() 함수를 트리거하여 새 게임을 시작하는 Play Again 버튼이 있습니다.

step 4: CSS

카드 게임의 마지막 단계는 CSS를 사용하여 페이지, 카드, 카드 슬롯의 스타일을 지정하는 것 입니다. 다음은 전체 style.css 파일입니다:

body {
  margin: 30px;
  font-family: "Georgia", serif;
  line-height: 1.8em;
  color: #333;
}

h1,
h2,
h3,
h4 {
  font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
}

#content {
  margin: 80px 70px;
  text-align: center;
  -moz-user-select: none;
  -webkit-user-select: none;
  user-select: none;
}

.wideBox {
  clear: both;
  text-align: center;
  margin: 70px;
  padding: 10px;
  background: #ebedf2;
  border: 1px solid #333;
}

.wideBox h1 {
  font-weight: bold;
  margin: 20px;
  color: #666;
  font-size: 1.5em;
}

#cardSlots {
  margin: 50px auto 0 auto;
  background: #ddf;
}

#cardPile {
  margin: 0 auto;
  background: #ffd;
}

#cardSlots,
#cardPile {
  width: 910px;
  height: 120px;
  padding: 20px;
  border: 2px solid #333;
  -moz-border-radius: 10px;
  -webkit-border-radius: 10px;
  border-radius: 10px;
  -moz-box-shadow: 0 0 .3em rgba(0, 0, 0, .8);
  -webkit-box-shadow: 0 0 .3em rgba(0, 0, 0, .8);
  box-shadow: 0 0 .3em rgba(0, 0, 0, .8);
}

#cardSlots div,
#cardPile div {
  float: left;
  width: 58px;
  height: 78px;
  padding: 10px;
  padding-top: 40px;
  padding-bottom: 0;
  border: 2px solid #333;
  -moz-border-radius: 10px;
  -webkit-border-radius: 10px;
  border-radius: 10px;
  margin: 0 0 0 10px;
  background: #fff;
}

#cardSlots div:first-child,
#cardPile div:first-child {
  margin-left: 0;
}

#cardSlots div.hovered {
  background: #aaa;
}

#cardSlots div {
  border-style: dashed;
}

#cardPile div {
  background: #666;
  color: #fff;
  font-size: 50px;
  text-shadow: 0 0 3px #000;
}

#cardPile div.ui-draggable-dragging {
  -moz-box-shadow: 0 0 .5em rgba(0, 0, 0, .8);
  -webkit-box-shadow: 0 0 .5em rgba(0, 0, 0, .8);
  box-shadow: 0 0 .5em rgba(0, 0, 0, .8);
}

#card1.correct {
  background: red;
}

#card2.correct {
  background: brown;
}

#card3.correct {
  background: orange;
}

#card4.correct {
  background: yellow;
}

#card5.correct {
  background: green;
}

#card6.correct {
  background: cyan;
}

#card7.correct {
  background: blue;
}

#card8.correct {
  background: indigo;
}

#card9.correct {
  background: purple;
}

#card10.correct {
  background: violet;
}

#successMessage {
  position: absolute;
  left: 580px;
  top: 250px;
  width: 0;
  height: 0;
  z-index: 100;
  background: #dfd;
  border: 2px solid #333;
  -moz-border-radius: 10px;
  -webkit-border-radius: 10px;
  border-radius: 10px;
  -moz-box-shadow: .3em .3em .5em rgba(0, 0, 0, .8);
  -webkit-box-shadow: .3em .3em .5em rgba(0, 0, 0, .8);
  box-shadow: .3em .3em .5em rgba(0, 0, 0, .8);
  padding: 20px;
}

위의 CSS를 적용하면 다음의 codepen과 같은 결과를 얻을 수 있습니다.

See the Pen jquery-ui drag and drop by shinyks (@shinyks) on CodePen.

정리

이 포스트에서는 jQuery 및 jQuery UI 라이브러리를 사용하여 웹 페이지에 드래그 앤 드롭 기능을 추가하는 방법을 알아봤습니다.

  • draggable 플러그인으로 어떠한 요소라도 draggable 위젯으로 만들 수 있습니다.
  • draggable 요소의 옵션을 알아봤습니다.
  • 헬퍼를 사용하여 원본 요소 대신 드래그되는 요소를 만들었습니다.
  • draggable 이벤트로 드래그된 요소의 정보를 얻을 수 있습니다.
  • 요소가 드래그되는 동안 스타일링을 변경할 수 있습니다.
  • droppable 플러그인으로 드롭된 요소를 제어할 수 있습니다.

관련 글

자바스크립트 드래그 앤 드롭 (draggable)

반응형

댓글