用javascript做拖动布局的思路


Posted in Javascript onMay 31, 2008

好了,转入正文,在开始之前先介绍几个功能函数!
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;  
} 

好了,一个可以拖动布局的页面就完成了  查看最终页面效果

能力有限,有些地方可能说的不清不楚,若有兴趣,自己好好看看代码吧。
有什么不足的地方,请指教。

Javascript 相关文章推荐
jquery实现图片渐变切换兼容ie6/Chrome/Firefox
Aug 02 Javascript
Javascript实现的常用算法(如冒泡、快速、鸽巢、奇偶等)
Apr 29 Javascript
Bootstrap模态对话框的简单使用
Apr 29 Javascript
React组件的三种写法总结
Jan 12 Javascript
Bootstrap 3浏览器兼容性问题及解决方案
Apr 11 Javascript
微信小程序报错:this.setData is not a function的解决办法
Sep 27 Javascript
JavaScript数据结构之优先队列与循环队列实例详解
Oct 27 Javascript
Vue Cli3 创建项目的方法步骤
Oct 15 Javascript
详解vue文件中使用echarts.js的两种方式
Oct 18 Javascript
node删除、复制文件或文件夹示例代码
Aug 13 Javascript
Vue简单封装axios之解决post请求后端接收不到参数问题
Feb 16 Javascript
vue在线动态切换主题色方案
Mar 26 Javascript
用JS实现一个页面多个css样式实现
May 29 #Javascript
使用jquery给input和textarea设定ie中的focus
May 29 #Javascript
js中cookie的使用详细分析
May 28 #Javascript
javascript一点特殊用法
May 28 #Javascript
js 加载时自动调整图片大小
May 28 #Javascript
javascript document.images实例
May 27 #Javascript
javascript Discuz代码中的msn聊天小功能
May 25 #Javascript
You might like
关于php 高并发解决的一点思路
2017/04/16 PHP
php实现JWT(json web token)鉴权实例详解
2019/11/05 PHP
Yii2框架中一些折磨人的坑
2019/12/15 PHP
JavaScript计算某一天是星期几的方法
2015/08/05 Javascript
JS数字千分位格式化实现方法总结
2016/12/16 Javascript
Vue实现双向绑定的方法
2016/12/22 Javascript
利用HTML5+Socket.io实现摇一摇控制PC端歌曲切换
2017/01/13 Javascript
javascript 使用正则test( )第一次是 true,第二次是false
2017/02/22 Javascript
xmlplus组件设计系列之网格(DataGrid)(10)
2017/05/05 Javascript
AngularJS表单验证功能分析
2017/05/26 Javascript
微信小程序tabbar不显示解决办法
2017/06/08 Javascript
常见的浏览器Hack技巧整理
2017/06/29 Javascript
node实现简单的反向代理服务器
2017/07/26 Javascript
使用react-router4.0实现重定向和404功能的方法
2017/08/28 Javascript
浅析vue中常见循环遍历指令的使用 v-for
2018/04/18 Javascript
在react中使用vue的状态管理的方法示例
2020/05/02 Javascript
2020淘宝618理想生活列车自动领喵币js脚本的代码
2020/06/02 Javascript
vue+elementUI 实现内容区域高度自适应的示例
2020/09/26 Javascript
[17:36]VG战队纪录片
2014/08/21 DOTA
Python实现控制台输入密码的方法
2015/05/29 Python
Python cookbook(数据结构与算法)将多个映射合并为单个映射的方法
2018/04/19 Python
在python 中实现运行多条shell命令
2019/01/07 Python
使用Python的OpenCV模块识别滑动验证码的缺口(推荐)
2019/05/10 Python
python实现微信自动回复及批量添加好友功能
2019/07/03 Python
Python爬虫学习之获取指定网页源码
2019/07/30 Python
使用Tensorboard工具查看Loss损失率
2020/02/15 Python
CSS3的resize属性使用初探
2015/09/27 HTML / CSS
巴西最大的玩具连锁店:Ri Happy
2020/06/17 全球购物
公积金单位接收函
2014/01/11 职场文书
元旦联欢会感言
2014/03/04 职场文书
公务员群众路线专题民主生活会发言材料
2014/09/17 职场文书
2014年档案管理工作总结
2014/11/17 职场文书
2015年业务员工作总结范文
2015/04/07 职场文书
人事聘任通知
2015/04/21 职场文书
大学毕业典礼致辞
2015/07/29 职场文书
学习型家庭事迹材料(2016精选版)
2016/02/29 职场文书