用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 相关文章推荐
用js实现in_array的方法
Nov 05 Javascript
随鼠标上下滚动的jquery代码
Dec 05 Javascript
JS实现点击按钮控制Div变宽、增高及调整背景色的方法
Aug 05 Javascript
JQuery组件基于Bootstrap的DropDownList(完整版)
Jul 05 Javascript
JavaScript SHA-256加密算法详细代码
Oct 06 Javascript
js验证手机号、密码、短信验证码代码工具类
Jun 24 Javascript
分析javascript中9 个常见错误阻碍你进步
Sep 18 Javascript
详解Vue用自定义指令完成一个下拉菜单(select组件)
Oct 31 Javascript
更改BootStrap popover的默认样式及popover简单用法
Sep 13 Javascript
记一次Vue.js混入mixin的使用(分权限管理页面)
Apr 17 Javascript
为vue项目自动设置请求状态的配置方法
Jun 09 Javascript
二维码条形码生成的JavaScript脚本库
Jul 07 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安全配置方法
2007/06/16 PHP
PHP基于GD库的缩略图生成代码(支持jpg,gif,png格式)
2014/06/19 PHP
百度Popup.js弹出框进化版 拖拽小框架发布 兼容IE6/7/8,Firefox,Chrome
2010/04/13 Javascript
JS嵌套函数调用上下文的问题解决
2014/03/26 Javascript
浅谈javascript中字符串String与数组Array
2014/12/31 Javascript
jQuery+PHP实现动态数字展示特效
2015/03/14 Javascript
jQuery选择id属性带有点符号元素的方法
2015/03/17 Javascript
Bootstrap modal 多弹窗之叠加关闭阴影遮罩问题的解决方法
2017/02/27 Javascript
JavaScript数组_动力节点Java学院整理
2017/06/26 Javascript
微信小程序之发送短信倒计时功能
2017/08/30 Javascript
Nodejs Express 通过log4js写日志到Logstash(ELK)
2018/08/30 NodeJs
微信小程序实现展示评分结果功能
2019/02/15 Javascript
微信小程序控制台提示warning:Now you can provide attr &quot;wx:key&quot; for a &quot;wx:for&quot; to improve performance解决方法
2019/02/21 Javascript
微信小程序picker组件关于objectArray数据类型的绑定方法
2019/03/13 Javascript
微信JS-SDK实现微信会员卡功能(给用户微信卡包里发送会员卡)
2019/07/25 Javascript
Python类的专用方法实例分析
2015/01/09 Python
使用Python脚本将绝对url替换为相对url的教程
2015/04/24 Python
Python实现方便使用的级联进度信息实例
2015/05/05 Python
Python中DJANGO简单测试实例
2015/05/11 Python
Python AES加密模块用法分析
2017/05/22 Python
Python读取和处理文件后缀为.sqlite的数据文件(实例讲解)
2017/06/27 Python
python re模块的高级用法详解
2018/06/06 Python
Python爬虫 批量爬取下载抖音视频代码实例
2019/08/16 Python
python使用requests库爬取拉勾网招聘信息的实现
2020/11/20 Python
CSS3 please 跨浏览器的CSS3产生器
2010/03/14 HTML / CSS
全球度假村:Club Med
2017/11/27 全球购物
Fossil美国官网:化石手表、手袋、首饰及配饰
2019/02/17 全球购物
大专生自荐信
2013/10/04 职场文书
大学生专业个人学习的自我评价
2013/10/26 职场文书
《美丽的公鸡》教学反思
2014/02/25 职场文书
初中升旗仪式演讲稿
2014/05/08 职场文书
新书发布会策划方案
2014/06/09 职场文书
明星员工获奖感言
2014/08/14 职场文书
2015年银行个人工作总结
2015/05/14 职场文书
用电申请报告范文
2015/05/18 职场文书
php实现自动生成验证码的实例讲解
2021/11/17 PHP