使用页面拖放的方法传递数据,可大大增加页面操作的用户体验。
比如购物车等将一个元素拖放至另一元素内以后,相关的数据进行运算,
达到一定的数据处理目的。本例实现了一个这样的功能:将左侧线框内的阴影框(标注s1,s2,s3,s4的DIV),拖至右侧的四个线框其中的一个,
在拖放时可选择目标框,拖放完成时,得到被拖动元素和目标元素,从而得到了相关的数据,
从而可以实现各种运算。本例提供的方法可通用,请各位探讨!绝对原创,如有雷同,纯属巧合。
比如购物车等将一个元素拖放至另一元素内以后,相关的数据进行运算,
达到一定的数据处理目的。本例实现了一个这样的功能:将左侧线框内的阴影框(标注s1,s2,s3,s4的DIV),拖至右侧的四个线框其中的一个,
在拖放时可选择目标框,拖放完成时,得到被拖动元素和目标元素,从而得到了相关的数据,
从而可以实现各种运算。本例提供的方法可通用,请各位探讨!绝对原创,如有雷同,纯属巧合。
/* 初始化参数
args={
obj,moveText,dragStart,dragEnd,target,btouch,touch
}
*/
//拖动时说明,未指定时为空
args.moveText=args.moveText||""; if(!args.obj)return;
if(!args.target)return; isIE=document.all;
var obj=args.obj;
obj.style.cursor="move";
obj.onmousedown=function(e){//将要拖动
if(!document.all)e.preventDefault();
document.body.style.cursor='default';
if(args.dragStart){args.dragStart(this);}
var opos=getObjPos(this);
var cpos = getCurPos(e);
this.moveFlag=true;
var md=document.createElement("div");
document.body.appendChild(md);
this.md=md;
with(md.style){//拖动时说明样式
position="absolute";
border="1px solid #f00";
background="transparent";
fontSize="9pt"; md.innerHTML=args.moveText;
height=(this.offsetHeight-(isIE?2:2))+"px";
if(args.moveText=="")
width=(this.offsetWidth-(isIE?0:2))+"px";
top=cpos.y-parseInt(md.offsetHeight);
left=cpos.x-parseInt(md.offsetWidth)/2;
}
obj.target=null;
tas=args.target;
ts=new Array();
tas.length?ts=tas:ts[0]=tas;
tsc=ts.length;
obj.docMmove=document.onmousemove;
document.onmousemove=function(e){//开始拖动
if(!obj.moveFlag)return false;
document.body.style.cursor='default';
var Pos = getCurPos(e);
obj.target=null;
var nmd=obj.md;
nmd.style.left = Pos.x-parseInt(nmd.offsetWidth)/2+'px';
nmd.style.top = Pos.y-parseInt(nmd.offsetHeight)+'px';
if(args.btouch)
for(i=0;i<tsc;i++){
args.btouch(ts[i]);
}
for(i=tsc-1;i>=0;i--){
if(checkTouch(nmd,ts[i])&&args.touch){
obj.target=ts[i];
args.touch(obj);
break;
}
}
return false;
};
obj.docContextMenu=document.oncontextmenu;
document.oncontextmenu=function(){
return false;
};
obj.docMup=document.onmouseup;
document.onmouseup=function(e){//结束拖动
obj.moveFlag=false;
document.body.style.cursor='auto';
if(obj.md)document.body.removeChild(obj.md);
if(obj.onmouseup)obj.onmouseup();
if(args.dragEnd&&obj.target){
args.btouch(obj.target);
args.dragEnd(obj);
obj.target=null;
}
setTimeout(function(){//还原借用事件
document.onmouseup=obj.docMup;
obj.docMup=null;
document.oncontextmenu=obj.docContextMenu;
obj.docContextMenu=null;
document.onmousemove=obj.docMmove;
obj.docMmove=null;
},10);
}; };
//检查两个DIV是否有接触
function checkTouch(o1,o2){
p1=getObjPos(o1);
p2=getObjPos(o2);
x1=p1.x;y1=p1.y;
x2=p2.x;y2=p2.y;
w1=o1.offsetWidth;
h1=o1.offsetHeight;
w2=o2.offsetWidth;
h2=o2.offsetHeight;
return ((x1-x2<=0)&&(x2-x1<w1)||(x1-x2>=0)&&(x1-x2<w2))&&
((y1-y2<=0)&&(y2-y1<h1)||(y1-y2>=0)&&(y1-y2<h2));
};
//得到元素的左上角绝对坐标
function getObjPos(o){
var x=y=0;
if(o.getBoundingClientRect){
var box=o.getBoundingClientRect();
var D=document.documentElement;
x=box.left+Math.max(D.scrollLeft,document.body.scrollLeft)-D.clientLeft;
y=box.top+Math.max(D.scrollTop,document.body.scrollTop)-D.clientTop;
} else {
for(;o!=document.body;x+=o.offsetLeft,y+=o.offsetTop,o=o.offsetParent);
}
return {'x':x, 'y':y};
};
//得到鼠标绝对坐标
function getCurPos(e){
e=e||window.event;
var D=document.documentElement;
if (e.pageX) return {x:e.pageX,y:e.pageY};
return {
x:e.clientX+D.scrollLeft-D.clientLeft,
y:e.clientY+D.scrollTop-D.clientTop
};
};
}
<HTML>
<HEAD>
<TITLE></TITLE>
<script src="dragdrop.js"></script>
<style>
.item{width:50px;height:20px;border:1px solid #000;background:#ccc;}
#items{margin-top:100px;position:absolute;top:5px;left:5px;width:100px;height:100px;border:1px solid #000;}
#target,#target2,#target3,#target4{position:absolute;width:100px;height:100px;border:1px solid #000;}
#target{top:100px;left:300px;}
#target2{top:150px;left:350px;}
#target3{top:100px;left:430px;}
#target4{top:30px;left:360px;}
</style>
</HEAD><BODY>
说明:可将左侧框内的黑框拖到右侧四个框之一,也可以将它们拖回来。
<div id="items">
<div class="item">s1</div>
<div class="item">s2</div>
<div class="item">s3</div>
<div class="item">s4</div>
</div><div id="targets">
<div id="target"></div>
<div id="target2"></div>
<div id="target3"></div>
<div id="target4"></div>
</div><script>
d=document.getElementById("items").getElementsByTagName("div");
c=d.length;
for(i=0;i<c;i++){
d[i].onmouseup=function(){
this.style.background='#ccc';
}
drag(d[i]);//初始化
}
function drag(oo){
DragDrop({
obj:oo,//拖动元素
moveText:'将'+oo.innerHTML+'拖至右侧框',//拖动时说明
//开始拖动执行方法,o为拖动元素
dragStart: function(o){
o.style.background='#f00';
}, //成功结束拖放时执行方法,o为拖动元素,o.target为目标元素
//在这里可以进行自己的业务运算,进行数据交换等
dragEnd: function(o){
o.target.appendChild(o);
back(o);
},
//目标元素,可为数组
target:document.getElementById("targets").getElementsByTagName("div"),
//拖动元素与目标未接触时,目标执行方法,t为目标对象, 可用来还原接触后的样式
btouch:function(t){fbtouch(t)},
//拖动元素与目标接触时,执行方法, o为拖动元素,
//o.target指向目标元素,可用来设置接触后的样式
touch:function(o){ftouch(o)}
});
}
function back(oo){
DragDrop({
obj:oo,
moveText:'将'+oo.innerHTML+'拖回',
dragStart: function(o){
o.style.background='#f00';
},
dragEnd: function(o){
o.target.appendChild(o);
drag(o);
},
target:document.getElementById("items"),
btouch:function(t){fbtouch(t)},
touch:function(o){ftouch(o)}
});
}
function fbtouch(t){
t.style.border="1px solid black";
}
function ftouch(o){
o.target.style.border="2px solid red";
}
</script>
</BODY>
</HTML>完毕。
S3,S4也可以继续放进去。然后再拖一拖,画面就乱了。算个Bug。
function mouseMove(ev) {
ev = ev || window.event;
var mousePos = mouseCoords(ev);
}
function mouseCoords(ev) {
if(ev.pageX || ev.pageY) {
return {x:ev.pageX, y:ev.pageY};
}
return {
x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
y:ev.clientY + document.body.scrollTop - document.body.clientTop
};
}
首先我们需要解释一下event对象。不论你什么时候移动、点击鼠标,或按键,等等,一个事件都会发生。在IE中,这个事件是全局的,它被存储在window.event中,对于Firefox,及其他的浏览器来说,这个事件将被传递到任何指向这个页面动作的函数中。因此,我们使document.onmousemove指向鼠标移动的函数,鼠标移动的函数获得事件对象。
var dragObject = null;
function makeClickable(object) {
object.onmousedown = function() {
dragObject = this;
}
}
function mouseUp(ev) {
dragObject = null;
}
我们现在有了一个变量dragObject,包含了你点击的任何元素。当你释放鼠标的时候,dragObject被设置为空,从而在dragObject非空的时候,我们需要进行拖动操作。
这个BUG,是因为在指定目标元素时有问题,我这么写: //目标元素,可为数组
target:document.getElementById("targets").getElementByTagName("div"),就会把已经放进去的div也做为目标,应该改为: //目标元素,可为数组
target:document.getElementById("targets").children,
再次感谢提出BUG的朋友.