PC端代码是别人写的,HTML5移动端jquery版是参照PC端我自己改的。
直接上代码:
PC端js原生版
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>拖拽</title>
<style>
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
}
#drag ul {
width: 612px;
margin: auto;
}
#drag ul li {
width: 200px;
height: 200px;
float: left;
border: 1px solid transparent;
}
#drag ul li img {
width: 200px;
height: 200px;
}
</style>
</head>
<body>
<div id="drag">
<ul>
<li>
<img src="1.jpg" alt="1.jpg">
</li>
<li>
<img src="2.jpg" alt="2.jpg">
</li>
<li>
<img src="3.jpg" alt="3.jpg">
</li>
<li>
<img src="4.jpg" alt="4.jpg">
</li>
<li>
<img src="5.jpg" alt="5.jpg">
</li>
<li>
<img src="6.jpg" alt="6.jpg">
</li>
</ul>
</div>
<script type="text/javascript">
let liItems = document.getElementsByTagName("li") // 获取到每个li
let zIndex = 1 //定义li的层级
/**
* 循环每个li获取他们的位置
* offsetLeft
* offsetTop
*/
let distanceL = [] // 定义距离对象数组
for(let i = 0; i<liItems.length; i++) {
distanceL.push(
{
left: liItems[i].offsetLeft,
top: liItems[i].offsetTop
}
)
}
// 把刚循环出来的位置值转换到图片的样式
for(let i = 0; i<liItems.length; i++) {
liItems[i].index = i;
liItems[i].style.position = "absolute";
liItems[i].style.left = distanceL[i].left + 'px';
liItems[i].style.top = distanceL[i].top + 'px';
liItems[i].style.margin = 0;
}
// 拖拽功能
for (let i = 0; i < liItems.length; i++) {
drag(liItems[i])
}
/**
* 拖拽函数
*/
function drag(obj) {
// 给该对象绑定鼠标按下事件
obj.onmousedown = function(ev) {
ev = ev || window.event
// 获取当前鼠标点击的位置
let x = ev.clientX
let y = ev.clientY
// 获取当前图片的位置
let left = this.offsetLeft
let top = this.offsetTop
// 设置li的层级不断往上加
this.style.zIndex = zIndex++
// 移动过程中
document.onmousemove = function(ev) {
ev = ev || window.event
// 获取移动中的位置,减去点击时候的位置,再加上图片原来的位置
let moveLeft = ev.clientX - x + left
let moveTop = ev.clientY - y + top
obj.style.left = moveLeft + "px"
obj.style.top = moveTop + "px"
// 移动的时候先把边框去掉
for(let i = 0; i< liItems.length; i++) {
liItems[i].style.border = "1px solid transparent"
}
// 检测碰撞
let hit = nearLi(obj)
if(hit) {
hit.style.border = "1px dashed red"
}
}
// 当鼠标抬起的时候,需要把鼠标松开事件改为null
document.onmouseup = function() {
document.onmousemove = null;
document.onmouseup = null;
// 抬起来的时候再次获取碰撞的数据
let oLi = nearLi(obj);
if(oLi){
// 交换位置
animate(obj, {left: distanceL[oLi.index].left, top: distanceL[oLi.index].top},10, 0.08);
animate(oLi, {left: distanceL[obj.index].left, top: distanceL[obj.index].top},10, 0.08);
// 清除交换的边框
oLi.style.border = "1px solid transparent";
// 交换索引
console.log(obj.index);
let temp = obj.index;
obj.index = oLi.index;
oLi.index = temp;
console.log(obj.index);
}else{
animate(obj, {left: distanceL[obj.index].left, top: distanceL[obj.index].top},10, 0.08);
// obj.style.left = arr[obj.index].left+"px";
// obj.style.top = arr[obj.index].top+"px";
}
}
//返回false是为了屏蔽h5中图片标签<img>默认的拖拽事件
return false;
}
}
// 计算最小距离
function nearLi(obj) {
let n = 10000000000;
let hit = '';
for (let i = 0; i < liItems.length; i++) {
if (obj != liItems[i] && impact(obj, liItems[i])) {
// 计算碰撞的li距离
let c = distance(obj, liItems[i]);
if (c < n) {
n = c;
hit = liItems[i];
}
}
}
return hit;
}
// 碰撞检查
function impact(obj1, obj2) {
//对象1的各各边距
let left1 = obj1.offsetLeft; //左边距
let top1 = obj1.offsetTop; //上边距
let right1 = left1 + obj1.offsetWidth; //对象右边距离屏幕左边的距离
let bottom1 = top1 + obj1.offsetHeight; //对象下边距离屏幕顶端的距离
//对象2的各各边距
let left2 = obj2.offsetLeft;
let top2 = obj2.offsetTop;
let right2 = left2 + obj2.offsetWidth;
let bottom2 = top2 + obj2.offsetHeight;
if (right1 <= left2 || bottom1 <= top2 || left1 >= right2 || top1 >= bottom2) {
// console.log("不成功") // 不成功
return false;
} else {
// console.log("成功") //成功
return true;
}
}
// 勾股定理计算斜边
function distance(obj1, obj2) {
let a = obj1.offsetLeft - obj2.offsetLeft;
let b = obj1.offsetTop - obj2.offsetTop;
return Math.sqrt(a * a + b * b);
}
function animate(obj, json, interval, sp, fn) {
clearInterval(obj.timer);
function getStyle(obj, arr) {
if(obj.currentStyle){
return obj.currentStyle[arr]; //针对ie
} else {
return document.defaultView.getComputedStyle(obj, null)[arr];
}
}
obj.timer = setInterval(function(){
let flag = true;
for(let arr in json) {
let icur = 0;
//k++;
if(arr == "opacity") {
icur = Math.round(parseFloat(getStyle(obj, arr))*100);
} else {
icur = parseInt(getStyle(obj, arr));
}
let speed = (json[arr] - icur) * sp;
speed = speed > 0 ? Math.ceil(speed): Math.floor(speed);
if(icur != json[arr]){
flag = false;
}
if(arr == "opacity"){
obj.style.filter = "alpha(opacity : '+(icur + speed)+' )";
obj.style.opacity = (icur + speed)/100;
}else {
obj.style[arr] = icur + speed + "px";
}
}
if(flag){
clearInterval(obj.timer);
if(fn){
fn();
}
}
},interval);
}
</script>
</body>
</html>
下面是移动端jquery版,点击右边拖拽手柄图片上下拖动排序
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<script type="text/javascript" src="jquery.min.js"></script>
<title>拖拽</title>
<style>
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
}
#drag ul {
width: 100%;
}
#drag ul li {
width: 100%;
height: 210px;
border: 1px solid transparent;
overflow: auto;
position: relative;
}
#drag ul li img {
width: 200px;
height: 200px;
}
#drag ul li p {
line-height: 40px;
}
#drag ul li em {
position: absolute;
background: url(eupdown.png) no-repeat;
background-size: 60%;
width: 48px;
height: 77px;
right: 0;
top: 0;
z-index: 2;
}
</style>
</head>
<body>
<input type="text" id="stext" />
<div id="drag">
<ul>
<li>
<img src="1.jpg" alt="1.jpg">
</li>
<li>
<img src="2.jpg" alt="2.jpg">
</li>
<li>
<img src="3.jpg" alt="3.jpg">
</li>
<li>
<img src="4.jpg" alt="4.jpg">
</li>
<li>
<img src="5.jpg" alt="5.jpg">
</li>
<li>
<img src="6.jpg" alt="6.jpg">
</li>
</ul>
</div>
<script type="text/javascript">
let liItems = $("li") // 获取到每个li
let zIndex = 1 //定义li的层级
/**
* 循环每个li获取他们的位置
* offsetLeft
* offsetTop
*/
let distanceL = [] // 定义距离对象数组
for(let i = 0; i<liItems.length; i++) {
distanceL.push(
{
left: parseInt(liItems.eq(i).offset().left),
top: parseInt(liItems.eq(i).offset().top),
}
)
}
// 把刚循环出来的位置值转换到图片的样式
for(let i = 0; i<liItems.length; i++) {
liItems.eq(i).css('position',"absolute");
liItems.eq(i).css('left',distanceL[i].left + 'px');
liItems.eq(i).css('top',distanceL[i].top + 'px');
liItems.eq(i).css('margin',0);
liItems.eq(i).data('index',i);
}
// 拖拽功能
for (let i = 0; i < liItems.length; i++) {
drag(liItems.eq(i))
}
/**
* 拖拽函数
*/
function drag(obj) {
// 给该对象绑定鼠标按下事件
obj.on("touchstart",'em',function(e) {
// 获取当前鼠标点击的位置
let x = e.originalEvent.targetTouches[0].pageX;
let y = e.originalEvent.targetTouches[0].pageY;
// 获取当前图片的位置
let left = obj.offset().left;
let top = obj.offset().top;
// 设置li的层级不断往上加
obj.css('zIndex',zIndex++);
// 移动过程中
obj.on("touchmove",'em',function(e) {
// 获取移动中的位置,减去点击时候的位置,再加上图片原来的位置
let moveLeft = e.originalEvent.changedTouches[0].pageX - x + left
let moveTop = e.originalEvent.changedTouches[0].pageY - y + top
obj.css('left',moveLeft + "px");
obj.css('top',moveTop + "px");
// 移动的时候先把边框去掉
for(let i = 0; i< liItems.length; i++) {
liItems.eq(i).css('border',"1px solid transparent");
}
// 检测碰撞
let hit = nearLi(obj)
if(hit) {
hit.css('border',"1px dashed red");
}
})
// 当鼠标抬起的时候,需要把鼠标松开事件改为null
obj.on("touchend",'em',function(e) {
obj.off('touchmove touchend');
// 抬起来的时候再次获取碰撞的数据
let oLi = nearLi(obj);
if(oLi){
oLi.off('touchmove touchend');
// 交换位置
animate(obj, {left: distanceL[oLi.data('index')].left, top: distanceL[oLi.data('index')].top},10, 0.08);
animate(oLi, {left: distanceL[obj.data('index')].left, top: distanceL[obj.data('index')].top},10, 0.08);
// 清除交换的边框
oLi.css('border',"1px solid transparent");
// 交换索引
let temp = obj.data('index');
obj.data('index',oLi.data('index')) ;
oLi.data('index',temp);
}else{
animate(obj, {left: distanceL[obj.data('index')].left, top: distanceL[obj.data('index')].top},10, 0.08);
}
})
//返回false是为了屏蔽h5中图片标签<img>默认的拖拽事件
return false;
})
}
// 计算最小距离
function nearLi(obj) {
let n = 10000000000;
let hit = '';
for (let i = 0; i < liItems.length; i++) {
if (!obj.is(liItems.eq(i)) && impact(obj, liItems.eq(i))) {
// 计算碰撞的li距离
let c = distance(obj, liItems.eq(i));
if (c < n) {
n = c;
hit = liItems.eq(i);
}
}
}
return hit;
}
// 碰撞检查
function impact(obj1, obj2) {
//对象1的各各边距
let left1 = obj1.offset().left; //左边距
let top1 = obj1.offset().top; //上边距
let right1 = left1 + obj1.outerWidth(); //对象右边距离屏幕左边的距离
let bottom1 = top1 + obj1.outerHeight(); //对象下边距离屏幕顶端的距离
//对象2的各各边距
let left2 = obj2.offset().left;
let top2 = obj2.offset().top;
let right2 = left2 + obj2.outerWidth();
let bottom2 = top2 + obj2.outerHeight();
if (right1 <= left2 || bottom1 <= top2 || left1 >= right2 || top1 >= bottom2) {
return false;
} else {
return true;
}
}
// 勾股定理计算斜边
function distance(obj1, obj2) {
let a = obj1.offset().left - obj2.offset().left;
let b = obj1.offset().top - obj2.offset().top;
return Math.sqrt(a * a + b * b);
}
function animate(obj, json, interval, sp, fn) {
clearInterval(obj.timer);
function getStyle(obj, arr) {
return obj.css(arr);
}
obj.timer = setInterval(function(){
let flag = true;
for(let arr in json) {
let icur = 0;
if(arr == "opacity") {
icur = Math.round(parseFloat(getStyle(obj, arr))*100);
} else {
icur = parseInt(getStyle(obj, arr));
}
let speed = (json[arr] - icur) * sp;
speed = speed > 0 ? Math.ceil(speed): Math.floor(speed);
if(icur != json[arr]){
flag = false;
}
$('#stext').val(icur +'!='+ json[arr]+'-'+arr+':'+flag+':'+obj.data('index'));
if(arr == "opacity"){
obj.css('filter',"alpha(opacity : '+(icur + speed)+' )");
obj.css('opacity',(icur + speed)/100);
}else {
obj.css(arr,icur + speed + "px");
}
}
if(flag){console.log('clear');
clearInterval(obj.timer);
if(fn){
fn();
}
}
},interval);
}
</script>
</body>
</html>