+ -
当前位置:首页 → 问答吧 → 一个拖放的小小问题

一个拖放的小小问题

时间:2010-06-03

来源:互联网

写了个拖放的实例,在IE下工作是正常的,但在FF下,第二次拖放的时候出现问题,具体请看代码:
<!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> <style type="text/css"> *{margin:0;padding:0;} #wrap{width:950px;margin:0 auto;height:200px;border:1px solid #FF0000;} .dragBox{width:300px;background-color:#FFF;position:absolute;z-index:1000;border:1px solid #D1E9F9;padding:2px;} .dragBox .t{background-color:#A5D5F1;height:25px;cursor:move;} .dragBox .c{padding:15px;} div{text-align:center;} </style> </head> <body> <div id="wrap"> <div class="dragBox"> <div class="t"></div> <div class="c"> 这个是一测试的拖放容器 </div> </div> </div> <div id="test"></div> <div id="test2"></div> <input id="btn" type="button" value="Button" /> <script type="text/javascript"> String.prototype.hasClass=function(c){ var cs=this.split(" "); for(var i=0;i<cs.length;i++){ if(c==cs[i]){ return true; } } return false; } function getE(t,c,d){ if(t.indexOf("#")==0){return document.getElementById(t.replace('#',''));} var od=d||document; var os=od.getElementsByTagName(t); var or=[]; var j=0; for(var i=0;i<os.length;i++){ if(os[i].className.hasClass(c)){ or[j++]=os[i]; } } return or; } function getPos(obj){ var p={}; p.x=obj.offsetLeft; p.y=obj.offsetTop; while(obj=obj.offsetParent){ p.x+=obj.offsetLeft; p.y+=obj.offsetTop; } return p; } function getBodyPos(n){ return document.body[n]||document.documentElement[n]; } function mousePos(e){ var e=e||window.event; return {x:e.clientX,y:e.clientY} } //事件绑定 function addEvent(obj,eName,fn){ if(obj.attachEvent){ obj.attachEvent(eName,fn) }else{ obj.addEventListener(eName.substr(2),fn,false); } } //取消事件绑定 function removeEvent(obj,eName,fn){ if(obj.detachEvent){ obj.detachEvent(eName,fn); }else{ obj.removeEventListener(eName.substr(2),fn,false); } } //拖放 function drag(ob,ot){ var op={}; var flag=false; ot.onmousedown=function(e){ var e=e||window.event; var bp=getPos(ob); op.x=e.clientX-bp.x; op.y=e.clientY-bp.y; if(e.button==1||e.button==0){ document.getElementById("test2").innerHTML="bind"; addEvent(document,"onmousemove",mouseMove); addEvent(document,"onmouseup",mouseUp); } } function mouseMove(e){ var e=e||window.event; var mp=mousePos(e); var x=mp.x-op.x; var y=mp.y-op.y; x=x<0?0:x; y=y<0?0:y; ob.style.left=x+'px'; ob.style.top=y+'px'; document.getElementById("test").innerHTML=mp.x+"|"+mp.y; } function mouseUp(){ removeEvent(document,"onmousemove",mouseMove); removeEvent(document,"onmouseup",mouseUp); document.getElementById("test2").innerHTML="up"; } } var dragBox=getE("div","dragBox")[0]; var d1=new drag(dragBox,getE("div","t",dragBox)[0]); </script> </body> </html>
 提示:您可以先修改部分代码再运行

作者: wgguizi   发布时间: 2010-06-03

问题终于找出来了,是因为在FF中,鼠标点击后默认是选中被点击的元素。
当拖放条被点击后,除了执行绑定的点击事件外,还执行了默认的点击事件——选中了点击的内容(设置点击内容焦点)。
第二次拖拽的时候,因为焦点是在拖放条,而拖放条是不能移动的,道理如同在页面选中文字,再拖拽文字是无效的一样。
所以解决的方法就是,在FF中,当点击时,取消默认事件动作。
复制内容到剪贴板
代码:
ot.onmousedown=function(e){
        var e=e||window.event;
        var bp=getPos(ob);
        op.x=e.clientX-bp.x;
        op.y=e.clientY-bp.y;
        if(e.button==1||e.button==0){
            document.getElementById("test2").innerHTML="bind";
            addEvent(document,"onmousemove",mouseMove);    
            addEvent(document,"onmouseup",mouseUp);
             if(e.preventDefault)e.preventDefault();/*增加的部分*/
        }
        
    }
正常的版本:
<!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> <style type="text/css"> *{margin:0;padding:0;} #wrap{width:950px;margin:0 auto;height:200px;border:1px solid #FF0000;} .dragBox{width:300px;background-color:#FFF;position:absolute;z-index:1000;border:1px solid #D1E9F9;padding:2px;} .dragBox .t{background-color:#A5D5F1;height:25px;cursor:move;} .dragBox .c{padding:15px;} div{text-align:center;} </style> </head> <body> <div id="wrap"> <div class="dragBox"> <div class="t"></div> <div class="c"> 这个是一测试的拖放容器 </div> </div> </div> <div id="test"></div> <div id="test2"></div> <input id="btn" type="button" value="Button" /> <script type="text/javascript"> String.prototype.hasClass=function(c){ var cs=this.split(" "); for(var i=0;i<cs.length;i++){ if(c==cs[i]){ return true; } } return false; } function getE(t,c,d){ if(t.indexOf("#")==0){return document.getElementById(t.replace('#',''));} var od=d||document; var os=od.getElementsByTagName(t); var or=[]; var j=0; for(var i=0;i<os.length;i++){ if(os[i].className.hasClass(c)){ or[j++]=os[i]; } } return or; } function getPos(obj){ var p={}; p.x=obj.offsetLeft; p.y=obj.offsetTop; while(obj=obj.offsetParent){ p.x+=obj.offsetLeft; p.y+=obj.offsetTop; } return p; } function getBodyPos(n){ return document.body[n]||document.documentElement[n]; } function mousePos(e){ var e=e||window.event; return {x:e.clientX,y:e.clientY} } //事件绑定 function addEvent(obj,eName,fn){ if(obj.attachEvent){ obj.attachEvent(eName,fn) }else{ obj.addEventListener(eName.substr(2),fn,false); } } //取消事件绑定 function removeEvent(obj,eName,fn){ if(obj.detachEvent){ obj.detachEvent(eName,fn); }else{ obj.removeEventListener(eName.substr(2),fn,false); } } //拖放 function drag(ob,ot){ var op={}; var flag=false; ot.onmousedown=function(e){ var e=e||window.event; var bp=getPos(ob); op.x=e.clientX-bp.x; op.y=e.clientY-bp.y; if(e.button==1||e.button==0){ document.getElementById("test2").innerHTML="bind"; addEvent(document,"onmousemove",mouseMove); addEvent(document,"onmouseup",mouseUp); if(e.preventDefault)e.preventDefault(); } } function mouseMove(e){ var e=e||window.event; var mp=mousePos(e); var x=mp.x-op.x; var y=mp.y-op.y; x=x<0?0:x; y=y<0?0:y; ob.style.left=x+'px'; ob.style.top=y+'px'; document.getElementById("test").innerHTML=mp.x+"|"+mp.y; } function mouseUp(){ removeEvent(document,"onmousemove",mouseMove); removeEvent(document,"onmouseup",mouseUp); document.getElementById("test2").innerHTML="up"; } } var dragBox=getE("div","dragBox")[0]; var d1=new drag(dragBox,getE("div","t",dragBox)[0]); </script> </body> </html>
 提示:您可以先修改部分代码再运行
[ 本帖最后由 wgguizi 于 2010-6-3 15:54 编辑 ]

作者: wgguizi   发布时间: 2010-06-03

我在写拖动效果的时候也研究过这个问题
引用:
这里说说ff下有一个比较奇怪的现象,在SimpleDrag中第一次拖放没有问题,但第二次拖放时鼠标就会显示禁止操作的样式(拖动失败)。
我发现如果在Start程序中阻止默认动作(preventDefault)或清除选择(window.getSelection().removeAllRanges())就能正常了。
所以我估计是在点击事件后,拖放对象已经默认设置成选择状态了(虽然看起来不是),再拖动时就触发了系统的默认拖动事件。
为了支持推断,我在html插入一段文本,然后在每一次拖放之后选择一下那段文本(间接取消拖放对象的选择),那就能正常了。
不过暂时还没找到官方说明,所以还不能下结论。

作者: cloudgamer   发布时间: 2010-06-04

哈哈,版主研究更深

作者: wgguizi   发布时间: 2010-06-04

版主厉害啊

作者: shbijiben   发布时间: 2010-06-04