최근 인터넷에서 구글의 개인화된 홈페이지와 MSN 공간과 유사한 드래그 앤 드롭 구현을 찾는 몇몇 친구들을 보았는데, 우연히 아래와 같은 예를 발견하게 되었는데, 문제점이 많아 다시 작성하고 개선하여 일반화하였습니다. 함수의 구체적인 구현은 다음과 같습니다:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>BlackSoul의 드래그 앤 드롭 데모</title >
<!- -
________
|---------저자: BlackSoul---------|
------------2006.03.30------ ---- ----|
|[email protected] ------ |
------------QQ:9136194---- ---- ------|
|------http://blacksoul.cnblogs.cn---|
================== ==== ===============
-->
<style type="text/css">
본문
{
여백:0px
}
#aim /*대상 레이어 스타일 설정*/
{
position:absolute;/*레이어 위치를 제어하는 데 필요한 스타일*/
width
:200px
border:1px
background-color:#FFCCCC
;;
#sourceLayer, #cloneLayer
{
position:absolute;/*레이어 위치를 제어하는 데 필요한 스타일*/
width
:300px;
height:50px;
border:1px
background-color:#CCCCCC
;
.docked
{
디스플레이:없음;
필터:알파(불투명도=100)
;
.actived
{
디스플레이:블록;
필터:알파(불투명도=70)
}
</style>
</head>
<본문>
<div id="aim">배치 범위</div>
<div id="sourceLayer" unselectable="off"><img src="
<div id="cloneLayer" class="docked" unselectable="off"> </div>
<script type="text/javascript" 언어="javascript">
<!--
/*
============================= =======
|---------작가: BlackSoul---------
|----------2006.03.30---- ---------|[email protected]
|----------QQ:9136194--- -----------
|------http://blacksoul.cnblogs.cn---|
================= ==================
*/
//레이어 객체 설정
var aim
var
sourceLayer;
//각 레이어의 초기 위치를 정의합니다.
var aimX
; var
orgnX
;
//드래그 중 변수
var draging = false; //드래그 중인지 여부
var offsetX = 0; //X 방향의 왼쪽 및 오른쪽 오프셋
var offsetY = 0; //Y 방향의 위쪽 및 아래쪽 오프셋
var back; //애니메이션 객체 반환
var thisX;
//현재 복제 레이어의 Y 위치
var time;
//변위
속도
//드래그 정보 초기화
/*
initAimX 타겟 x 좌표
initAimY 타겟 y 좌표
initOrgnX 드래그 소스 x 좌표
initOrgnY 드래그 소스 y 좌표
*/
//레이어 객체 가져오기
function getLayer(inAim,inSource,inClone)
{
aim = document.getElementById(inAim);
sourceLayer = document.getElementById(inSource);
cloneLayer = document.getElementById(inClone)
}
function initDrag(initAimX,initAimY,initOrgnX,initOrgnY)
{
aimX = initAimX;
aimY = initAimY;
orgnX = initOrgnX;
orgnY
= initOrgnY;
aim.style.pixelLeft
= aimX;
=
aimYer.style.pixelLeft = orgnX;
sourceLayer.style.pixelTop = orgnY;
cloneLayer.style.pixelTop
= orgnY
;
//드래그
함수 준비 BeforeDrag()
{
if (event.button != 1)
{
return;
}
cloneLayer.innerHTML = sourceLayer.innerHTML; //드래그 소스 콘텐츠 복사
offsetX = document.body.scrollLeft + event.clientX - sourceLayer.style.pixelLeft;
offsetY = document.body.scrollTop + event.clientY - sourceLayer.style.className
="
actived"
}
//드래그
함수 OnDrag()
{
if(!draging)
{
return;
}
//위치 업데이트
event.returnValue = false;
cloneLayer.style.pixelLeft = document.body.scrollLeft + event.clientX -
cloneLayer.style .pixelTop
;= document.body.scrollTop + event.clientY - 오프셋Y
}
//드래깅
기능 종료 EndDrag()
{
if (event.button != 1)
{
return
}
draging = false;
if (event.clientX >= aim.style.pixelLeft && event.clientX <= (aim.style.pixelLeft + aim.offsetWidth) &&
event.clientY >= aim.style.pixelTop && event.clientY <= (aim.style .pixelTop + aim.offsetHeight))
{
//드래그 레이어는 대상에 위치하며 자동으로 대상 위치에 배치됩니다
sourceLayer.style.pixelLeft = aim.style.pixelLeft =
sourceLayer.style.pixelTop = aim.style.pixelTop;
cloneLayer.className = "docked";
/*
** 이 작업을 완료한 후 xml을 사용하여 현재 위치를 저장할 수 있습니다.
** 다음에 사용자가 입력하면
소스 드래그 레이어가 xml의 데이터로 초기화됩니다
.*/
}
else
{
//드래그 앤 드롭 대상 레이어 외부에 위치, 드래그 소스 위치 복원
thisX = cloneLayer.style.pixelTop
;
offSetX
= Math.abs(thisX - orgnX);
(thisY - orgnY);
time = 500;//애니메이션 시간 설정
stepX = Math.floor((offSetX/time)*20);
stepY = Math.floor((offSetY/time)*20)
; 0)
stepX = 2;
if (stepY == 0)
stepY = 2;
//반환 애니메이션 시작
moveStart()
}
}
function moveStart()
{
back = setInterval("MoveLayer();",15)
}
//반환된 애니메이션 효과 설정
function MoveLayer()
{
//타겟의 왼쪽 상단에 위치
if(cloneLayer.style.pixelLeft <= orgnX && cloneLayer.style.pixelTop <= orgnY)
{
cloneLayer.style.pixelLeft + = stepX;
cloneLayer.style
.pixelTop += stepY;
//변위가 목표를 초과하면 속도를 pix로 설정하고 여기서는 스프링 효과를 얻습니다.
pixelLeft > orgnX)
{
stepX = 1;
}
if(cloneLayer.style.pixelTop > orgnY)
{
stepY = 1;
}
//X축 또는 Y축의 좌표가 동일하면 변위가 발생하지 않습니다
. if(cloneLayer.style .pixelLeft == orgnX)
{
stepX = 0;
}
if(cloneLayer .style.pixelTop == orgnY)
{
stepY = 0;
}
if
(cloneLayer.style.pixelLeft == orgnX && cloneLayer.style.pixelTop == orgnY)
끝이동()
}
}
//타겟의 왼쪽 하단에 위치
else if(cloneLayer.style.pixelLeft <= orgnX && cloneLayer.style.pixelTop >= orgnY)
{
cloneLayer.style.pixelLeft += stepX;
cloneLayer.style.pixelTop -= stepY;
if(cloneLayer.style .pixelLeft>
orgnX)
{
stepX = 1;
}
if(cloneLayer.style.pixelTop<
orgnY)
{
stepY = 1;
}
if(cloneLayer.style.pixelLeft == orgnX)
{
stepX = 0;
(cloneLayer.style.pixelTop == orgnY)
{
stepY = 0;
}
if(cloneLayer.style.pixelLeft == orgnX && cloneLayer.style.pixelTop == orgnY)
{
EndMove()
}
}
//타겟의 오른쪽 상단에 위치
else if(cloneLayer.style.pixelLeft >= orgnX && cloneLayer.style.pixelTop <= orgnY)
{
cloneLayer.style.pixelLeft -= stepX;
cloneLayer.style.pixelTop += stepY ;
if(cloneLayer.style .pixelLeft < orgnX)
{
stepX = 1;
}
if(cloneLayer.style.pixelTop > orgnY)
{
stepY = 1;
}
if(cloneLayer.style.pixelLeft == orgnX)
{
stepX = 0
;
if(cloneLayer.style.pixelTop == orgnY)
{
stepY = 0;
}
if(cloneLayer.style.pixelLeft == orgnX && cloneLayer.style.pixelTop == orgnY)
{
EndMove()
}
}
//타겟의 오른쪽 상단에 위치
else if(cloneLayer.style.pixelLeft >= orgnX && cloneLayer.style.pixelTop >= orgnY)
{
cloneLayer.style.pixelLeft -= stepX;
cloneLayer.style.pixelTop -= stepY ;
if(cloneLayer.style .pixelLeft < orgnX)
{
stepX = 1;
}
if(cloneLayer.style.pixelTop < orgnY)
{
stepY = 1;
}
if(cloneLayer.style.pixelLeft == orgnX)
{
stepX = 0
;
if(cloneLayer.style.pixelTop == orgnY)
{
stepY = 0;
}
if(cloneLayer.style.pixelLeft == orgnX && cloneLayer.style.pixelTop == orgnY)
{
EndMove()
}
}
//목표에 도달
else
{
EndMove()
}
}
//애니메이션 반환 중지
함수 EndMove()
{
sourceLayer.style.pixelTop=
orgnY;
cloneLayer.style.pixelTop
= orgnY
;
ClearInterval(뒤로)
}
//주요 드래그 기능
function startDraging(inAim,inSource,inClone,initAimX,
initAimY,initOrgnX,initOrgnY)
{
getLayer(inAim,inSource,inClone)
initDrag(initAimX,initAimY,initOrgnX,initOrgnY);
sourceLayer.onmousedown = BeforeDrag;
onmousemove = OnDrag; //여기서 cloneLayer를 사용하면 드래그하는 동안 cloneLayer의 내용이 선택되고 일부 버그가 나타납니다...
cloneLayer.onmouseup = EndDrag
}
//
startDraging("aim","sourceLayer","cloneLayer",300,200,20,20)
호출
//-->
</script>
</body>
</html>
다음 사항에 유의해야 합니다.
1. HTML에서는 div에 대해 세 가지 정의가 필요합니다. 위치를 제어하려면 세 레이어 모두에서 스타일의 위치를 절대값으로 정의해야 합니다.
1. 대상 레이어(목표)의 주요 기능은 드래그가 적용되는 위치를 정의하는 것입니다.
2. 소스(sourceLayer)를 드래그합니다. unselectable = "off" 속성을 설정하는 데 주의하세요. (이상합니다. on 범위로 설정하면 드래그 프로세스 중에 레이어 내용이 선택됩니다.)
3. 복사에 사용되는 레이어(cloneLayer).
2. 함수 호출
startDraging 매개변수 설명:
initAim 대상 레이어 이름 initSource 드래그 소스 이름 initClone 복사에 사용되는 레이어 이름
initAimX 대상 레이어의 x축 좌표 initAimY 대상 레이어의 y축 좌표 initOrgnX 드래그 소스의 x좌표 initOrgnY 드래그 소스의 Y축 좌표는
IE에서만 테스트됩니다. 드래그 소스가 대상에 도달한 후 xml을 작성하는 작업을 추가할 수 있습니다. 그런 다음 사용자 정의 페이지 레이아웃의 데이터를 기록합니다. 애니메이션을 반환하는 알고리즘이 매우 만족스럽지 않습니다. 개선을 위한 몇 가지 제안. 저는 현재 asp.net2.0을 기반으로 한 ajax 컨트롤 세트를 개발 중입니다. 더 많은 의사소통을 하시기 바랍니다.
추신: 제 블로그 정원의 첫 번째 기사입니다. .