用到了H5 所添加的拖放api

第一步 设置属性

那就是把元素的 draggable 属性为 true,当该属性为 false 时,将不允许拖放。而 img 元素和 a 元素都默认设置了 draggable 属性为 true,可直接拖放

draggable='true'

第二步 绑定事件

一共由7个事件,但并不是每一个都必须使用,简单的介绍以下

被拖动的源对象可以触发的事件:

(1)ondragstart:源对象开始被拖动

(2)ondrag:源对象被拖动过程中(鼠标可能在移动也可能未移动)

(3)ondragend:源对象被拖动结束

用于放置源对象的目标对象可以触发的事件:

(1)ondragenter:目标对象被源对象拖动着进入

(2)ondragover:目标对象被源对象拖动着悬停在上方

(3)ondragleave:源对象拖动着离开了目标对象

(4)ondrop:源对象拖动着在目标对象上方释放/松手

注意坑:并不需要每一个元素都绑定事件,只需要在最外部的标签中绑定了事件,那么该标签内的所有元素都会被绑定上该事件。就好比我们给一个容器绑定了click事件,如果点击了该容器中的其它元素,也会触发click事件一样;

那么如何在目标对象和源对象之间进行数据传递呢?

使用 e.dataTransfer 对象的setData( k,  v )和getData( k )方法;

具体案例

来看一个具体案例吧,从任务池中选取任务,然后可以对任务进行排序。

直接看代码

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta charset="utf-8" />
	<title>拖拽排序</title>
	<meta name="generator" content="EverEdit" />
	<meta name="author" content="" />
	<meta name="keywords" content="" />
	<meta name="description" content="" />
	<script type="text/javascript" src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
	<style type="text/css">
		#flowPool ul,#nodePool ul{list-style: none;padding:0 5px;margin: 0;}
		#flowPool ul li,#nodePool ul li,#flowTemp {
			float: left;
			margin:5px 0px;
			width:100%;
			cursor: -webkit-grab;
		}
		#flowPool ul li:active,#nodePool ul li:active,#flowTemp {
			cursor: -webkit-grabing;
		}
		#flowTemp{
			outline: 1px solid #000;
   			outline-style: dotted;
		}
		.node{
			border: 1px solid #999;
		}
		.test{
			width:40%;
			float: left;
			border: 1px solid #999;
			margin:4%;
		}
		#nodePool{background: #eee ;}
		#flowPool{background: #ccc;position: relative;}
		#flowPool .dissociate{opacity: 0.2;
			-moz-opacity: 0.2;
			filter:alpha(opacity=20);
		}
		#flowPoolUL{min-height:100px;overflow: hidden;}
	</style>

</head>
<body>
	<div id="nodePool" class="test">
		<ul>
			<li data-node-id="1" draggable="true">
				<div class="node"   >
					节点1
				</div>
			</li>
			<li data-node-id="2" draggable="true">
				<div class="node" >
					节点2
				</div>
			</li>
			<li data-node-id="3" draggable="true">
				<div class="node">
					节点3
				</div>
			</li>
			<li data-node-id="4" draggable="true">
				<div class="node">
					节点4
				</div>
			</li>
		</ul>
	</div>
	<div id="flowPool" class="test">
		<ul id="flowPoolUL"  >
		</ul>
	</div>
	<ul style="display: none;">
		<li id="flowTemp" class="flowTemp">
			  
		</li>
	</ul>
</body>
	<script type="text/javascript">
	   (function(source,target,temp){
		    var moveItem
            //绑定源对象事件
		    source.ondragstart = function(e){ //开始拖动源对象
				console.log("ragstart")
		    	console.log(e)
		    	moveItem = $(e.target).clone()
		      }
		    source.ondrag = function(){}
		    source.ondragend = function(e){
			    console.log("ragstart")
			    console.log(e)
			    temp.remove();
		    }
  
		    target.ondragstart = function(e){ //开始拖动源对象
				console.log("ragstart")
		    	console.log(e)
		    	$(e.target).addClass("dissociate")
		    	moveItem = $(e.target)
		      }
		    target.ondrag = function(){}
		    target.ondragend = function(){
			    temp.remove();
			    moveItem?moveItem.remove():null;
		    }

		    //绑定目标对象事件
		    target.ondragenter=function(e){
			    e.stopPropagation();
			    console.log("enter")
			    console.log(e)
			    if(e.target.className=='node'){
				    $(e.target).parent('li').before(temp.get(0));
				}else if(e.target.id=='flowPoolUL'){
					target.append(temp.get(0));
				}
		    }
		    target.ondragover=function(e){
				//console.log("dragover");
				e.preventDefault(); //这样才可以触发ondrop事件
		    }
		    target.ondrop = function(e){
	      		console.log("drop")
				moveItem.removeClass("dissociate")
	      		temp.after(moveItem);
	      		moveItem=null;
		    }
		    target.ondragleave = function(e){
			    e.stopPropagation();
			    e.preventDefault(); 
			    console.log("leave")
		    }
	    })(nodePool,flowPoolUL,$('#flowTemp').clone())
	</script>
</html>

source:任务池对象,从中选出任务,也就是存放了需要的渊对象

target:任务流程,可以进行排序,也就是用以存放源对象的目标对象

temp:没什么业务功能,注要用来标记任务将会插入的位置

moveItem:移动中的对向,就是源对象