拖放效果系列 二

上一节我们实现了基本的拖拽,但是需要给可拖拽的元素设置一个特定的id,然后再在JS中修改代码,使用起来比较麻烦。这样一旦文档结构发生变化就要调整JS代码,没有做到JavaScript与HTML分离的原则。

所以应该实现一个可以适用于多个元素的拖拽代码,而且代码在可拖拽元素改变后应该不需要修改而仍然能正常工作。
使用class做“钩子”

为了使代码适用于多个元素,我们使用它的class来指定元素是否可以拖拽。我们使用如下的JavaScript代码来遍历文档中所有的节点,然后让class为drag的元素可以被拖拽。

Javascript代码
  1. function dragInit(node){  
  2.     if(node.className == "drag"){   
  3.         node.onmousedown = down;  
  4.         node.onmousemove = move;  
  5.         node.style.position = "relative";  
  6.         node.style.top = "0px";  
  7.         node.style.left = "0px";  
  8.     }  
  9.     var children = node.childNodes;  
  10.     for(var i = 0;i < children.length; i++){  
  11.         dragInit(children[i]);  
  12.     }  
  13. }  
function dragInit(node){
	if(node.className == "drag"){ 
		node.onmousedown = down;
		node.onmousemove = move;
		node.style.position = "relative";
		node.style.top = "0px";
		node.style.left = "0px";
	}
	var children = node.childNodes;
	for(var i = 0;i < children.length; i++){
		dragInit(children[i]);
	}
}



dragInit函数会逐个检查各个节点的class是否为drag,如是是,那么会为该元素设置鼠标经过、鼠标按下事件的响应函数。
多个元素一起移动的问题

上面我们已经实现了多个元素可移动的问题。可以进入这个网页测试一下。可以发现这个拖拽效果有一个严重的问题。当我们拖动div1的时候,如果鼠标路径经过了div2,那么两个div会同时移动。原因是这触发了 div2的onmouseover事件。我们可以通过给元素设置z-index的方法来解决。因为当我们拖动z-index较高的元素经过z-index 较低的元素时并不会触发z-index较低元素的鼠标经过事件。所以我们对代码做出如下修改:

Javascript代码
  1. <script type="text/javascript">  
  2. var max = 1;//定义一个max变量  
  3. ……其它部分不变  
  4. function down(event)  
  5. {     
  6.     ……  
  7.     //保证点击元素的z-index最高  
  8.     this.style.zIndex = max++;  
  9. }  
  10. </script>  
<script type="text/javascript">
var max = 1;//定义一个max变量
……其它部分不变
function down(event)
{	
	……
	//保证点击元素的z-index最高
	this.style.zIndex = max++;
}
</script>



我们设置了一个max变量来记录当前的z-index值,当点击一个元素的时候就用max的值来设置它的z-index属性,同时max的值会变大。这样就实现了每次拖拽一个元素的时候,不会触发其它元素的mouseover事件。但是,

我们发现,当拖动元素的速度非常快的时候,仍然会造成两个元素一起移动。我个人认为这是浏览器处理事件的延迟造成的。通过给每个对象分别设置一个判断拖拽状态的布尔变量dragging就可以解决这个问题了。最终的代码如下:
拖拽JavaScript代码

Javascript代码
  1. <script type="text/javascript">  
  2. var dragging = false;  
  3. var mouseY;  
  4. var mouseX;  
  5. var max = 1;  
  6. function dragInit(node){  
  7.     if(node.className == "drag"){   
  8.         node.onmousedown = down;  
  9.         node.onmousemove = move;  
  10.         node.onmouseover = over;  
  11.         node.onmouseup = up;  
  12.         node.style.position = "relative";  
  13.         node.style.top = "0px";  
  14.         node.style.left = "0px";  
  15.         node.dragging = false;  
  16.     }  
  17.     var children = node.childNodes;  
  18.     for(var i = 0;i < children.length; i++){  
  19.         dragInit(children[i]);  
  20.     }  
  21. }  
  22. window.onload = function(){  
  23.     dragInit(document);  
  24.     document.onmouseup = docUp;  
  25. }  
  26. function down(event)  
  27. {     
  28.     event = event || window.event;   
  29.     dragging = true;   
  30.     this.dragging = true;   
  31.     mouseX = parseInt(event.clientX);  
  32.     mouseY = parseInt(event.clientY);  
  33.     objY = parseInt(this.style.top);  
  34.     objX = parseInt(this.style.left);  
  35.     this.style.zIndex = max++;  
  36. }  
  37. function move(event){  
  38.     event = event || window.event;   
  39.     if(this.dragging == true && dragging == true){  
  40.         var x,y;  
  41.         y = event.clientY - mouseY + objY;  
  42.         x = event.clientX - mouseX + objX;  
  43.         this.style.top = y + "px";  
  44.         this.style.left = x + "px";  
  45.     }  
  46. }  
  47. function up(){  
  48.     this.dragging = false;  
  49. }  
  50. function docUp(){  
  51.     dragging = false;  
  52. }  
  53. function over(){  
  54.     this.style.cursor = "move";  
  55. }  
  56. </script>  
<script type="text/javascript">
var dragging = false;
var mouseY;
var mouseX;
var max = 1;
function dragInit(node){
	if(node.className == "drag"){ 
		node.onmousedown = down;
		node.onmousemove = move;
		node.onmouseover = over;
		node.onmouseup = up;
		node.style.position = "relative";
		node.style.top = "0px";
		node.style.left = "0px";
		node.dragging = false;
	}
	var children = node.childNodes;
	for(var i = 0;i < children.length; i++){
		dragInit(children[i]);
	}
}
window.onload = function(){
	dragInit(document);
	document.onmouseup = docUp;
}
function down(event)
{	
	event = event || window.event; 
	dragging = true; 
	this.dragging = true; 
	mouseX = parseInt(event.clientX);
	mouseY = parseInt(event.clientY);
	objY = parseInt(this.style.top);
	objX = parseInt(this.style.left);
	this.style.zIndex = max++;
}
function move(event){
	event = event || window.event; 
	if(this.dragging == true && dragging == true){
		var x,y;
		y = event.clientY - mouseY + objY;
		x = event.clientX - mouseX + objX;
		this.style.top = y + "px";
		this.style.left = x + "px";
	}
}
function up(){
	this.dragging = false;
}
function docUp(){
	dragging = false;
}
function over(){
	this.style.cursor = "move";
}
</script>



做出修改的代码用已经标记了出来。点击进入示例网页。
JavaScript拖拽系列

   1. JavaScript拖拽
   2. JavaScript拖拽2——多元素、分离JS
   3. JavaScript拖拽3——解决快速拖拽的问题
   4. JavaScript拖拽4——获得元素的位置
   5. JavaScript拖拽5——性能优化
   6. JavaScript拖拽6——修复错误

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值