在上一篇文章中所用的方法基本上 MicroSoft Live 和GOOGLE个性主页 页面元素可拖拽放置的实现原理,但是你也许会发现一个问题,鼠标不在可拖动的层之内,而是在与拖动层的相对位置的0,0坐标上,这样当鼠标经过未被拖动的层的时候才能触发这些层的onmouseover事件。如果你为拖动对象设置一个偏移值就可以将鼠标放置到已拖动层内的位置,但是这样就出现一个更严重的问题,未被拖动的那些层的onmouseover事件触发不了了,这样就也无法进行放置动作和放置位置的预览显示。
解决方法:当鼠标在一个层内时是不能触发另一个层(在这里是下面的层)的任何鼠标事件的,所以这时候必须抛弃onmouseover事件,我们需要通过对鼠标坐标和未被拖动的层的坐标及范围做判断,判断鼠标是否经过某个层。然后再处理相应的事情,但是这里又出现一个问题,判断鼠标是否在某个层内?但是鼠标已经在被拖动的层内了,并且在放下之前会一直在这个层内,这样判断将会得出两个符合条件的结果,所以我们要排除被拖动的层,可以有很多解决方法,在这里我使用一个比较容易理解的方法:不直接判断鼠标是否在哪个层,而是判断被拖动的层是否在某个未被拖动的层内,所以判断的语句片段是这样的:obj.style.posTop>rootNode.childNodes[i].offsetTop&&obj.style.posTop<rootNode.childNodes[i].offsetTop+15 这样的话,第一个条件obj.style.posTop>rootNode.childNodes[i].offsetTop 就将被拖动的本身排除掉了(当rootNode.childNodes[i]是被拖动的这个层obj的时候,style.posTop和offsetTop 是相等的,所以大于>条件就不成立了,被拖动的层自身就这样被排除的)。当然,还可以用其他更有效更直接的方法,例如在onmousedown的时候就记录下被抓取的元素,然后在判断的时候直接逼开这个元素即可。
<%@ Page language="c#" Codebehind="DropLayer2.aspx.cs" AutoEventWireup="false" Inherits="test.DropLayer2" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<html>
<head>
<title>DropLayer2</title>
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" Content="C#">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
<style type="text/css">
div
{
border-right: lightgrey thin solid;
border-top: lightgrey thin solid;
font-weight: bold;
z-index: 2;
text-transform: capitalize;
border-left: lightgrey thin solid;
color: white;
border-bottom: lightgrey thin solid;
background-color: dimgray;
}
</style>
</head>
<body>
<div id="parentDiv" class="parentCss" style="width:100">
<div class="itemCss">one 1</div>
<div class="itemCss">two 2</div>
<div class="itemCss">three 3</div>
<div class="itemCss">four 4</div>
<div class="itemCss">five 5</div>
<div class="itemCss">six 6</div>
<div class="itemCss">seven 7</div>
<div class="itemCss">eight 8</div>
<div class="itemCss">nine 9</div>
<div class="itemCss">ten 10</div>
</div>
<script language="javascript">
<!--
var obj,obj2; //引发事件对象
var rootNode; //控制对象根节点
var IsDrag=false; //是否抓起
var NullDiv; //空临时层
var x,y; //鼠标与控件的相对坐标
window.onload = Prepare; //窗体加载时委托到Prepare
function Prepare()
{
//生成临时层,并设置其属性
NullDiv = document.createElement("div");
//获得控制对象的根节点元素
rootNode = document.getElementById("parentDiv");
document.onmousemove=MoveIt; //当鼠标在文档上移动时事件委托到MoveIt
document.onmousedown=Drag; //当鼠标按下时事件委托到Drag
document.onmouseup=Release; //当鼠标释放台起时事件委托到Release
}
function Drag()
{
obj = event.srcElement;
x=20;//event.offsetX;
y=10;//event.offsetY;
obj.style.position='absolute';
obj.style.posTop=event.y-y;
obj.style.posLeft=event.x-x;
IsDrag=true;
}
function MoveIt()
{
if(IsDrag)
{
obj.style.posTop=event.y-y;
obj.style.posLeft=event.x-x;
//循环并判断鼠标经过哪个未被拖动的层
for(var i = 0 ; i<rootNode.childNodes.length;i++)
{
//判断鼠标经过哪个未被拖动的层
if(obj.style.posTop>rootNode.childNodes[i].offsetTop&&obj.style.posTop<rootNode.childNodes[i].offsetTop+15&&obj.style.posLeft>rootNode.childNodes[i].offsetLeft&&obj.style.posLeft<rootNode.childNodes[i].offsetLeft+100)
{
obj2=rootNode.childNodes[i];
NullDiv.style.display='';
NullDiv.style.height='18';
NullDiv.style.width='100';
rootNode.insertBefore(NullDiv,obj2);
break;
}
}
}
}
function Release()
{
IsDrag=false;
NullDiv.style.display='none';
obj.style.position='';
rootNode.insertBefore(obj,obj2);
}
//-->
</script>
</body>
</html>