본문 바로가기
프로그래밍/Javascript

드래그 앤 드랍

by o테리o 2010. 8. 12.
드래그 앤 드랍을 자바 스크립트로 구현하는 예제이다.

<div>드래그 앤 드랍</div>

위의 div 태그를 드래그 앤 드랍하려면 우선 onmousedown 속성을 설정한다.

<div onmousedown="drag(this, event);">드래그 앤 드랍</div>

사용자가 div 태그를 마우스로 누른 순간에 onmousedown 속성으로 선언한 자바 스크립트 함수(drag - 아래에서 설명)가 수행된다.

drag 함수는 다음과 같다.

/*
drag 함수의 첫번째 파라미터(element)는 드래그할 대상이고, 두번째 파라미터(event)는 이벤트이다.
*/


function drag(element, ev) {
}


다음은 drag 함수 구현부이다. 우선 마우스 커서를 드래그를 의미하는 것으로 변경한다.

document.body.style.cursor = "move";

/*
마우스 커서는 드래그할 대상(<div>드래그 앤 드랍</div>)이 아닌 body에 설정해야 한다. 마우스를 드래그를 하면 마우스 포인터가 대상 밖으로 벗어나는 것이 일반적이기 때문이다.
*/


그리고 document에 대해서 onmousemove 이벤트 리스너를 설정한다.

/*
onmousemove 로 설정한 함수는 마우스가 움직일 때마다 반복적으로 계속 호출된다.  마우스 커서와 동일한 이유로 드래그할 대상(<div>드래그 앤 드랍</div>)이 아닌 document에 대해서 onmousemove 이벤트 리스너를 등록한다.
*/

document.onmousemove = function(ev) {
    // IE 6.0은 해당 함수 파라미터로 이벤트 객체를 전달하지 않는다.
    // 대신 window.event 변수로 전달한다.
    ev = ev || window.event;

    // prototype이 제공하는 API로 현재 마우스 커서의 위치 값을 추출한다.
    var top = Event.pointerY(ev);
    var left = Event.pointerX(ev);

    // 드래그할 대상을 움직이게 하려면 onmousemove 이벤트 리스너가 호출될 때마다
    // CSS 속성으로 위치 값을 변경한다.
    // position 속성을 absolute로 설정하고 left와 top 속성으로 위치를 지정한다.
    element.style.position = "absolute";
   element.style.left = left + "px";
   element.style.top = top + "px";
    // left, top 속성을 설정할 때 px(단위)를 명기해야 한다.

    // prototype이 제공하는 API로 이벤트를 종료하고 false를 반환한다. 그렇지 않으면
    // 주변에 있는 텍스트를 선택하는 것과 같은 현상이 일어난다.
    Event.stop(ev);
    return false;
  };

마우스 커서 위치 값 추출에 Prototype 라이브러리를 사용했다. 자세한 사항은 다음을 참조한다.


그리고 document에 대해서 onmouseup 이벤트 리스너를 설정한다.

/*
onmouseup으로 설정한 함수는 마우스 누른 것을 해제할 때(드랍) 호출된다. 마우스 커서와 동일한 이유로 드래그할 대상(<div>드래그 앤 드랍</div>)이 아닌 document에 대해서 onmousemove 이벤트 리스너를 등록한다.
*/

document.onmouseup = function(ev) {
    ev = ev || window.event;
    // 마우스 커서를 초기화한다.
    document.body.style.cursor = "auto";
   
   // 여기에서 필요한 작업을 한다. 이는 드래그 앤 드랍 성격에 따라서 달라진다.
   // 예를 들어, AJAX를 이용해서 현재 위치 값을 서버에 저장할 수도 있다.

    // 드래그앤 드랍과 관련한 이벤트 리스너를 초기화한다.
    document.onmousemove = null;
    document.onmouseup = null;
    Event.stop(ev);
    return false;
  };


최종적인 drag 함수는 다음과 같다.

function drag(element, ev) {
  document.body.style.cursor = "move";

  document.onmousemove = function(ev) {
    ev = ev || window.event;
    var top = Event.pointerY(ev);
    var left = Event.pointerX(ev);
    element.style.position = "absolute";
    element.style.left = left + "px";
    element.style.top = top + "px";
    Event.stop(ev);
    return false;
  };

  document.onmouseup = function(ev) {
    ev = ev || window.event;
    document.body.style.cursor = "auto";

    // 필요한 작업 수행

    document.onmousemove = null;
    document.onmouseup = null;
    Event.stop(ev);
    return false;
  };
  Event.stop(ev);
  return false;
}