移动端拖动

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script type="text/javascript" src="js/jquery.min.js"></script>
    <title>拖拽</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        ul {
            list-style: none;
        }
        #drag ul {
            width: 612px;
        }
        #drag ul li {
            width: 100px;
            height: 100px;
            float: left;
            border: 1px solid transparent;
        }
        #drag ul li img {
            width: 100px;
            height: 100px;
        }
        
        @media only screen and (max-width: 750px) {
            #drag ul {
                width: 100%;
            }
            #drag ul li {
                width: 100px;
                height: 100px;
                float: left;
                border: 1px solid transparent;
            }
            #drag ul li img {
                width: 100px;
                height: 100px;
            }
        }
    </style>
</head>
<body>
    <div id="drag">
        <ul>
            <li>
                <img src="img/1.png" alt="1.jpg">
            </li>
            <li>
                 <img src="img/Request-1.png" alt="2.jpg">
            </li>
            <li>
                 <img src="img/logo.png" alt="4.jpg">
            </li>
            <li>
                 <img src="img/sold.jpg" alt="5.jpg">
            </li>
            <li>
                <img src="img/1.png" alt="1.jpg">
            </li>
            <li>
                 <img src="img/Request-1.png" alt="2.jpg">
            </li>
            <li>
                 <img src="img/logo.png" alt="4.jpg">
            </li>
            <li>
                 <img src="img/sold.jpg" alt="5.jpg">
            </li>
            <li>
                <img src="img/1.png" alt="1.jpg">
            </li>
            <li>
                 <img src="img/Request-1.png" alt="2.jpg">
            </li>
            <li>
                 <img src="img/logo.png" alt="4.jpg">
            </li>
            <li>
                 <img src="img/sold.jpg" alt="5.jpg">
            </li>
            <li>
                <img src="img/1.png" alt="1.jpg">
            </li>
            <li>
                 <img src="img/Request-1.png" alt="2.jpg">
            </li>
            <li>
                 <img src="img/logo.png" alt="4.jpg">
            </li>
            <li>
                 <img src="img/sold.jpg" alt="5.jpg">
            </li>
            <li>
                 <img src="img/sold.jpg" alt="5.jpg">
            </li>
            <li>
                 <img src="img/logo.png" alt="4.jpg">
            </li>
        </ul>
    </div>
    <script type="text/javascript">
    if (
      navigator.userAgent.match(/Mobi/i) ||
      navigator.userAgent.match(/Android/i) ||
      navigator.userAgent.match(/iPhone/i)
    ){
        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",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",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",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);
        }
    }else{
        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>

 

posted @ 2023-07-26 16:54  热心市民~菜先生  阅读(13)  评论(0编辑  收藏  举报