用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 相关文章推荐
Locate a File Using a File Open Dialog Box
Jun 18 Javascript
jQuery-serialize()输出序列化form表单值的方法
Dec 26 Javascript
二叉树先序遍历的非递归算法具体实现
Jan 09 Javascript
js获取微信版本号的方法
May 12 Javascript
jQuery取消特定的click事件
Feb 29 Javascript
JS获取及验证开始结束日期的方法
Aug 20 Javascript
js实现简单的网页换肤效果
Jan 18 Javascript
jQuery插件Echarts实现的双轴图效果示例【附demo源码下载】
Mar 04 Javascript
在vue项目中引用Iview的方法
Sep 14 Javascript
Vue.js实现大屏数字滚动翻转效果
Nov 29 Javascript
原生JS与CSS实现软件卸载对话框功能
Dec 05 Javascript
JavaScript实现表单验证功能
Dec 09 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实现插入排序?
2013/04/10 PHP
浅析HTTP消息头网页缓存控制以及header常用指令介绍
2013/06/28 PHP
php 判断服务器操作系统的类型
2014/02/17 PHP
php求正负数数组中连续元素最大值示例
2014/04/11 PHP
php自定文件保存session的方法
2014/12/10 PHP
PHP超牛逼无限极分类生成树方法
2015/05/11 PHP
JS宝典学习笔记(下)
2007/01/10 Javascript
jquery validation插件表单验证的一个例子
2010/03/03 Javascript
jquery中dom操作和事件的实例学习 仿yahoo邮箱登录框的提示效果
2011/11/30 Javascript
拖动table标题实现改变td的大小(css+js代码)
2013/04/16 Javascript
jQuery实现根据生日计算年龄 星座 生肖
2016/11/23 Javascript
完美的js图片轮换效果
2017/02/05 Javascript
Bootstrap表单制作代码
2017/03/17 Javascript
xmlplus组件设计系列之图标(ICON)(1)
2017/05/05 Javascript
基于js中document.cookie全面解析
2017/09/14 Javascript
详解vue-cli与webpack结合如何处理静态资源
2017/09/19 Javascript
Three.js实现浏览器变动时进行自适应的方法
2017/09/26 Javascript
jQuery实现获取选中复选框的值实例详解
2018/06/28 jQuery
JavaScript ECMA-262-3 深入解析(二):变量对象实例详解
2020/04/25 Javascript
通过js随机函数Math.random实现乱序
2020/05/19 Javascript
Vue+penlayers实现多边形绘制及展示
2020/12/24 Vue.js
极简的Python入门指引
2015/04/01 Python
Selenium控制浏览器常见操作示例
2018/08/13 Python
python binascii 进制转换实例
2019/06/12 Python
关于pycharm中pip版本10.0无法使用的解决办法
2019/10/10 Python
Python底层封装实现方法详解
2020/01/22 Python
css3实现文字首尾衔接跑马灯的示例代码
2020/10/16 HTML / CSS
产品工艺师的岗位职责
2013/11/15 职场文书
红领巾广播站广播稿
2014/02/01 职场文书
企业安全生产责任书
2014/04/14 职场文书
小学安全教育月活动总结
2014/07/07 职场文书
英语教育专业毕业生求职信
2014/08/28 职场文书
给校长的建议书作文300字
2015/09/14 职场文书
叶县这家生产军用电台的兵工厂,人称“四机部”,走出一上将
2022/02/18 无线电
Nginx实现负载均衡的项目实践
2022/03/18 Servers
Go微服务项目配置文件的定义和读取示例详解
2022/06/21 Golang