<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<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:hidden;}
        body,div,h2,p{margin:0;padding:0;}
        body{color:#fff;background:#000;font:12px/2 Arial;}
        p{padding:0 10px;margin-top:10px;}
        span{color:#ff0;padding-left:5px;}
        #box{position:absolute;width:300px;height:150px;background:#333;border:2px solid #ccc;top:50%;left:50%;margin:-75px 0 0 -150px;}
        #box h2{height:25px;cursor:move;background:#222;border-bottom:2px solid #ccc;text-align:right;padding:0 10px;}
        #box h2 a{color:#fff;font:12px/25px Arial;text-decoration:none;outline:none;}
    </style>
    <script>
        window.onload=function(){
            var oBox=document.getElementById("box");
            var oH=oBox.getElementsByTagName("h2")[0];
            var oA=oBox.getElementsByTagName("a")[0];
            var aSpan=oBox.getElementsByTagName("span");
            var aPos=[{x:oBox.offsetLeft,y:oBox.offsetTop}];
            var bDrag=false;
            var disX=disY=0;

            oH.onmousedown=function(ev){
                var oEv=ev||window.event;
                bDrag=true;
                aPos.push({x:oBox.offsetLeft,y:oBox.offsetTop});
                disX=oEv.clientX-oBox.offsetLeft;
                disY=oEv.clientY-oBox.offsetTop;
                this.setCapture&&this.setCapture();
                return false;
            };
            document.onmousemove=function(ev){
                if (!bDrag) return;
                var oEv=ev||window.event;
                var iL=oEv.clientX-disX;
                var iT=oEv.clientY-disY;
                var iMaxL=document.documentElement.clientWidth-oBox.offsetWidth;
                var iMaxT=document.documentElement.clientHeight-oBox.offsetHeight;
                iL=iL<0?0:iL;
                iT=iT<0?0:iT;
                iL=iL>iMaxL?iMaxL:iL;
                iT=iT>iMaxT?iMaxT:iT;
                oBox.style.marginTop=oBox.style.marginLeft=0;
                oBox.style.left=iL+"px";
                oBox.style.top=iT+"px";
                aPos.push({x:iL,y:iT});
                status();
                return false;
            };
            document.onmouseup=window.onblur=oH.onlosecapture=function(){//window.onblur表示当前窗口失去焦点即激活了其他线程的窗口
                bDrag=false;
                this.releaseCapture&&this.releaseCapture();
                status()
            };
            //回放
            oA.onclick=function(){
                var oPos=play=null;
                if(aPos.length==1) return;
                play=setInterval(function(){
                    oPos=aPos.pop();
                    oPos?(oBox.style.left=oPos.x+"px",oBox.style.top=oPos.y+"px", status()):clearInterval(play);
                },50);
                this.focus=false;
                return false;

            };
            oA.onmousedown=function(ev){
                (ev||window.event).cancelBubble=true;
            };
            function status(){
                aSpan[0].innerHTML=bDrag;
                aSpan[1].innerHTML=oBox.offsetLeft;
                aSpan[2].innerHTML=oBox.offsetTop;
            }
            status();
        };
//心得:用bDrag来独立move和up函数(不同嵌套在down函数里)
//     在临界值的处理里,先把最值算出来再和最值比较再赋值
//     三目运算符里可以写多条语句,用","隔开即可
//     赋值的时候,要考虑是否收到布局的影响。如oBox.style.left和top赋值前要先把margin值清零
//     ie捕获事件:setCapture()  ie释放事件捕获:releaseCapture()
    </script>
</head>
<body>
<div id="box">
    <h2><a href="javascript:;">点击回放拖动轨迹</a></h2>
    <p><strong>Drag:</strong><span></span></p>
    <p><strong>offsetTop:</strong><span></span></p>
    <p><strong>offsetLeft:</strong><span></span></p>
</div>
</body>
</html>