2013-06-23 44 views
1

所以我寫了一種繪圖腳本,現在它工作的很好(雖然代碼仍然需要清理並且需要更多的功能),但是當繪畫太多時,mousemove滯後令人難以置信的。這裏是主要的Javascript:防止在DOM中滯後

$('#canvas').on('mousedown', function(){ 
     going = !going; 
     $(this).on('mousemove', function(e){ 
      if(cursor == 'paint' && going == true){ 
     $('.fall').each(function(){ 
      if ($(this).css("opacity") == 0){ 
       $(this).remove(); 
      }; 
     }); 
     var ps = $('#canvas').offset().top; 
     var t = (e.pageY - ps - $('.fall').height()).toString() + 'px'; 
     var l = (e.pageX - $('.fall').width()).toString() + 'px'; 
     $('.fall').css("margin_left",l); 
     $('.fall').css("margin_top",t); 
       var doit = '<div class="fall" style="position:absolute;margin-left:' + l + ';margin-top:' + t + ';background-color:'+ color +';box-shadow: 0px 0px 5px ' + color + ';"></div>' 
     $('#canvas').prepend(doit); 
      } 
      else if(cursor == 'erase'){ 
      $('.fall').mouseenter(function(){ 
       $(this).fadeOut('fast',function(){ 
        $(this).remove() 
       }); 
      }); 
     }; 
    }); 

從本質上講,當你在部分中單擊繪圖,如果點擊該按鈕,油漆,可以得出:jsfiddle

我的問題:

如果你畫太多了,尤其是啓動和停止,它並不追加足夠的mousemove做的(我認爲)的DOM被淹沒。

問:

什麼會是很多很多的div添加到DOM而不產生滯後的有效途徑?這可能嗎?

注:

這是一個個人項目,我沒有興趣使用先前創建繪圖API

+0

您正在爲每個「mousedown」添加**另一個**「mousemove」處理程序。調用'.on()'不會刪除任何以前的處理程序! – Pointy

+0

嗯,我想這是真的!我將如何刪除處理程序? –

+1

有沒有必要刪除舊的處理程序;只需將該代碼添加到其他「mousemove」處理程序即可。此外,更新「光標」的代碼非常昂貴。您應該嘗試從事件對象獲取鼠標座標,而不是詢問DOM。 – Pointy

回答

1

有很多可以做,以提高性能。

下面的代碼是對問題中的代碼進行大量重構。乍一看,它可能效率不高,因爲它大約是原件行數的兩倍。但是,線數並不是問題。有兩條基本原則適用:

  • 儘可能在mousemove處理程序中進行儘可能少的DOM交互,並儘可能地在mousedown上進行操作。
  • 包括一個「分頻器電路」來限制mousemove處理程序被調用的次數。這是通過在每次調用時分離mousemove事件處理程序並在短暫延遲後重新連接來實現的,條件是鼠標仍然處於關閉狀態。

另請參閱代碼中的註釋。

jQuery(function($) { 
    ... 
    var $canvas = $("#canvas"); 
    var data = { 
     name: 'fall'//a unique string for namespacing the muousemove event. 
    }; 
    $canvas.on('mousedown', function() { 
     going = !going; 
     data.$fall = $('.fall');//this collection is created once per mousedown then managed inside mm to avoid unnecessary DOM interaction 
     data.mousedown = true; 
     data.colorCSS = { 
      'background-color': color, 
      'box-shadow': '0px 0px 5px ' + color 
     }; 
     data.fallWidth = data.$fall.width(); 
     data.fallHeight = data.$fall.height(); 
     attachMouseMoveHandler(); 
    }).on('mouseup', function() { 
     data.mousedown = false; 
    }).trigger('mouseup'); 

    function attachMouseMoveHandler() { 
     if(data.mousedown); 
      $canvas.on('mousemove.' + data.name, mm);//the event is namespaced so its handler can be removed without affecting other canvas functionality 
    } 

    //The mousemove handler 
    function mm(e) { 
     if(going && cursor == 'paint') { 
      data.$fall.each(function() { 
       data.$fall = data.$fall.not(this);//manage data.$fall rather than re-form at every call of mm() 
       var $this = $(this); 
       if ($this.css("opacity") == 0) { 
        $this.remove(); 
       }; 
      }); 
      data.$fall = data.$fall.add($('<div class="fall" />').css(data.colorCSS).prependTo($canvas)).css({ 
       'margin-left': (e.pageX - data.fallWidth) + 'px', 
       'margin-top': (e.pageY - $canvas.offset().top - data.fallHeight) + 'px' 
      }); 
     } 
     else if(cursor == 'erase') { 
      data.$fall.mouseenter(function() { 
       data.$fall = data.$fall.not(this);//manage data.$fall rather than re-form at every call of mm() 
       var $this = $(this).fadeOut('fast', function() { 
        $this.remove(); 
       }); 
      }); 
     }; 
     $canvas.off('mousemove.' + data.name); 
     setTimeout(attachMouseMoveHandler, 50);//adjust delay up/down to optimise performance 
    } 
}); 

只爲語法

我不得不做出一些假設的測試,主要是關於什麼成爲對鼠標按下固定數據。這些假設可能是不正確的,所以你很可能還有一些工作要做,但只要你在上面的總體框架內工作,你的性能問題很可能會消失。

+0

+1,很好的解釋和代碼似乎非常有希望,但是當我試圖將它實現到我的jsfiddle時,它打破了小提琴...也許我把它錯了? –

+0

我只是對答案中的代碼做了一個小但潛在的重要修改。 'data。$ fall.add'現在讀取'data。$ fall = data。$ fall.add(...'。如果這不能解決小提琴問題,那麼我需要看它來判斷什麼是錯誤 –

+0

我鏈接了jsfiddle,顯示了問題中的所有內容...這是一個使用代碼的jsfiddle:http://jsfiddle.net/xyuBJ/1/ ...當你比較它們時,你的延遲較少,但除非你刪除了延遲......但是這會增加延遲......這甚至有可能嗎? –