<!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="images/1.jpg">
</li>
<li>
<img src="images/2.jpg">
</li>
<li>
<img src="images/3.jpg">
</li>
<li>
<img src="images/4.jpg">
</li>
<li>
<img src="images/5.jpg">
</li>
<li>
<img src="images/6.jpg">
</li>
<li>
<img src="images/7.jpg">
</li>
<li>
<img src="images/8.jpg">
</li>
<li>
<img src="images/9.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";
// 交换索引
let temp = obj.index;
obj.index = oLi.index;
oLi.index = temp;
}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>```
[可以看码云地址](https://gitee.com/jiang_wei_hao/tuozhuai.git)
简单的拖拽排序
最新推荐文章于 2024-02-29 14:19:08 发布