Recently, I saw some friends on the Internet looking for drag-and-drop implementations similar to Google's personalized homepage and MSN space, and I happened to find an example below. But there were many problems. I rewritten and improved it and established a general function. The specific function implementation is as follows:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>BlackSoul's Drag and Drop Demo</title>
<!- -
____________________________________
|--------Author By BlackSoul---------|
|------------2006.03.30---------- ----|
|[email protected] ------|
|------------QQ:9136194-------- ------|
|------http://blacksoul.cnblogs.cn---|
======================= ===============
-->
<style type="text/css">
body
{
margin:0px;
}
#aim /*Set the target layer style*/
{
position:absolute;/*Style necessary to control the position of the layer*/
width:200px;
height:30px;
border:1px solid #666666;
background-color:#FFCCCC;
}
#sourceLayer, #cloneLayer
{
position:absolute;/*Style necessary to control the position of the layer*/
width:300px;
height:50px;
border:1px solid #666666;
background-color:#CCCCCC;
cursor:move;
}
.docked
{
display:none;
filter:alpha(opacity=100);
}
.actived
{
display:block;
filter:alpha(opacity=70);
}
</style>
</head>
<body>
<div id="aim">Placement range</div>
<div id="sourceLayer" unselectable="off"><img src="
<div id="cloneLayer" class="docked" unselectable="off"> </div>
<script type="text/javascript" language="javascript">
<!--
/*
============================= =======
|--------Author By BlackSoul---------|
|------------2006.03.30----- ---------|
|[email protected] ------|
|------------QQ:9136194--- -----------|
|------http://blacksoul.cnblogs.cn---|
================== ==================
*/
//Set the layer object
var aim;
var sourceLayer;
var cloneLayer;
//Define the initial position of each layer
var aimX;
var aimY;
var orgnX;
var orgnY;
//Variables during dragging
var draging = false; //Whether it is being dragged
var offsetX = 0; //The left and right offsets in the X direction
var offsetY = 0; //The up and down offsets in the Y direction
var back; / /Return animation object
var thisX; //X position of current clone layer
var thisY; //Y position of current clone layer
var time;
var stepX; //Displacement speed
var stepY; //Displacement speed
//Initialize drag information
/*
initAimX target x coordinate
initAimY target y coordinate
initOrgnX drag source x coordinate
initOrgnY drag source y coordinate
*/
//Get the layer object
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;
//Set the position of each starting layer
aim.style.pixelLeft = aimX;
aim.style.pixelTop = aimY;
sourceLayer.style.pixelLeft = orgnX;
sourceLayer.style.pixelTop = orgnY;
cloneLayer.style.pixelLeft = orgnX;
cloneLayer.style.pixelTop = orgnY;
}
//Prepare the drag
function BeforeDrag()
{
if (event.button != 1)
{
return;
}
cloneLayer.innerHTML = sourceLayer.innerHTML; //Copy the drag source content
offsetX = document.body.scrollLeft + event.clientX - sourceLayer.style.pixelLeft;
offsetY = document.body.scrollTop + event.clientY - sourceLayer.style.pixelTop;
cloneLayer.className = "actived";
draging = true;
}
//Drag
function OnDrag()
{
if(!dragging)
{
return;
}
//Update position
event.returnValue = false;
cloneLayer.style.pixelLeft = document.body.scrollLeft + event.clientX - offsetX;
cloneLayer.style .pixelTop = document.body.scrollTop + event.clientY - offsetY;
}
//End dragging
function 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))
{
//The drag layer is located in the target and automatically positioned to the target position
sourceLayer.style.pixelLeft = aim.style.pixelLeft;
sourceLayer.style.pixelTop = aim.style.pixelTop;
cloneLayer.className = "docked";
/*
** After completing this, you can use xml to save the current position.
** The next time the user enters
, the source drag layer will be initialized to the data in xml
*/
}
else
{
//Drag and drop Located outside the target layer, restore the drag source position
thisX = cloneLayer.style.pixelLeft;
thisY = cloneLayer.style.pixelTop;
offSetX = Math.abs(thisX - orgnX);
offSetY = Math.abs(thisY - orgnY);
time = 500;//Set animation time
stepX = Math.floor((offSetX/time)*20);
stepY = Math.floor((offSetY/time)*20);
if(stepX == 0)
stepX = 2;
if (stepY == 0)
stepY = 2;
//Start the return animation
moveStart();
}
}
function moveStart()
{
back = setInterval("MoveLayer();",15);
}
//Set the returned animation effect
function MoveLayer()
{
//Located on the upper left side of the target
if(cloneLayer.style.pixelLeft <= orgnX && cloneLayer.style.pixelTop <= orgnY)
{
cloneLayer.style.pixelLeft += stepX;
cloneLayer.style .pixelTop += stepY;
//If the displacement exceeds the target, set the speed to pix and move back in the opposite direction. A spring effect is achieved here. The same as
if(cloneLayer.style.pixelLeft > orgnX)
{
stepX = 1;
}
if(cloneLayer.style.pixelTop > orgnY)
{
stepY = 1;
}
//If the coordinates on the X or Y axis are the same, no displacement will occur
if(cloneLayer.style.pixelLeft == orgnX)
{
stepX = 0;
}
if(cloneLayer .style.pixelTop == orgnY)
{
stepY = 0;
}
if(cloneLayer.style.pixelLeft == orgnX && cloneLayer.style.pixelTop == orgnY)
{
EndMove();
}
}
//Located at the lower left of the target
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();
}
}
//Located on the upper right side of the target
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();
}
}
//Located on the upper right side of the target
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();
}
}
//reach the target
else
{
EndMove();
}
}
//Stop return animation
function EndMove()
{
sourceLayer.style.pixelLeft = orgnX;
sourceLayer.style.pixelTop = orgnY;
cloneLayer.style.pixelLeft = orgnX;
cloneLayer.style.pixelTop = orgnY;
cloneLayer.className = "docked";
clearInterval(back);
}
//Main drag function
function startDraging(inAim,inSource,inClone,initAimX,initAimY,initOrgnX,initOrgnY)
{
getLayer(inAim,inSource,inClone)
initDrag(initAimX,initAimY,initOrgnX,initOrgnY);
sourceLayer.onmousedown = BeforeDrag;
document .onmousemove = OnDrag; //If cloneLayer is used here, the content in cloneLayer will be selected during dragging, and some bugs will appear...
cloneLayer.onmouseup = EndDrag;
}
//Call
startDraging("aim","sourceLayer","cloneLayer",300,200,20,20);
//-->
</script>
</body>
</html>
It should be noted that:
1. There need to be three definitions of div in HTML. The position of style must be defined as absolute in all three layers to control the position.
1. Target layer (aim), its main function is to define the position where drag takes effect.
2. Drag the source (sourceLayer). Pay attention to setting the attribute unselectable = "off" (this is strange, setting it to the on range will select the layer content during the dragging process)
3. The layer used for copying (cloneLayer).
2. Function call
startDraging parameter explanation:
initAim target layer name initSource drag source name initClone name of the layer used for copying
initAimX The x-axis coordinate of the target layer initAimY The y-axis coordinate of the target layer initOrgnX The x-coordinate of the drag source initOrgnY The Y-axis coordinate of the drag source
is only tested in IE. Comments have been added to the code. You can add the operation of writing xml after the drag source reaches the target. .And then record the data of user-defined page layout. I am not very satisfied with the algorithm of returning animation. I hope you can give me some suggestions for improvement. I am currently working on developing a set of ajax controls based on asp.net2.0. I hope you will have more Communicate.
ps: The first article in my blog garden. I hope you can support me a lot.