用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实现运行代码需要刷新的解决方法
Aug 18 Javascript
JQuery 前台切换网站的样式实现
Jun 22 Javascript
使用jQuery.Validate进行客户端验证(初级篇) 不使用微软验证控件的理由
Jun 28 Javascript
CSS和Javascript简单复习资料
Jun 29 Javascript
40个有创意的jQuery图片和内容滑动及弹出插件收藏集之二
Dec 31 Javascript
js获取dom的高度和宽度(可见区域及部分等等)
Jun 13 Javascript
js阻止默认事件与js阻止事件冒泡示例分享 js阻止冒泡事件
Jan 27 Javascript
new Date()问题在ie8下面的处理方法
Jul 31 Javascript
jQuery制作简洁的图片轮播效果
Apr 03 Javascript
JavaScript事件 &quot;事件对象&quot;的注意要点
Jan 14 Javascript
超实用的JavaScript表单代码段
Feb 26 Javascript
jQuery zTree搜索-关键字查询 递归无限层功能实现代码
Jan 25 jQuery
用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环境配置 php5 mysql5 apache2 phpmyadmin安装与配置
2006/11/17 PHP
提高PHP编程效率 引入缓存机制提升性能
2010/02/15 PHP
PHP的博客ping服务代码
2012/02/04 PHP
PHP获取中英混合字符串长度的方法
2014/06/07 PHP
php实现批量压缩图片文件大小的脚本
2014/07/04 PHP
PhpStorm配置Xdebug调试的方法步骤
2019/02/02 PHP
PHP开启目录引索+fancyindex漂亮目录浏览带搜索功能
2019/09/23 PHP
jQuery 全选效果实现代码
2009/03/23 Javascript
Javascript 多浏览器兼容总结(实战经验)
2013/10/30 Javascript
jquery bind(click)传参让列表中每行绑定一个事件
2014/08/06 Javascript
JavaScript实现简单的二级导航菜单实例
2015/04/15 Javascript
Prototype框架详解
2015/11/25 Javascript
Sort()函数的多种用法
2016/03/20 Javascript
AngularJS中实现用户访问的身份认证和表单验证功能
2016/04/21 Javascript
jquery实现无刷新验证码的简单实例
2016/05/19 Javascript
JS实现滑动门效果的方法详解
2016/12/19 Javascript
Angularjs2不同组件间的通信实例代码
2017/05/06 Javascript
node.js监听文件变化的实现方法
2019/04/17 Javascript
jQuery实现input[type=file]多图预览上传删除等功能
2019/08/02 jQuery
vue v-on:click传递动态参数的步骤
2020/09/11 Javascript
[03:03]DOTA2校园争霸赛 济南城市决赛欢乐发奖活动
2013/10/21 DOTA
[47:55]Ti4第二日主赛事败者组 NaVi vs EG 1
2014/07/20 DOTA
Python时间戳使用和相互转换详解
2017/12/11 Python
使用Python获取网段IP个数以及地址清单的方法
2018/11/01 Python
Python编程学习之如何判断3个数的大小
2019/08/07 Python
python实现树的深度优先遍历与广度优先遍历详解
2019/10/26 Python
Anconda环境下Vscode安装Python的方法详解
2020/03/29 Python
Python生成器next方法和send方法区别详解
2020/05/30 Python
Python性能分析工具py-spy原理用法解析
2020/07/27 Python
美国百年历史早餐食品供应商:Wolferman’s
2017/01/18 全球购物
屈臣氏乌克兰:Watsons UA
2019/10/29 全球购物
沃尔玛加拿大:Walmart.ca
2020/03/02 全球购物
敬老院活动感想
2015/08/07 职场文书
大学副班长竞选稿
2015/11/21 职场文书
用python修改excel表某一列内容的操作方法
2021/06/11 Python
Python字符串的转义字符
2022/04/07 Python