效果:实现类似于学生换座位的效果,将网页内的两个元素通过拖拽的方式互换。
找了一些现成的插件,发现都不太符合我的需求,于是参考网上的例子自己实现了一个,还没有优化。
参考:怎么用javascript进行拖拽- 蓝色理想
还是贴代码吧:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
dragtoreplace
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd%22>
<html xmlns="http://www.w3.org/1999/xhtml%22>
<head>
<title>DragToReplaceDeom</title>
<style>
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
#displayRoom
{background:#eee;position:relative;float:left;clear:both;padding:30px 0px 0px 20px;margin-left:20px;margin-top:10px;}
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
.row
{display:inline-block;float:left;width:90px;clear:none;top:0;/**//*background:#DFEFFC;*/}
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
.row span
{display:inline-block;width:60px;clear:none;background:#9192B1;height:30px;line-height:30px;margin-bottom:30px;text-align:center;}
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
span.usr
{cursor:pointer;position:absolute;display:inline-block;width:60px;clear:none;height:30px;line-height:30px;margin-bottom:30px;text-align:center;background:#4DA74D;color:#fff;}
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
span.usr.catch
{background:#BD9B33!important;}
</style>
</head>
<body>
<div id="displayRoom">
<div class="row">
<span><span class="usr" id="345">学生甲</span></span><span></span><span></span><span></span></div>
<div class="row">
<span><span class="usr" id="123">学生乙</span></span><span id="3"></span><span></span><span></span></div>
<div class="row">
<span></span><span></span><span></span><span></span>
</div>
<div class="row">
<span></span><span><span class="usr" id="456">学生一</span></span><span></span><span></span>
</div>
</div>
<script type="text/javascript">var curTarget = null; //鼠标拖拽的目标元素
var curPos = null;
var dropTarget = null; //要放下的目标元素
var iMouseDown = false; //鼠标是否按下
var lMouseState = false; //前一个iMouseDown状态
var dragreplaceCont = [];
var mouseOffset = null;
var callbackFunc = null;
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
Number.prototype.NaN0 = function()
{ return isNaN(this) ? 0 : this; }
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
function setdragreplace(obj, callback)
{
dragreplaceCont.push(obj);
obj.setAttribute('candrag', '1');
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (callback != null && typeof (callback) == 'function')
{
callbackFunc = callback;
}
}
//鼠标移动
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
function mouseMove(ev)
{
ev = ev || window.event;
var target = ev.target || ev.srcElement;
var mousePos = mouseCoords(ev);
//如果当前元素可拖拽
var dragObj = target.getAttribute('candrag');
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (dragObj != null)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (iMouseDown && !lMouseState)
{
//刚开始拖拽
curTarget = target;
curPos = getPosition(target);
mouseOffset = getMouseOffset(target, ev);
// 清空辅助层
for (var i = 0; i < dragHelper.childNodes.length; i++) dragHelper.removeChild(dragHelper.childNodes[i]);
//克隆元素到辅助层,并移动到鼠标位置
dragHelper.appendChild(curTarget.cloneNode(true));
dragHelper.style.display = 'block';
dragHelper.firstChild.removeAttribute('candrag');
//记录拖拽元素的位置信息
curTarget.setAttribute('startWidth', parseInt(curTarget.offsetWidth));
curTarget.setAttribute('startHeight', parseInt(curTarget.offsetHeight));
curTarget.style.display = 'none';
//记录每个可接纳元素的位置信息,这里一次记录以后多次调用,获取更高性能
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
for (var i = 0; i < dragreplaceCont.length; i++)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
with (dragreplaceCont[i])
{
if (dragreplaceCont[i] == curTarget)
continue;
var pos = getPosition(dragreplaceCont[i]);
setAttribute('startWidth', parseInt(offsetWidth));
setAttribute('startHeight', parseInt(offsetHeight));
setAttribute('startLeft', pos.x);
setAttribute('startTop', pos.y);
}
} //记录end
} //刚开始拖拽end
}
//正在拖拽
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (curTarget != null)
{
// move our helper div to wherever the mouse is (adjusted by mouseOffset)
dragHelper.style.top = mousePos.y - mouseOffset.y + "px";
dragHelper.style.left = mousePos.x - mouseOffset.x + "px";
//拖拽元素的中点
var xPos = mousePos.x - mouseOffset.x + (parseInt(curTarget.getAttribute('startWidth')) / 2);
var yPos = mousePos.y - mouseOffset.y + (parseInt(curTarget.getAttribute('startHeight')) / 2);
var havedrop = false;
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
for (var i = 0; i < dragreplaceCont.length; i++)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
with (dragreplaceCont[i])
{
if (dragreplaceCont[i] == curTarget)
continue;
if ((parseInt(getAttribute('startLeft')) < xPos) &&
(parseInt(getAttribute('startTop')) < yPos) &&
((parseInt(getAttribute('startLeft')) + parseInt(getAttribute('startWidth'))) > xPos) &&
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
((parseInt(getAttribute('startTop')) + parseInt(getAttribute('startHeight'))) > yPos))
{
havedrop = true;
dropTarget = dragreplaceCont[i];
dropTarget.className = 'usr catch';
break;
}
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (!havedrop && dropTarget != null)
{
dropTarget.className = 'usr';
dropTarget = null;
}
} //正在拖拽end
lMouseState = iMouseDown;
if (curTarget) return false; //阻止其它响应(如:鼠标框选文本)
}
//鼠标松开
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
function mouseUp(ev)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (curTarget)
{
dragHelper.style.display = 'none'; //隐藏辅助层
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (curTarget.style.display == 'none' && dropTarget != null)
{
//有元素接纳,两者互换
var destP = dropTarget.parentNode;
var sourceP = curTarget.parentNode;
destP.appendChild(curTarget);
sourceP.appendChild(dropTarget);
dropTarget.className = 'usr';
dropTarget = null;
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (callbackFunc != null)
{
callbackFunc(curTarget);
}
}
curTarget.style.display = '';
curTarget.style.visibility = 'visible';
curTarget.setAttribute('candrag', '1');
}
curTarget = null;
iMouseDown = false;
}
//鼠标按下
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
function mouseDown(ev)
{
//记录变量状态
iMouseDown = true;
//获取事件属性
ev = ev || window.event;
var target = ev.target || ev.srcElement;
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (target.onmousedown || target.getAttribute('candrag'))
{//阻止其它响应(如:鼠标双击文本)
return false;
}
}
//返回当前item相对页面左上角的坐标
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
function getPosition(e)
{
var left = 0;
var top = 0;
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while (e.offsetParent)
{
left += e.offsetLeft + (e.currentStyle ? (parseInt(e.currentStyle.borderLeftWidth)).NaN0() : 0);
top += e.offsetTop + (e.currentStyle ? (parseInt(e.currentStyle.borderTopWidth)).NaN0() : 0);
e = e.offsetParent;
}
left += e.offsetLeft + (e.currentStyle ? (parseInt(e.currentStyle.borderLeftWidth)).NaN0() : 0);
top += e.offsetTop + (e.currentStyle ? (parseInt(e.currentStyle.borderTopWidth)).NaN0() : 0);
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
return
{ x: left, y: top };
}
//返回鼠标相对页面左上角的坐标
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
function mouseCoords(ev)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (ev.pageX || ev.pageY)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
return
{ x: ev.pageX, y: ev.pageY };
}
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
return
{ x: ev.clientX + document.body.scrollLeft + document.documentElement.scrollLeft - document.body.clientLeft,
y: ev.clientY + document.body.scrollTop + document.documentElement.scrollTop - document.body.clientTop
};
}
//鼠标位置相对于item的偏移量
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
function getMouseOffset(target, ev)
{
ev = ev || window.event;
var docPos = getPosition(target);
var mousePos = mouseCoords(ev);
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
return
{ x: mousePos.x - docPos.x, y: mousePos.y - docPos.y };
}
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
window.onload = function()
{
document.onmousemove = mouseMove;
document.onmousedown = mouseDown;
document.onmouseup = mouseUp;
//辅助层用来显示拖拽
dragHelper = document.createElement('DIV');
dragHelper.style.cssText = 'position:absolute;display:none;';
document.body.appendChild(dragHelper);
setdragreplace(document.getElementById('345'));
setdragreplace(document.getElementById('123'));
setdragreplace(document.getElementById('456'));
};
</script>
</body>
</html>
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)