简单拖拽布局 cookie

参考的google的拖拽布局,

用的鼠标的x=e.clientx  和 y=e.clienty,判断是否在其它块里面


offest = pos(div)       div为需要检测碰撞的块
x>offset.left&&x<offset.right&&y>offset.top&&y<offset.bottom

有一个占位div  一个代理div

占位div就是放到的位置

代理div就是拖拽时候的代理层

在写的时候遇到了一些问题和要注意的地方

1.在ie6,7下 如果没有设置高度和宽度  直接设置透明度是不会透明的  可以在样式写*zoom:1 触发它的layout
2.拖拽的时候可能会选中文字图片什么的  在退拽的过程中可以不断的清空选中  window.getSelection? window.getSelection().removeAllRanges(): document.selection.empty();
3.初始化的时候 我会清除掉里面的dom块  如果用innerHTML ="" 发现ie6下加上dom块  样式加载不了....  所以用的removeChild  而且多遍历了一次
4. 当占位div(虚线的div)加到页面上的时候 计算碰撞的位置 是占位div 和 别选中的那个div合起来的面积

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>拖拽布局</title>
<style type="text/css">
html,body{ overflow-x:hidden; overflow-y:auto;}
*{ margin:0px; padding:0px;}
body{ font-size:12px;}
#warp{ 960px; margin:0 auto; overflow:hidden;zoom:1;}
#warp #left{ 180px; padding:10px;float:left;}
#warp #center{ 380px; padding:10px;float:left;}
#warp #right{ 340px; padding:10px;float:left;}
#warp .c{ border:1px solid #DCDCDC; margin:10px 0; zoom:1}
#warp .c.h{ border:1px solid #03C;}
#warp .c.b{ border:1px dashed #999;}
#warp .c .hd{ padding:0px 10px; line-height:30px; background-color:#EFF7FF;border-bottom:1px solid #DCDCDC; cursor:move;}
#warp .c .hd h2{ font-weight:bold; font-size:13px; color:#666;}
#warp .c .bd{ padding:10px;}
</style>
</head>

<body >

    <div id="warp" style="display:none">
        <div p="p" id="left">
            <div id="a1" class="c">
                <div class="hd">
                    <h2>标题1</h2>
                </div>
                <div class="bd">
                    <div style=" height:120px;">模块1</div>                
                </div>
            </div>
            <div id="a2" class="c">
                <div class="hd">
                    <h2>标题2</h2>
                </div>
                <div class="bd">
                    <div style=" height:100px;">模块2</div>                
                </div>
            </div>
            <div id="a3" class="c">
                <div class="hd">
                    <h2>标题3</h2>
                </div>
                <div class="bd">
                    <div style=" height:60px;">模块3</div>                
                </div>
            </div>                        
        </div>
        <div p="p" id="center">
            <div id="a4" class="c">
                <div class="hd">
                    <h2>标题4</h2>
                </div>
                <div class="bd">
                    <div style=" height:160px;">模块4</div>                
                </div>
            </div>
            <div id="a5" class="c">
                <div class="hd">
                    <h2>标题5</h2>
                </div>
                <div class="bd">
                    <div style=" height:80px;">模块5</div>                
                </div>
            </div>
            <div id="a6" class="c">
                <div class="hd">
                    <h2>标题6</h2>
                </div>
                <div class="bd">
                    <div style=" height:120px;">模块6</div>                
                </div>
            </div>                                
        </div>
        <div p="p" id="right">
            <div id="a7" class="c">
                <div class="hd">
                    <h2>标题7</h2>
                </div>
                <div class="bd">
                    <div style=" height:30px;">模块7</div>                
                </div>
            </div>
            <div id="a8" class="c">
                <div class="hd">
                    <h2>标题8</h2>
                </div>
                <div class="bd">
                    <div style=" height:130px;">模块8</div>                
                </div>
            </div>            
            <div id="a9" class="c">
                <div class="hd">
                    <h2>标题9</h2>
                </div>
                <div class="bd">
                    <div style=" height:80px;">模块9</div>                
                </div>
            </div>            
        </div>
    </div>
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
    <script type="text/javascript">
        function getCookie(name){
            if (document.cookie.length>0){
                start=document.cookie.indexOf(name + "=")
                if (start!=-1){
                    start=start + name.length+1
                    c_end=document.cookie.indexOf(";",start)
                    if (c_end==-1) c_end=document.cookie.length
                    return unescape(document.cookie.substring(start,c_end))
                }
            }
            return ""
        }    
        (function(doc,undefined){
            var win = this;
            win.Sys = function (ua){
                var b = {
                    ie: /msie/.test(ua) && !/opera/.test(ua),
                    opera: /opera/.test(ua),
                    safari: /webkit/.test(ua) && !/chrome/.test(ua),
                    firefox: /firefox/.test(ua),
                    chrome: /chrome/.test(ua)
                },vMark = "";
                for (var i in b) {
                    if (b[i]) { vMark = "safari" == i ? "version" : i; break; }
                }
                b.version = vMark && RegExp("(?:" + vMark + ")[\\/: ]([\\d.]+)").test(ua) ? RegExp.$1 : "0";
                b.ie6 = b.ie && parseInt(b.version, 10) == 6;
                b.ie7 = b.ie && parseInt(b.version, 10) == 7;
                b.ie8 = b.ie && parseInt(b.version, 10) == 8;  
                return b;
            }(win.navigator.userAgent.toLowerCase());
            
            win.Sys.ie6&&doc.execCommand("BackgroundImageCache", false, true);
            
            win.$$ = function(id){
                return typeof id === 'string'
                    ? doc.getElementById(id)
                    : id;
            };
            win.$q = function(name,parent){
                return parent.getElementsByTagName(name);
            }
            win.$c = function(name,parent){
                var elem = typeof name ==='object'? name : doc.createElement(name);
                parent&&parent.appendChild(elem);
                return elem;        
            };
            
            win.addListener = function(element,e,fn){
                !element.events&&(element.events = {});
                element.events[e]&&(element.events[e][addListener.guid++]=fn)||(element.events[e] = {'0':fn});
                element.addEventListener?element.addEventListener(e,fn,false):element.attachEvent("on" + e,fn);
            };
            win.addListener.guid = 1;
            win.removeListener = function(element,e,fn){
                var handlers = element.events[e],type;
                if(fn){
                    for(type in handlers)
                        if(handlers[type]===fn){
                            element.removeEventListener?element.removeEventListener(e,fn,false):element.detachEvent("on" + e,fn);
                            delete handlers[type];
                        }
                }else{
                    for(type in handlers){
                        element.removeEventListener?element.removeEventListener(e,handlers[type],false):element.detachEvent("on" + e,handlers[type]);
                        delete handlers[type];
                    }
                }       
            };
            win.fireEvent = function(element,eventName){
                if(element[eventName]){
                    element[eventName]();
                }else if(element.fireEvent){
                    element.fireEvent('on'+eventName);
                }else if(doc.createEvent){
                    var evt = doc.createEvent("MouseEvents");
                    evt.initEvent(eventName, true, true);
                    element.dispatchEvent(evt);
                }    
            };
            win.setStyle = function(elems, style, value){
                if( !elems.length ) elems = [elems];
                if( typeof style == "string"){       
                    style = value === undefined?{cssText:style}:(function(o){
                        return (o[style] = value,o);           
                    })({});
                };
                each(elems,function(i,elem,style){
                    var value,name,ie=Sys.ie ;
                    for(name in style){
                        value = style[name];
                        if (name === "opacity" && ie) {
                            elem.style.filter = (elem.currentStyle.filter || "").replace( /alpha\([^)]*\)/, "" ) + "alpha(opacity=" + value * 100 + ")";
                        }else if(name === "float"){
                            elem.style[ ie ? "styleFloat" : "cssFloat" ] = value;
                        }else{
                            name = name.replace(/-([a-z])/ig, function(all, letter){
                                return letter.toUpperCase();
                            });
                            elem.style[name] = value;
                        }
                    }
                },style);
            };
            win.setAttr = function(dom,attr){
                if(typeof attr !== 'object')
                    return;
                for(var name in attr)
                    dom.setAttribute(name,attr[name]);
            }
            
            var slice = Array.prototype.slice;
            win.bind = function(object, fun) {
                var args = slice.call(arguments).slice(2);
                return function() {
                        return fun.apply(object, args);
                };
            };
            
            win.bindAsEventListener = function(object, fun,args) {
                var args = slice.call(arguments).slice(2);
                return function(event) {
                    return fun.apply(object, [event || win.event].concat(args));
                }
            };
        
            win.extend = function(){
                var target = arguments[0] || {}, i = 1, length = arguments.length, deep = true, options;
                if ( typeof target === "boolean" ) {
                    deep = target;
                    target = arguments[1] || {};
                    i = 2;
                }
                if ( typeof target !== "object" && Object.prototype.toString.call(target)!="[object Function]")
                    target = {};
                for(;i<length;i++){
                    if ( (options = arguments[ i ]) != null )
                        for(var name in options){
                            var src = target[ name ], copy = options[ name ];
                            if ( target === copy )
                                continue;
                            if ( deep && copy && typeof copy === "object" && !copy.nodeType ){
                                target[ name ] = arguments.callee( deep, src || ( copy.length != null ? [ ] : { } ), copy );
                            }   
                            else if(copy !== undefined)
                                target[ name ] = copy;                       
                        }
                }
                return target;           
            };
    
            win.each =  function ( object, callback, args ) {  
                var name, i = 0, length = object.length;  
                if ( args ) {
                    args = Array.prototype.slice.call(arguments).slice(2);
                    if ( length === undefined ) {  
                        for ( name in object )  
                            if ( callback.apply( object[ name ],[name,object[ name ]].concat(args) ) === false )  
                                break;  
                    } else
                        for ( ; i < length; i++)  
                            if ( callback.apply( object[ i ],[i,object[ i ]].concat(args)) === false )   //
                                break;  
                } else {     
                    if ( length === undefined ) {  
                        for ( name in object )  
                            if ( callback.call( object[ name ], name, object[ name ] ) === false )  
                                break;  
                    } else
                        for ( var value = object[0];  
                            i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}  
                }  
                return object;  
            };  
            win.currentStyle = function(element){
                return element.currentStyle || doc.defaultView.getComputedStyle(element, null);
            };
            win.pos = function(elem){
                var left = 0, top = 0, right = 0, bottom = 0,doc = elem ? elem.ownerDocument : doc;
                if ( !elem.getBoundingClientRect || win.Sys.ie8 ) {
                    var n = elem;
                    while (n) { left += n.offsetLeft, top += n.offsetTop; n = n.offsetParent; };
                    right = left + elem.offsetWidth; bottom = top + elem.offsetHeight;
                } else {
                    var rect = elem.getBoundingClientRect();
                    left = right = doc.documentElement.scrollLeft || doc.body.scrollLeft;
                    top = bottom = doc.documentElement.scrollLeft || doc.body.scrollLeft;
                    left += rect.left; right += rect.right;
                    top += rect.top; bottom += rect.bottom;
                }
                return { "left": left, "top": top, "right": right, "bottom": bottom ,"width":elem.offsetWidth,"height":elem.offsetHeight};
            };
            win.hasClass = function(element, className){
                return element.className.match(new RegExp('(\\s|^)'+className+'(\\s|$)'));
            };
            win.addClass = function(element, className){
                if(!win.hasClass(element, className))
                    element.className.replace(/\s/g,'')===''
                        ? element.className = className
                        : element.className+= " "+className;
            };
            win.removeClass = function(element, className){
                win.hasClass(element, className)&&(element.className = element.className.replace(new RegExp('(\\s*|^)'+className+'(\\s*|$)'),' '));
            }
        })(document);
        
        
        var dragLayout = {
            init : function(options){
                extend(this,options);
                var items = this.items = [],
                    self = this;
                this.data = {};
                this.hashItems ={}
                each(this.groups,function(i,group){
                    var arr = self.data[i] = [];
                    group.setAttribute("pid",i);
                    each($q("div",group),function(i,div){
                        if(div.className === "c"){
                            self.hashItems[div.id] = div;
                            items.push(div);
                            arr.push(div.id);
                            addListener(div,"mousedown",bindAsEventListener(self,self.start,div));
                        }
                    });
                    //group.innerHTML ="" ie6这样清除dom  在加上dom居然 dom居然没有样式
                });
                
                each(this.hashItems,function(i,div){
                    div.parentNode.removeChild(div);
                });
                
                this.proxyDiv = $c("div",document.body);
                setStyle(this.proxyDiv,{
                    display : "none",
                    backgroundColor:"#F0FBEB",
                    position : "absolute",
                    opacity : 0.8
                });
                this.temporaryDiv = $c("div");
                this.temporaryDiv.className = "c b";
                
                var xx = getCookie("xx")
                //xx=0-a1_a2_a3,1-a8_a5,2-a7_a9_a4_a6
                //生成data结构
                if(xx){
                    this.data = {}
                    each(xx.split(","),function(i,d){
                        d = d.split("-");
                        var lists = d[1].split("_");
                        if(lists[0]===""){
                            lists=[];
                        }
                        self.data[d[0]] = lists;
                    });
                }else{
                    this.setCookie();
                }
                
                //重新生成页面
                each(this.data,function(i,o){
                    var group = self.groups[i],
                        data  = self.data[i];
                    data.length!==0
                        &&each(data,function(i,id){
                            group.appendChild(self.hashItems[id]);
                        });    
                })
                
                this.container.style.display="";
            },
            start : function(e,div){
                var elem = e.target || e.srcElement;
                if( elem.nodeName==="H2" || elem.className==="c" ){
                    this.div = div;
                    setStyle(div,{
                        opacity: 0.5
                    });
                    var offset = pos(this.div);
                    this.x = e.clientX - offset.left;
                    this.y = e.clientY - offset.top;
                    Sys.ie
                        ? this.proxyDiv.setCapture()
                        : e.preventDefault();    
                    addListener(document,"mousemove",bindAsEventListener(this,this.move,div));
                    addListener(document,"mouseup",bind(this,this.up));                     
                }                
            },
            move : function(e){
                window.getSelection 
                    ? window.getSelection().removeAllRanges() 
                    : document.selection.empty();
    
                var proxyDiv = this.proxyDiv,
                    self = this,
                    x = e.clientX,
                    y = e.clientY;
                if(proxyDiv.style.display === "none"){
                    var offset = pos(this.div);
                    setStyle(proxyDiv,{
                        width  : offset.width+"px",
                        height : offset.height+"px",
                        display: "block"
                    });
                }
                setStyle(proxyDiv,{
                    left : x - this.x + "px",
                    top  : y - this.y +(Math.max(document.documentElement.scrollTop,document.body.scrollTop))  + "px"
                });
                
                var l = this.items.length,j=0;
                each(this.items,function(i,div){
                    j++;
                    if(self.div === div)
                        return;    
                    var offset = pos(div)
                    if(div === self.targetDiv){
                        offset.top = pos(self.temporaryDiv).top;
                    }
                    if(x>offset.left&&x<offset.right&&y>offset.top&&y<offset.bottom){                    
                        self.targetDiv = div;
                        setStyle(self.temporaryDiv,{
                            height : self.div.offsetHeight + "px"
                        });
                        div.parentNode.insertBefore(self.temporaryDiv,div);
                        j=0;
                        return false;
                    }
                });
                                
                if(l===j&&this.temporaryDiv.parentNode&&this.temporaryDiv.parentNode.nodeName=== "DIV"){
                    this.temporaryDiv.parentNode.removeChild(this.temporaryDiv);
                    this.targetDiv = null;
                }                
                
                if(!(this.temporaryDiv.parentNode&&this.temporaryDiv.parentNode.nodeName=== "DIV")){                    
                    each(this.groups,function(i,div){
                            var offset = pos(div);
                            if($q("div",div).length===0){
                                var top    = offset.top;
                                var bottom = offset.top+240;
                            }else{
                                var top    = offset.bottom;
                                var bottom = offset.bottom+150;
                            }
                            if(x>offset.left&&x<offset.right&&y>top&&y<bottom){
                                self.targetDiv = div;
                                setStyle(self.temporaryDiv,{
                                    height : self.div.offsetHeight + "px"
                                });
                                div.appendChild(self.temporaryDiv)
                            }                       
                    });
                }
            },
            up : function(e){
                removeListener(document,'mousemove');
                removeListener(document,'mouseup');
                Sys.ie&&this.proxyDiv.releaseCapture();
                this.proxyDiv.style.display = "none"
                setStyle(this.div,"opacity",1);
                if(this.targetDiv){
                    var group = this.div.parentNode,
                        index = group.getAttribute("pid"),
                        self  = this,
                        j,
                        toGroup;
                    this.targetDiv.getAttribute("pid")
                        ? toGroup = this.targetDiv
                        : toGroup = this.targetDiv.parentNode;
                    var toIndex = toGroup.getAttribute("pid")
                    each(this.data[index],function(i,id){
                        if(id===self.div.id){
                            j=i;
                            return false;
                        }
                    });
                    var k;
                    each(this.data[toIndex],function(i,id){
                        if(id===self.targetDiv.id){
                            k=i;
                            return false;
                        }
                    });                    
                    var list = this.data[index].splice(j,1)[0];
                    this.targetDiv.getAttribute("pid")
                        ? this.data[toIndex].push(list)
                        : this.data[toIndex].splice(k,0,list);                    
                    this.setCookie();
                }            
                if(this.temporaryDiv.parentNode&&this.temporaryDiv.parentNode.nodeName=== "DIV"){
                    this.div.parentNode.removeChild(this.div);
                    this.temporaryDiv.parentNode.replaceChild(this.div,this.temporaryDiv)
                }
                
                this.div = null;
                this.targetDiv = null;                                
            },
            setCookie : function(){
                var str = "";
                for(var list in this.data){
                    str+=list+"-"+this.data[list].join("_")+",";
                }                    
                document.cookie = "xx="+str.replace(/,$/,"");
            }
        }
        window.onload = function(){
            dragLayout.init({
                container   : $$("warp"),
                groups : {"0":$$("left"),"1":$$("center"),"2":$$("right")}
            });
        }
    </script>
</body>
</html>
原文地址:https://www.cnblogs.com/sensualgirl/p/2720023.html