zoukankan      html  css  js  c++  java
  • 用javascript做拖动布局的思路

    这几天不是很忙,就找了些拖动布局方面的资料看看,也学着写了个拖动布局的效果,没想到花了好多时间,
    七拼八凑,总算是把这个效果写出来了。哎!还是js的功夫太差。因为是边找资料边写的,很多地方印象不深,
    时间一长,再重新写估计也难,所以把当时的思路记录一下!也希望大虾指点一下!

    好了,转入正文,在开始之前先介绍几个功能函数!
    1.格式化事件的函数
     程序代码

    function getEvent(){
         //同时兼容ie和ff的写法
         if(document.all)    return window.event;
         func=getEvent.caller;
         while(func!=null){
             var arg0=func.arguments[0];
             if(arg0){
                 if((arg0.constructor==Event || arg0.constructor ==MouseEvent)
                    || (typeof(arg0)=="object" && arg0.preventDefault && arg0.stopPropagation)){    
                    return arg0;
                  }
             }
              func=func.caller;
            }
            return null;
    }

    2.取得鼠标的位置
     程序代码

    function mouseCoords(ev){
        if(ev.pageX || ev.pageY){
            return {x:ev.pageX, y:ev.pageY};
        }
        return {
            x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
            y:ev.clientY + document.body.scrollTop - document.body.clientTop
        };
    }

    3.得到元素的位置
     程序代码

    function getPosition(ele){
        var left = 0;
        var top = 0;
        while (ele.offsetParent){
            left += ele.offsetLeft;
            top += ele.offsetTop;
            ele = ele.offsetParent;
        }
        left += ele.offsetLeft;
        top += ele.offsetTop;
        return {x:left, y:top};
    }


    首先,当然是写好初始布局的页面

    一般拖动的元素是跟随鼠标的,我的思路是在把拖动的元素增加到一个position为absolute的div中,
    鼠标拖动的时候就让它的位置根据鼠标的坐标变化就可以了。所以在页面增加了个onload
     程序代码

    var tmpDiv=null;//临时存放拖动对象的div
    window.onload=function(){
        tmpDiv=document.createElement("div");
        tmpDiv.style.cssText = 'position:absolute;display:none;border:1px dotted #FFCC66;';
        document.body.appendChild(tmpDiv);
    }

    要实现拖动,首先触发的事件是mouseDown,所以我在拖动的table的一个td上绑定了onmousedown="mouseDown(this);"
     程序代码

    var dragObject = null;//拖动的元素(table)
    var mouseOffset = null;//鼠标的在拖动元素中的位置
    var dragDiv=null;//拖动的table所在的列的div
    var eleDivW=null;//拖动的table的父节点(div)的高度
    var dragDivLen=null;//拖动的table所在的列的div中用来放置table的div的个数
    var DragContainer=["col1","col2","col3"];//用来实现列布局的div的id
    //鼠标按下拖动的元素
    function mouseDown(elem){
        ev=getEvent();
        dragObject = elem.parentNode.parentNode.parentNode;//被拖动的table
        dragDiv=dragObject.parentNode.parentNode;
        //拖动元素所在列里div的个数
        dragDivLen=dragDiv.getElementsByTagName("div").length;
        mouseOffset = getMouseOffset(dragObject, ev);
        eleDivW=dragObject.parentNode.offsetWidth;
        dragObject.parentNode.style.border="1px dotted #FFCC66";
        return false;
    }
    //得到鼠标在拖动元素中的位置
    function getMouseOffset(target, ev){
        var docPos = getPosition(target);
        var mousePos = mouseCoords(ev);
        return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y};
    }

    剩下的当然就是鼠标移动拖动对象也能移动,用到的当然就是mouseMove咯,为简单我在document上绑定,
     程序代码

    document.onmousemove = mouseMove;
    function mouseMove(){
        ev=getEvent();
        var mousePos = mouseCoords(ev);
        if(dragObject){
            dragObject.parentNode.style.display="none";//设置放置被拖动table的div隐藏
            //把拖动的table放到临时的div中,并设置其坐标
            for(var i=0; i<tmpDiv.childNodes.length; i++) tmpDiv.removeChild(tmpDiv.childNodes[i]);
            tmpDiv.appendChild(dragObject.cloneNode(true));
            tmpDiv.style.width=eleDivW+"px";
            tmpDiv.style.backgroundColor="#FFFFFF";
            tmpDiv.style.display="block";
            tmpDiv.style.top = (mousePos.y - mouseOffset.y)+"px";
            tmpDiv.style.left = (mousePos.x - mouseOffset.x)+"px";
        }
        return false;
    }

    有了mousemove当然少不了mouseup
     程序代码

    document.onmouseup = mouseUp;
    //鼠标松开
    function mouseUp(){
        if(dragObject){
            if(dragObject.parentNode.style.display=="none") dragObject.parentNode.style.display="block";
            dragObject.parentNode.style.border="1px solid #FFCC66";
            tmpDiv.style.display="none";
            //这里是判断当列里有可拖动的元素时清除前面设置的高度值20px
            for(var m=0;m<DragContainer.length;m++){
                var colDiv=document.getElementById(DragContainer[m]);
                var colDivLen=colDiv.getElementsByTagName("div").length
                var colSty=colDiv.getAttribute("style");
                if(colDivLen>0&&colSty!=null){
                    colDiv.removeAttribute("style");
                    break;
                }
            }
            dragObject=null;
        }
    }


    看看是不是可以拖动了,当你松开鼠标左键时,拖动的元素将回到原来的位置


    最后要做的就是让拖动元素不回到原来的位置,而是回到我们拖动的位置。
    下面是mousemove事件的所有代码,看看注释就明白了
     程序代码

    function mouseMove(){
        ev=getEvent();
        var mousePos = mouseCoords(ev);
        if(dragObject){
            //可拖动的个数为1,说明拖动后此列就没有拖动元素,为避免此列没有高度而不见,所以设置其高度为20px
            if(dragDivLen==1) dragDiv.style.height="20px";
            dragObject.parentNode.style.display="none";
            //把拖动的元素加入到临时的tmpDiv中,并设置tmpDiv坐标
            for(var i=0; i<tmpDiv.childNodes.length; i++) tmpDiv.removeChild(tmpDiv.childNodes[i]);
            tmpDiv.appendChild(dragObject.cloneNode(true));
            tmpDiv.style.width=eleDivW+"px";
            tmpDiv.style.backgroundColor="#FFFFFF";
            tmpDiv.style.display="block";
            tmpDiv.style.top = (mousePos.y - mouseOffset.y)+"px";
            tmpDiv.style.left = (mousePos.x - mouseOffset.x)+"px";
            //被拖动对象的中心点的坐标
            var dragObjCntX=mousePos.x - mouseOffset.x+parseInt(dragObject.offsetWidth)/2;
            var dragObjCntY=mousePos.y - mouseOffset.y+parseInt(dragObject.offsetHeight)/2;
            //判断tmpDiv所在的列
            var dragConLen=DragContainer.length;
            for(var i=0;i<dragConLen;i++){
                var curContainer=document.getElementById(DragContainer[i]);
                var dcPos=getPosition(curContainer);
                var dcPosMinX=dcPos.x;
                var dcPosMinY=dcPos.y;
                var dcWidth=curContainer.offsetWidth;
                var dcHeight=curContainer.offsetHeight;
                var dcPosMaxX=dcPosMinX+dcWidth;
                var dcPosMaxY=dcPosMinY+dcHeight;
                if(dragObjCntX>dcPosMinX&&dragObjCntX<dcPosMaxX&&dragObjCntY>dcPosMinY&&dragObjCntY<dcPosMaxY){
                    var activeContainer=curContainer;
                    break;
                }
            }
        }
        //判断tmpDiv在此列哪个区块范围内
        if(activeContainer){
            var beforNode=null;
            var sDiv=activeContainer.getElementsByTagName("div")
            var acChiLen=sDiv.length;
            for(j=acChiLen-1;j>=0;j--){
                var activeDiv=sDiv[j];
                if(activeDiv){
                    var activeDivPos=getPosition(activeDiv);
                    var activeDivMinX=activeDivPos.x;
                    var activeDivMinY=activeDivPos.y;
                    var activeDivMaxX=activeDivMinX+activeDiv.offsetWidth;
                    var activeDivMaxY=activeDivMinY+activeDiv.offsetHeight;
                    if(activeDivMaxX>dragObjCntX&&activeDivMaxY>dragObjCntY){
                    //if(dragObjCntX>activeDivMinX&&dragObjCntX<activeDivMaxX&&dragObjCntY>activeDivMinY&&dragObjCntY<activeDivMaxY){
                        beforNode=activeDiv;
                    }
                }
                
            }
            //若此区块存在,就在此区块前插入拖动元素
            if(beforNode!=null){
                if(dragObject.parentNode!=beforNode){
                    curContainer.insertBefore(dragObject.parentNode,beforNode);
                    dragObject.parentNode.style.display="block";
                    //document.getElementById("test").value=curContainer.id;
                }
            }
            //不存在就在所在列插入拖动元素
            else{
                curContainer.appendChild(dragObject.parentNode);
                dragObject.parentNode.style.display="block";
            }
        }
        return false;
    }

    好了,一个可以拖动布局的页面就完成了
  • 相关阅读:
    HTTP 协议中的并发限制及队首阻塞问题
    聊聊JMM
    聊聊CacheLine
    git解决本地建立git仓库 连接远程git仓库出现拒绝合并问题
    django 本地项目部署uwsgi 以及云服务器部署 uwsgi+Nginx+Docker+MySQL主从
    我的第一篇播客
    大爷的超市管理系统——冲刺第一天
    能混绝不C——凡事预则立
    2020软件工程团队作业——05
    2020软件工程作业——04
  • 原文地址:https://www.cnblogs.com/top5/p/1862763.html
Copyright © 2011-2022 走看看