2

だから私は一種の描画スクリプトを書いていますが、今はうまく動作します (ただし、コードはまだクリーンアップする必要があり、より多くの機能が必要です) mousemove。主な Javascript は次のとおりです。

   $('#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 .

私の問題:

特に開始と停止で描画しすぎると、Do に十分に追加されずmousemove、DOM が圧倒されます (私はそう思います)。

質問:

遅延を発生させずに多数の div を DOM に追加する効率的な方法は何でしょうか? これは可能ですか?

ノート:

これは個人的なプロジェクトであり、以前に作成した描画 API の使用には興味がありません

4

1 に答える 1

2

パフォーマンスを向上させるためにできることはたくさんあります。

以下のコードは、問題のコードを大幅にリファクタリングしたものです。元の約2倍の行数があるため、一見すると効率が悪いように見えるかもしれません。ただし、ここでは行数は問題ではありません。2 つの基本原則が適用されます。

  • 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
    }
});

構文についてのみテスト済み

主に、マウスダウンで何が固定データになるかに関して、いくつかの仮定を立てる必要がありました。これらの仮定は正しくない可能性があるため、おそらくまだやるべきことがいくつかありますが、上記の全体的なフレームワーク内で作業している限り、パフォーマンスの問題が解消される可能性は十分にあります。

于 2013-06-24T11:42:14.247 に答える