Div的drag-drop实践结果【原创】

  看了那些个框架里关于拖曳方面的例子,一看代码,昏倒,乱得很,有的又只支持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 == null return ;
        
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 + " ;width: " + 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 == null return ;
        
        
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 ="width:200px;height:50px;border:1px solid black" > 1 </ div >
< div  id ="t2"  style ="width:200px;height:100px;border:1px solid black" > 2 </ div >
< div  id ="t3"  style ="width:500px;height:300px;border:1px solid black;padding:5 5 5 5" >     
    
< div  id ="t5"  style ="width:200px;height:50px;border:1px solid black" > 5 </ div >
    
< div  id ="t6"  style ="width:200px;height:50px;border:1px solid black" > 6 </ div >
</ div >
< div  id ="t4"  style ="width: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

转载于:https://www.cnblogs.com/zxub/archive/2006/06/28/438152.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值