您好,
  假設我有10個圖形要在網頁上能夠自由地被拖曳移動. 我試了兩種方法如下. 我想請問為何兩種方式在滑鼠拖曳圖片時的效能會差這麼多? 方法1的效能比方法2差許多, 不知問題出在哪? 請幫幫忙, 指教更精簡更有效率的做法. 謝謝!!
1. 設定好addEventHandler, 這10個圖形都去呼叫它, share同一個mousedown, mouseup, mousemove. 用target.addEventListener來觸發事件函式.
    problem: 滑鼠只能慢慢移動, 否則圖形來不及偵測mouseup而出現圖形亂飄(應該是因為mousemove的listener仍在作用).
    ----------------------------------------------------
    for(var i=0;i<GroupID02.childNodes.length;i++){
     if(GroupID02.childNodes[i].id){
     addEventHandler(GroupID02.childNodes[i],"mousedown",mousedown_listener);
     }
    }
    function addEventHandler(target, type, func) {
     if (target.addEventListener)
     target.addEventListener(type, func, true);
     else if (target.attachEvent)
     target.attachEvent("on" + type, func);
     else target["on" + type] = func;
    }
    function removeEventHandler(target, type, func) {
     if (target.removeEventListener)
     target.removeEventListener(type, func, true);
     else if (target.detachEvent)
     target.detachEvent("on" + type, func);
     else delete target["on" + type];
    }
    function mousedown_listener()
    {
     var oEvent = arguments[0];
     var oTarget = oEvent.target || oEvent.srcElement;
     dx = oTarget.x.baseVal.value - oEvent.clientX;
     dy = oTarget.y.baseVal.value - oEvent.clientY;
     addEventHandler(oTarget,"mousemove",mousemove_listener);
     addEventHandler(oTarget,"mouseup",mouseup_listener);
    }
    function mousemove_listener()
    {
     var oEvent = arguments[0];
     var oTarget = oEvent.target || oEvent.srcElement;
     var id = oTarget.ownerSVGElement.suspendRedraw(1000);
     oTarget.x.baseVal.value = oEvent.clientX + dx;
     oTarget.y.baseVal.value = oEvent.clientY + dy;
     oTarget.ownerSVGElement.unsuspendRedraw(id);
    }
    function mouseup_listener()
    {
     var oEvent = arguments[0];
     var oTarget = oEvent.target || oEvent.srcElement;
     removeEventHandler(oTarget,"mousemove",mousemove_listener);
     removeEventHandler(oTarget,"mouseup",mouseup_listener);
    }
2. 每個圖形都有自己的mousedown, mouseup and mousemove, 用document.addEventListener來觸發事件函式.
   problem: 無法動態增加圖片, 要另外新增事件控制程式碼
    -----------------------------------------------------
    rectangle001.addEventListener("mousedown", mousedown_listener001, true);
    rectangle002.addEventListener("mousedown", mousedown_listener002, true);
    ...
    rectangle010.addEventListener("mousedown", mousedown_listener010, true);    function mousedown_listener001(evt)
    {
     dx001 = rectangle001.x.baseVal.value - evt.clientX;
     dy001 = rectangle001.y.baseVal.value - evt.clientY;
     if(ifIE){
     document.attachEvent("mousemove", mousemove_listener001, true);
     document.attachEvent("mouseup", mouseup_listener001, true);
     }else{
     document.addEventListener("mousemove", mousemove_listener001, true);
     document.addEventListener("mouseup", mouseup_listener001, true);
     }
    }
    ....
    function mousemove_listener001(evt)
    {
     var id = rectangle001.ownerSVGElement.suspendRedraw(1000);
     rectangle001.x.baseVal.value = evt.clientX + dx001;
     rectangle001.y.baseVal.value = evt.clientY + dy001;
     rectangle001.ownerSVGElement.unsuspendRedraw(id);
    }
   ...
   function mouseup_listener001(evt)
   {
     if(ifIE){
     document.detachEvent("mousemove", mousemove_listener001);
     document.detachEvent("mouseup", mouseup_listener001);
     }else{
     document.removeEventListener("mousemove", mousemove_listener001, true);
     document.removeEventListener("mouseup", mouseup_listener001, true);
     }
   }

解决方案 »

  1.   

    Sorry, 因我是台湾人, 老忘了化繁为简.  您好,假设我有10个图形要在网页上能够自由地被拖曳移动. 我试了两种方法如下. 我想请问为何两种方式在鼠标拖曳图片时的效能会差这么多? 方法1的效能比方法2差许多, 不知问题出在哪? 请帮帮忙, 指教更精简更有效率的做法. 谢谢!!  
    1. 设定好addEventHandler, 这10个图形都去呼叫它, share同一个mousedown, mouseup, mousemove. 用target.addEventListener来触发事件函式.      
       problem: 鼠标只能慢慢移动, 否则图形来不及侦测mouseup而出现图形乱飘(应该是因为mousemove的listener仍在作用). 
    2. 每个图形都有自己的mousedown, mouseup and mousemove, 用document.addEventListener来触发事件函式.    
       problem: 无法动态增加图片, 要另外新增事件控制程序码
      

  2.   

    第一个!原因我找到了,原因是你把mousemove这个函数绑定到了被拖拽的物件上,造成的后果就是,只有鼠标处在物件上面的时候才有效果,如果鼠标移动过快,离开了物件,那么这个mousemove就失效了,因为鼠标已经脱离了物件,所以你应该考虑在mouseover的相关的函数的内容放到其他物件上去,放到document是比较好的选择,因为你的鼠标很难跑出document的范围,也就不会失效,我在测试你的代码的时候改的有点乱,因为我的电脑似乎找不到很多你曾经用到的方法,所以我把他们做了//,注掉了,原因是这个原因,具体代码还需要你自己去写的完美!我的时间也有限!你可以运行我下面的代码,你会发现在点击了红色部分后,不再轻易脱离鼠标!<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <HTML>
     <HEAD>
      <TITLE> New Document </TITLE>
      <META NAME="Generator" CONTENT="EditPlus">
      <META NAME="Author" CONTENT="">
      <META NAME="Keywords" CONTENT="">
      <META NAME="Description" CONTENT="">
     </HEAD>
    <Style>
    div li{border-color:green;background-color:red;position:absolute;}</style>
     <BODY>
      <div id="GroupID02"><li id="d1">caoa</li><li id="2">caoa</li></div>
     </BODY>
     <script type="text/javascript">
     var GroupID02=document.getElementById("GroupID02");
     var dx,dy,oldx,oldy,oTarget=document.getElementById("d1");
      for(var i=0;i <GroupID02.childNodes.length;i++){ 
        if(GroupID02.childNodes[i].id){ 
        addEventHandler(GroupID02.childNodes[i],"mousedown",mousedown_listener); 
        } 
        } 
        function addEventHandler(target, type, func) { 
        if (target.addEventListener) 
        target.addEventListener(type, func, true); 
        else if (target.attachEvent) 
        target.attachEvent("on" + type, func); 
        else target["on" + type] = func; 
        } 
        function removeEventHandler(target, type, func) { 
        if (target.removeEventListener) 
        target.removeEventListener(type, func, true); 
        else if (target.detachEvent) 
        target.detachEvent("on" + type, func); 
        else delete target["on" + type]; 
        } 
        function mousedown_listener() 
        { 
        var oEvent = arguments[0]; 
        var oTarget = oEvent.target || oEvent.srcElement; 
        dx = oTarget.style.left;
    oldx=oEvent.clientX; 
        dy = oTarget.style.top;
    oldy=oEvent.clientY; 
        addEventHandler(document.getElementsByTagName("body")[0],"mousemove",mousemove_listener); 
        addEventHandler(oTarget,"mouseup",mouseup_listener); 
        } 
        function mousemove_listener() 
        { 
        var oEvent = arguments[0]; 
        //var oTarget = oEvent.target || oEvent.srcElement; 
       // var id = oTarget.ownerSVGElement.suspendRedraw(1000); 
        oTarget.style.left = oEvent.clientX-oldx + dx; 
        oTarget.style.top = oEvent.clientY-oldy + dy; 
       // oTarget.ownerSVGElement.unsuspendRedraw(id); 
        } 
        function mouseup_listener() 
        { 
        var oEvent = arguments[0]; 
        var oTarget = oEvent.target || oEvent.srcElement; 
      //  removeEventHandler(oTarget,"mousemove",mousemove_listener); 
       // removeEventHandler(oTarget,"mouseup",mouseup_listener); 
        }  
     </script>
    </HTML>关于第二个问题,我谈一谈我的看法,我觉得你可以不需要写那么多的方法!你可以考虑换一种写法,比如这么写!rectangle001.addEventListener("mousedown", mousedown_listener001, true); 
        rectangle002.addEventListener("mousedown", mousedown_listener002, true); 
        ... 
        rectangle010.addEventListener("mousedown", mousedown_listener010, true); 
    换成:
    var photo=document.getElementsByTagName("img");//[rectangle001,rectangle001,..]for(var i=0;i<photo.length;i++){
    this.addEventListener("mousedown", mousedown_listener, true); 
    }
    这样你就不需要写太多的代码,当然这只是思路,如果你直接复制我写的代码显然会出很多错误,因为我并不是非常熟悉代码的拼写格式!第二个问题:
    如果你新加了其他的图片,在你添加完毕之后,你可以再重新运行我上面写的函数,因为这时候photo数组已经把你新加的图片自动搜索进去,所以新加的图片也已经添加了各种事件!mousedown,mousemove,mouseup,当然从思路来说这并不是最好的办法,这会增加浏览器的负担,我只是想告诉你,想动态给一张图片添加动作事件,并没有你想的那么困难,我认为最好的方法是这样的,你新加的图片可以通过id /name/ class等方法得到它的引用,然后直接把这张图片传到某个函数中去,这个函数在整个网页中只写一次,在函数内部采用this来代替图片,并对当前图片进行整理,添加对应的动作事件mousedown,mousemove,mouseup你也看到,在上面我就已经提到了,不要为某张图片写固定的方法,要统一写一个对每一张图片都起作用的方法,这样可以省很多代码量,而且可以动态和新图片联合起作用!综上所述,你似乎总是担心方法与物件一对一,其实你可以把所有的物件的集合整体看做是一个更大的物件,只对这一个大的物件只写一个方法就可以了,
    在函数方法内部你可以用for(var i=0;i<arr.length;i++){"this"to do something}
    这样对大集合大物件中的每一个具体的物件进行管控;最后:希望你多打打基础,系统的看一些资料,因为从思路上来讲,我上面说的这些真是再简单不过的东西了!
      

  3.   

    tntooo,
      多謝你花時間費心思幫忙, 謝謝你.