• Div的dragdrop实践结果【原创】


      看了那些个框架里关于拖曳方面的例子,一看代码,昏倒,乱得很,有的又只支持IE,ff下根本没用,郁闷之下,决定自己写一个。
      为了在ff下能用,花了点时间,代码如下:
      event.js:
    /**
     * 事件处理类
     * @author zxub 2006-06-21
     
    */
    var Event=new function()
    {
        
    this.element=function(_event)
        {
            
    return _event.target || _event.srcElement;        
        }
        
        
    this.pointerX=function(_event)
        {
            
    return _event.pageX || (_event.clientX+(document.documentElement.scrollLeft || document.body.scrollLeft));
        }
        
        
    this.pointerY=function(_event)
        {
            
    return _event.pageY || (_event.clientY+(document.documentElement.scrollTop || document.body.scrollTop));
        }
        
        
    this.isLeftClick=function(_event)
        {
            
    return (((_event.which) && (_event.which==1)) || ((_event.button) && (_event.button==1)));
        }
        
        
    this.observers=null;
        
        
    this.alreadyObserve=function(element,name,observer,useCapture)
        {
            
    for (var i=0; i<Event.observers.length; i++)
            {
                
    if (Event.observers[i][0]==element && Event.observers[i][1]==name && Event.observers[i][2]==observer)
                {
                    
    return true;                
                }
            }
            
    return false;
        }
        
        
    this.unReg=function(element,name,observer,useCapture)
        {
            
    for (var i=0; i<Event.observers.length; i++)
            {
                
    if (Event.observers[i][0]==element && Event.observers[i][1]==name && Event.observers[i][2]==observer)
                {
                    Event.observers[i][
    0]=null;
                    Event.observers.splice(i,
    1);
                    
    break;
                }
            }
        }
        
        
    /**
         * 防止事件传播,进行中止
         
    */
        
    this.stopEvent=function(_event)
        {
            
    if (_event.preventDefault)
            {
                _event.preventDefault();
                _event.stopPropagation();
            }
            
    else
            {
                _event.returnValue 
    = false;
                _event.cancelBubble 
    = true;
            }
        }
        
        
        
    /**
         * 增加事件处理
         * 注意,对于同一个Element,IE和Firefox的处理顺序是相反的,IE用栈的形式,后注册的先执行,而Firefox用队列的形式,先注册先执行
         * 至于useCapture,是当element存在包含关系,事件的处理顺序
         * 处理顺序有2种,capturing和bubbling
         * capturing是从外向内,而bubbling是从内向外
         * IE只支持bubbling,所有useCapture是没有意义的
         * Firefox中,2种都支持,useCapture为false的时候为bubbling,true为capturing,推荐用bubbling
         * 默认useCapture为false
         
    */
        
    this.observe=function(element, name, observer, useCapture)
        {
            
    if (typeof(element)=="string")
            {
                element
    =document.getElementById(element);
            }
            useCapture 
    = useCapture || false;
            
    if (this.observers==null)
            {
                
    this.observers=new Array();
            }        
            
    //检查是否注册了同样的事件处理
            if (Event.alreadyObserve(element, name, observer, useCapture)) return;        
            
    if (element.addEventListener) //firefox
            {          
                element.addEventListener(name, observer, useCapture);
            }
            
    else if (element.attachEvent) //IE
            {
                element.attachEvent(
    "on"+name, observer);
            }
            
    this.observers.push([element, name, observer, useCapture]);        
        }
        
        
    this.stopObserving=function(element, name, observer, useCapture)
        {
            
    if (typeof(element)=="string")
            {
                element
    =document.getElementById(element);
            }
            useCapture 
    = useCapture || false;
            
            
    if (element.removeEventListener)
            {
                element.removeEventListener(name, observer, useCapture);
            }
            
    else if (element.detachEvent)
            {
                element.detachEvent(
    "on"+name, observer);
            }
            Event.unReg(element, name, observer, useCapture);
        }
        
        
    this.clearObservers=function()
        {
            
    if (Event.observers==nullreturn;
            
    for (var i=0;i<Event.observers.length; i++)
            {
                Event.stopObserving.apply(
    this, Event.observers[i]);
                Event.observers[i][
    0= null;//释放对element的引用
            }
            Event.observers 
    = null;
        }
    }

    if (window.navigator.userAgent.indexOf("MSIE")>=1)
    {
        Event.observe(window,'onunload',Event.clearObservers,
    false);
    }

      position.js:
    var Position=new function()
    {
        
    this.getPosition=function(element)
        {
            
    if (element==undefined || element==null || element==""return new Position.instance(0,0,0,0);
            
    var offsetTop=element.offsetTop;
            
    var offsetLeft=element.offsetLeft;
            
    var offsetWidth=element.offsetWidth;
            
    var offsetHeight=element.offsetHeight;
            
    while (element=element.offsetParent)
            {
                
    if (element.style.position=='absolute' || element.style.position=='relative' || (element.style.overflow!='visible' && element.style.overflow!=''))
                {
                    
    break;
                }
                offsetTop
    +=element.offsetTop;
                offsetLeft
    +=element.offsetLeft;
            }
            
    return new Position.instance(offsetTop,offsetLeft,offsetWidth,offsetHeight);
        }
        
        
    this.inside=function(_source,_target)
        {
            
    var _tPosition=Position.getPosition(_target);
            
    var _sPosition=Position.getPosition(_source);
            
    return (_sPosition.minX>=_tPosition.minX && _sPosition.maxX<=_tPosition.maxX && _sPosition.minY>=_tPosition.minY && _sPosition.maxY<=_tPosition.maxY);
        }
        
        
    this.outside=function(_source,_target)
        {
            
    var _tPosition=Position.getPosition(_target);
            
    var _sPosition=Position.getPosition(_source);
            
    return (_sPosition.maxX<_tPosition.minX || _sPosition.minX>_tPosition.maxX || _sPosition.minY>_tPosition.maxY || _sPosition.maxY<_tPosition.minY);
        }
    }

    Position.instance
    =function(_top,_left,_width,_height)
    {
        
    this.top=_top;
        
    this.left=_left;
        
    this.width=_width;
        
    this.height=_height;
        
    this.minX=this.left;
        
    this.maxX=this.left+this.width;
        
    this.minY=this.top;
        
    this.maxY=this.top+this.height;
        
    this.toString=function()
        {
            
    return "top:"+this.top+";left:"+this.left+";"+this.width+";height:"+this.height+";xRange:"+this.minX+"-"+this.maxX+";yRange:"+this.minY+"-"+this.maxY;
        }
    }

    Position.direction
    =new function()
    {
        
    this.up=false;
        
    this.down=false;
        
    this.left=false;
        
    this.rgiht=false;
        
    this.lastX=0;
        
    this.lastY=0;
        
    this.setInitValue=function(_x,_y)
        {
            
    this.lastX=_x;
            
    this.lastY=_y;
        }
        
        
    this.setDirection=function(_cX,_cY)
        {
            
    if (_cX==undefined) _cX=Event.pointerX(event);
            
    if (_cY==undefined) _cY=Event.pointerY(event);
            
    this.up=(_cY<this.lastY);
            
    this.down=!this.up;
            
    this.left=(_cX<this.lastX);
            
    this.right=!this.left;
            
    this.setInitValue(_cX,_cY);
        }
        
        
    this.toString=function()
        {
            
    return "up:"+this.up+";down:"+this.down+";left:"+this.left+";right:"+this.right;
        }
    }

      drag.js:
    var Drag=new function()
    {    
        
    this.source=new Array();
        
    this.target=new Array();
        
        
    this.topDistance=0;
        
    this.leftDistance=0;
        
        
    this.currentObj=null;
        
        
    this.currentContainer=null;
        
        
    this.isDragging=false;
        
        
    this.addSource=function()
        {
            
    for (var i = 0; i < arguments.length; i++)
            {
                
    var _element = arguments[i];
                
    if (typeof(_element)=="string")
                {
                    _element
    =document.getElementById(_element);
                }            
                Drag.source.push(
    new Drag.sourceObj(_element));            
            }
        }
        
        
    this.hasSource=function(_element)
        {
            
    for (var i=0; i<Drag.source.length; i++)
            {
                
    if (Drag.source[i].element==_element)
                {
                    
    return true;
                }
            }
            
    return false;
        }
        
        
    this.addTarget=function(_element)
        {
            
    for (var i = 0; i < arguments.length; i++)
            {
                
    var _element = arguments[i];
                
    if (typeof(_element)=="string")
                {
                    _element
    =document.getElementById(_element);
                }
                Drag.target.push(
    new Drag.targetObj(_element));            
            }
        }
        
        
    this.hasTarget=function(_element)
        {
            
    for (var i=0; i<Drag.target.length; i++)
            {
                
    if (Drag.target[i].element==_element)
                {
                    
    return true;
                }
            }
            
    return false;
        }
        
        
    this.start=function(event)
        {
            
    if (!Event.isLeftClick(event)) return;
            Drag.currentObj
    =Event.element(event);
            
    if (Drag.hasSource(Drag.currentObj))
            {
                Drag.currentObj.style.cursor
    ="move";
                
    var p=Position.getPosition(Drag.currentObj);
                
    var x=Event.pointerX(event);
                
    var y=Event.pointerY(event);
                Position.direction.setInitValue(x,y);            
                Drag.topDistance
    =y-p.top;
                Drag.leftDistance
    =x-p.left;
                
                DashedDiv.div.style.width
    =p.width;
                DashedDiv.div.style.height
    =p.height;
                DashedDiv.div.style.display
    ="";
                
                Drag.currentObj.parentNode.insertBefore(DashedDiv.div,Drag.currentObj);
                
                Drag.currentObj.style.top
    =p.top+5;
                Drag.currentObj.style.left
    =p.left+5;
                Drag.currentObj.style.position
    ="absolute";
                
                document.body.appendChild(Drag.currentObj);
                
                Drag.isDragging
    =true;
                
                Event.observe(document,
    "mousemove",Drag.drag);
                Event.observe(document,
    "mouseup",Drag.end);
            }
            
    else
            {
                Drag.currentObj
    =null;
            }
        }
        
        
    this.drag=function(event)
        {
            
    if (!Event.isLeftClick(event) || !Drag.isDragging || Drag.currentObj==nullreturn;
            
            
    var x=Event.pointerX(event);
            
    var y=Event.pointerY(event);
            Position.direction.setDirection(x,y);        
            
            Drag.currentObj.style.top
    =y-Drag.topDistance;
            Drag.currentObj.style.left
    =x-Drag.leftDistance;
            
    if (Drag.currentContainer==null)
            {
                
    for (var i=0;i<Drag.target.length;i++)
                {
                    
    if (Position.inside(Drag.currentObj,Drag.target[i].element))
                    {
                        Drag.currentContainer
    =Drag.target[i].element;
                        Drag.setDashedDivPosition();
                        
    break;                    
                    }
                }
            }
            
    else
            {
                
    if (Position.outside(Drag.currentObj,Drag.currentContainer))
                {
                    Drag.currentContainer
    =null;
                }
                
    else
                {
                    Drag.setDashedDivPosition();
                }
            }
        }
        
        
    this.end=function(event)
        {
            
    if (!Event.isLeftClick(event)) return;
            
    if (Drag.currentObj!=null)
            {       
                DashedDiv.div.parentNode.insertBefore(Drag.currentObj,DashedDiv.div);
                DashedDiv.div.style.display
    ="none";
                
                Drag.currentObj.style.position
    ="relative";
                Drag.currentObj.style.cursor
    ="default";
                
                
                Drag.currentObj.style.top
    =0;
                Drag.currentObj.style.left
    =0;
                
                Drag.currentObj
    =null;
                Drag.currentContainer
    =null;
                Drag.topDistance
    =0;
                Drag.leftDistance
    =0;
                
    this.isDragging=false;
                
                Position.direction.setInitValue(
    0,0);
            }
            
    //发送请求保存页面
        }
        
        
    this.setDashedDivPosition=function()
        {        
            
    if (Position.direction.down)
            {
                
    if (DashedDiv.div.parentNode!=Drag.currentContainer)
                {
                    Drag.currentContainer.insertBefore(DashedDiv.div,Drag.currentContainer.firstChild)
                    
    return;
                }
                
    var cp=Position.getPosition(Drag.currentObj);
                
    var nextNode=Drag.handler.getNextNode(DashedDiv.div);
                
    var p=Position.getPosition(nextNode);
                
    var node=null;
                
    while (nextNode!=null && cp.minY>p.minY+2)
                {
                    node
    =nextNode;
                    nextNode
    =Drag.handler.getNextNode(nextNode);
                    p
    =Position.getPosition(nextNode);
                }
                
    if (node!=null)
                {
                    
    if (node.nextSibling)
                    {
                        node.parentNode.insertBefore(DashedDiv.div,node.nextSibling);
                    }
                    
    else
                    {
                        node.parentNode.appendChild(DashedDiv.div);
                    }
                }
            }
            
    else if (Position.direction.up)
            {
                
    if (DashedDiv.div.parentNode!=Drag.currentContainer)
                {
                    Drag.currentContainer.appendChild(DashedDiv.div);
                    
    return;
                }
                
    var cp=Position.getPosition(Drag.currentObj);
                
    var previousNode=Drag.handler.getPreviousNode(DashedDiv.div);
                
    var p=Position.getPosition(previousNode);
                
    var node=null;
                
    while (previousNode!=null && cp.minY<p.minY-2)
                {
                    node
    =previousNode;
                    previousNode
    =Drag.handler.getPreviousNode(previousNode);
                    p
    =Position.getPosition(previousNode);
                }
                
    if (node!=null)
                {
                    node.parentNode.insertBefore(DashedDiv.div,node);
                }
            }
        }
    }

    Drag.sourceObj
    =function(_element)
    {
        
    this.element=_element;
        Event.observe(
    this.element,"mousedown",Drag.start);    
    }

    Drag.targetObj
    =function(_element)
    {
        
    this.element=_element;    
    }



    var DashedDiv=new function()
    {
        
    this.div=null;
        
    this.init=function()
        {
            
    if (this.div==null)
            {
                
    this.div=document.createElement("div");
                
    this.div.id="dashed";
                
    this.div.style.cssText="border:1px dashed red;position:relative;cursor:move;filter:alpha(opacity=60);-moz-opacity:0.6;display:none";
                document.body.appendChild(
    this.div);
            }
        }
        
    this.init();
    }

    //为不支持swapNode的浏览添加方法
    if (window.Node)
    {
        Node.prototype.swapNode
    =function(node)//由于在ff下测试出了错,所以没用
        {     
            
    var nextSibling=this.nextSibling;
            
    var parentNode=this.parentNode;
            node.parentNode.replaceChild(
    this,node);
            parentNode.insertBefore(node,nextSibling);   
        }
    }

    Drag.handler
    =new function()
    {
        
    this.swap=function(_node1,_node2)
        {
            _node1.swapNode(_node2);
        }
        
        
    this.getNextNode=function(_node)
        {
            
    var sibling = _node.nextSibling;
            
    while (sibling != null)
            {
                
    if (sibling.nodeName==_node.nodeName) return sibling;
                sibling 
    = sibling.nextSibling;
            }
            
    return null;
        }
        
        
    this.getPreviousNode=function(_node)
        {
            
    var sibling = _node.previousSibling;
            
    while (sibling != null)
            {
                
    if (sibling.nodeName==_node.nodeName) return sibling;
                sibling 
    = sibling.previousSibling;
            }
            
    return null;
        }
    }

      测试页面:
    <html>
    <head>
    <title>测试</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    
    <style type="text/css">
    <!--
    body,tr,td 
    { font-size: 12px;}
    div 
    {margin:5 5 5 5}
    -->
    </style>
    </head>
    <body>
    <script type="text/javascript" src="event.js"></script>
    <script type="text/javascript" src="position.js"></script>
    <script type="text/javascript" src="drag.js"></script>
    <div id="t1" style="200px;height:50px;border:1px solid black">1</div>
    <div id="t2" style="200px;height:100px;border:1px solid black">2</div>
    <div id="t3" style="500px;height:300px;border:1px solid black;padding:5 5 5 5">    
        
    <div id="t5" style="200px;height:50px;border:1px solid black">5</div>
        
    <div id="t6" style="200px;height:50px;border:1px solid black">6</div>
    </div>
    <div id="t4" style="500px;height:200px;border:1px solid black;padding:5 5 5 5"></div>
    <div id="info"></div>
    <script type="text/javascript">
    Drag.addSource(
    "t1","t2","t5","t6");
    Drag.addTarget(
    "t3","t4");
    </script>
    </body>
    </html>

      关于位置保存,以后再加上来。
      源码下载: drag.rar
  • 相关阅读:
    软件推荐Q10 CircleDock PHP
    Google Chrome浏览器 扩展程序推荐 PHP
    jsColor取色器 PHP
    在线指法练习【怀旧版】 PHP
    model工厂类(转)
    表变量与临时表的优缺点
    项目的阶段性目标管理
    如何配置不启用安全的WCF服务
    团队高效执行力从何而来
    socket connect函数本质含义
  • 原文地址:https://www.cnblogs.com/zxub/p/438152.html
Copyright © 2020-2023  润新知