模仿google首页拖拽页面模块

html

<body style="margin: 0 auto">
    <table id="dragTable" cellpadding="3" style="border: solid 0px green; width: 98%;">
        <tr>
            <td valign="top" style="width: 30%">
                <div class="dragDiv" id="dragDiv1">
                    <table cellpadding="0" cellspacing="0" border="1" style="width: 100%; border-collapse: collapse;
                        border-color: Blue">
                        <tr id="titleBar1" style="height: 22px; text-align: left; background-color: #547BC9;
                            color: White; padding: 3px; cursor: move;">
                            <th align="left" unselectable="on">
                                Title1
                            </th>
                        </tr>
                        <tr style="height: 130px; padding: 3px;" align="left" valign="top">
                            <td unselectable="on">
                                这里的字比较长....我来了....中国....中国...外国.,看一下有没有溢出>
                            </td>
                        </tr>
                    </table>
                </div>
                <div class="dragDiv" id="dragDiv2">
                    <table cellpadding="0" cellspacing="0" border="1" style="width: 100%; border-collapse: collapse;
                        border-color: Blue">
                        <tr id="titleBar2" style="height: 22px; text-align: left; background-color: #547BC9;
                            color: White; padding: 3px; cursor: move;">
                            <th align="left" unselectable="on">
                                Title2
                            </th>
                        </tr>
                        <tr style="height: 130px; padding: 3px;" align="left" valign="top">
                            <td unselectable="on">
                                Content2...
                            </td>
                        </tr>
                    </table>
                </div>
            </td>
            <td valign="top" style="width: 50%">
                <div class="dragDiv" id="dragDiv3">
                    <table cellpadding="0" cellspacing="0" border="1" style="width: 100%; border-collapse: collapse;
                        border-color: Blue">
                        <tr id="titleBar3" style="height: 22px; text-align: left; background-color: #547BC9;
                            color: White; padding: 3px; cursor: move;">
                            <th align="left" unselectable="on">
                                Title3
                            </th>
                        </tr>
                        <tr style="height: 230px; padding: 3px;" align="left" valign="top">
                            <td unselectable="on">
                                Content3...
                            </td>
                        </tr>
                    </table>
                </div>
            </td>
            <td valign="top" style="width: 20%">
                <div class="dragDiv" id="dragDiv4">
                    <table cellpadding="0" cellspacing="0" border="1" style="width: 100%; border-collapse: collapse;
                        border-color: Blue">
                        <tr id="titleBar4" style="height: 22px; text-align: left; background-color: #547BC9;
                            color: White; padding: 3px; cursor: move;">
                            <th align="left" unselectable="on">
                                Title4
                            </th>
                        </tr>
                        <tr style="height: 130px; padding: 3px;" align="left" valign="top">
                            <td unselectable="on">
                                Content4...
                            </td>
                        </tr>
                    </table>
                </div>
                <div class="dragDiv" id="dragDiv5">
                    <table cellpadding="0" cellspacing="0" border="1" style="width: 100%; border-collapse: collapse;
                        border-color: Blue">
                        <tr id="titleBar5" style="height: 22px; text-align: left; background-color: #547BC9;
                            color: White; padding: 3px; cursor: move;">
                            <th align="left" unselectable="on">
                                Title5
                            </th>
                        </tr>
                        <tr style="height: 130px; padding: 3px;" align="left" valign="top">
                            <td unselectable="on">
                                Content5...
                            </td>
                        </tr>
                    </table>
                </div>
            </td>
        </tr>
    </table>
</body>

 

设计思路

/*
首先实现模块拖拽功能(略).
如何在拖拽后生产新的位置呢?
1. 点击某个可拖拽元素生成一个clone元素, 这个clone就是显示即将生成新元素的位置.
2. 在鼠标拖拽的时候, 得到所有可拖拽元素的坐标信息和二级容器的坐标
然后进行判断是否符合要求并生成
*/
<style type="text/css">
        .Draging_Clone{ border:dashed 2px #aaa;}
    </style>
    <script type="text/javascript">
 
        var DragDrop = function () {
            //
            var targetElement = "";
            var zIndex = 1000;
            var handler = arguments[1] || "";
            if (typeof arguments[0] == "string") {
                targetElement = document.getElementById(arguments[0]);
            }
            else
                targetElement = arguments[0];
            tools.bind(targetElement, "mouseover", mouseOn); //鼠标移上去改变目标元素的鼠标样式
            tools.bind(targetElement, "mousedown", mouseMove); //鼠标按下
 
 
            function mouseOn(event) {
                if (handler) {
                    if (typeof handler == "string")
                        document.getElementById(handler).style.cursor = "move";
                    else
                        handler.style.cursor = "move";
                }
                else
                    targetElement.style.cursor = "move";
            }
 
            //鼠标按下
            function mouseMove(event) {
                var event = window.event || event;
 
                //鼠标按下的同时, 原位置应该克隆一个新的target, 并赋予其相关属性.  克隆出来的元素的作用是拖拽元素至容器中的时候制造将要添加的效果.
                var clone = targetElement.cloneNode(true);
                clone.innerHTML = ""; clone.className = "Draging_Clone";
                clone.setAttribute('id', 'clone_' + clone.id);
                //保存目标元素的父元素以及下一个元素
                var targetElementFather = targetElement.parentNode;
                var nextSibling = tools.getNextNode(targetElement);
                //如果元素的宽高是由所在父元素决定的话, 手动保存其原始宽高
 
                targetElement.style.width = targetElement.offsetWidth + "px";
                clone.style.width = "auto";
                targetElement.style.height = targetElement.offsetHeight + "px";
                clone.style.height = targetElement.offsetHeight + "px";
 
                targetElement.style.position = "absolute";
                targetElement.style.zIndex = zIndex;
                zIndex++; //该div的样式改变
 
                var offset = tools.getOffsetCoordinates(targetElement); //获得该目标距离页面顶部\左边的距离作为绝对坐标, 并作为闭包成员供move方法访问
                targetElement.style.top = offset.top + "px";
                targetElement.style.left = offset.left + "px";
 
                var mousedownClient = { top: event.clientY, left: event.clientX }; //当前鼠标按下的坐标,  作为闭包成员供move方法访问
 
                var dragArray = RegDragsPos(); //保存其他的可以移动的元素的坐标信息
 
                //实现移动目标元素的方法
                var move = function (event) {
                    var top = parseInt(offset.top) + parseInt(event.clientY) - mousedownClient.top;
                    targetElement.style.top = top + "px";
                    targetElement.style.left = parseInt(offset.left) + parseInt(event.clientX) - mousedownClient.left + "px";
                    //目标元素坐标=鼠标移动地的坐标-鼠标按下时的坐标+鼠标按下时候目标元素的绝对坐标
 
                    if (!document.getElementById(clone.getAttribute('id'))) {
                        if (nextSibling)
                            targetElementFather.insertBefore(clone, nextSibling);
                        else
                            targetElementFather.appendChild(clone);
                    }
 
                    var targetDiv = null;
                    //同类可以移动元素
                    for (var k = 0; k < dragArray.length; k++) {
                        //如果鼠标在某个可移动元素之内
                        if (event.clientX > dragArray[k].PosLeft && event.clientX < (dragArray[k].PosLeft + dragArray[k].PosWidth)
                            && event.clientY > dragArray[k].PosTop && event.clientY < (dragArray[k].PosTop + dragArray[k].PosHeight)
                        ) {
                            targetDiv = document.getElementById(dragArray[k].DragId); //得到
                            clone.style.width = "auto"
                            if (event.clientY < dragArray[k].PosTop + dragArray[k].PosHeight / 2) {//如果在上半部, 那么需要在上面插入
                                targetDiv.parentNode.insertBefore(clone, targetDiv);
                            }
                            else {
                                //下半部
                                if (targetDiv.nextSibling) {
                                    targetDiv.parentNode.insertBefore(clone, targetDiv.nextSibling);
                                }
                                else {
                                    targetDiv.parentNode.appendChild(clone);
                                }
                            }
                        }
                    }
 
                    var cells = DragDrop.Config.ContainerElements;//这一段在二级容器里面如果没有同类可拖拽元素, 那么附加上克隆出来的节点绘制"将要添加"效果
                    var dragElementTagName = DragDrop.Config.dragElementTagName;
                    for (var i = 0; i < cells.length; i++) {
                        var cellposition = tools.getOffsetCoordinates(cells[i])
                        if (cells[i].getElementsByTagName(dragElementTagName).length == 0) {//该容器下没有可拖拽目标
                            if (event.clientX > cellposition.left && event.clientX < (cellposition.left + cells[i].offsetWidth) &&
                           event.clientY > cellposition.top && event.clientY < (cellposition.top + cells[i].offsetHeight)
                              ) {
                                cells[i].appendChild(clone);
                            }
                        }
 
                    }
                }
 
 
                //绑定鼠标移动则移动目标元素
                tools.bind(targetElement, "mousemove", move)
 
 
                function rollback() {
                    if (nextSibling)
                        targetElementFather.insertBefore(clone, nextSibling);
                    else
                        targetElementFather.appendChild(clone);
                    targetElementFather.removeChild(clone);
                    $(targetElement).css({ position: "", top: "", left: "" });
                }
 
                //确定插入到新的位置..
                function setNewPosition() {
                    $(targetElement).css({ position: "", top: "", left: "", width: clone.style.width, height: clone.style.height });
                    if (document.getElementById(clone.id))
                        clone.parentNode.replaceChild(targetElement, clone);
                }
 
                //如果松开鼠标按钮、或者鼠标滑出handler的范围, 则移除mousemove的绑定
                tools.bind(targetElement, "mouseup", function (event) {
                    tools.unbind(targetElement, "mousemove", move);
                    //rollback();
                    setNewPosition();
                })
                //防止鼠标滑出的bug
                tools.bind(handler || targetElement, "mouseout", function (event) {
                    tools.unbind(targetElement, "mousemove", move);
                    //rollback();
                    setNewPosition();
                })
 
 
            }
 
            var RegDragsPos = function () {//把所有布局(二级)容器的坐标信息整理返回
                var arrDragDivs = new Array();
                var dragTbl = DragDrop.Config.FatherContainer;
                var tmpDiv, tmpPos;
                for (i = 0; i < dragTbl.getElementsByTagName(DragDrop.Config.dragElementTagName).length; i++) {
                    tmpDiv = dragTbl.getElementsByTagName(DragDrop.Config.dragElementTagName)[i];
                    if (tmpDiv.style.position != "absolute") {
                        tmpPos = tools.getOffsetCoordinates(tmpDiv);
                        arrDragDivs.push({ DragId: tmpDiv.id, PosLeft: tmpPos.left, PosTop: tmpPos.top, PosWidth: tmpDiv.offsetWidth, PosHeight: tmpDiv.offsetHeight });
                    }
                }
                return arrDragDivs;
            }
        }
 
        /*工具函数 */
        var tools = {
            /*     ******************工具函数*/
            bind: function (element, type, fn) {
                if (element.attachEvent) {
                    element.attachEvent("on" + type, fn);
                } else
                    element.addEventListener(type, fn, false);
            },
            unbind: function (element, type, fn) {
                if (element.detachEvent) {
                    element.detachEvent("on" + type, fn);
                } else
                    element.removeEventListener(type, fn, false);
            },
            getOffsetCoordinates: function (obj) {
                ///    <summary>
            ///        anthor: 简佳林 date 2010-7-27
            ///     获得某个元素距离顶部以及底部的坐标 返回{top: value , left: value}    
            ///    </summary>
            ///    <returns type="boolean" />
                var top = 0, left = 0;
                while (obj) {
                    top += obj.offsetTop;
                    left += obj.offsetLeft;
                    obj = obj.offsetParent;
                }
                return { top: top, left: left };
            },
            getEvent: function () {
                if (document.all)
                    return window.event;
                else {
                    var func = getEvent.caller;
 
                    while (func) {
                        var arg0 = arguments[0];
                        if (arg0) {
                            if ((typeof (arg0) == "object" && arg0.preventDefault && arg0.stopPropagation)) {
                                return arg0;
                            }
                        }
                        func = func.caller;
                    }
                    return null;
                }
            },
            getNextNode: function (node) {
                return node.nextSibling ? (node.nextSibling.nodeType == 1 ? node.nextSibling : arguments.callee(node.nextSibling)) : "";
            },
            hasChild : function (father, obj) {
                var flag = false;
                var nodes = father.childNodes
                for (var i = 0; i < nodes; i++) {
                    if (nodes[i].id = obj.id) {
                        flag = true;
                        break;
                    }
                }
                return hasChild;
            }
            /*     ******************工具函数*/
        }
 
        window.onload = function () {
            var divs = document.getElementById("dragTable").getElementsByTagName("div");
            DragDrop.Config = {
                ContainerElements:document.getElementById("dragTable").tBodies[0].rows[0].cells,
                dragElementTagName: "div",
                FatherContainer: document.getElementById("dragTable")
            }
            for (var i = 0; i < divs.length; i++) {
                DragDrop(divs[i], divs[i].getElementsByTagName('th')[0]);
            }
 
        }
    </script>
posted @ 2010-07-27 16:52  MyCoolDog  阅读(495)  评论(1编辑  收藏  举报