2013-01-07 42 views
3

我正在一个Web艺术项目,需要许多对象淡入和淡出在特定的时间间隔(我希望使用100个或更多的对象)。我有jQ读取包含元数据的XML文件,并将Ps附加到主体,然后根据元数据中的信息告知其淡入和淡出。我使用setTimeouts来实现这一点。JS/jQ更有效的方式来处理大量的setTimeouts

这件作品最终会非常耗费资源。在页面加载一两分钟后,我的机器开始喘息。 (或者,我认为它可能不是一个资源问题,而是一个图形化的问题。)

有没有人有一些建议,使这更资源友好/高效?我感谢任何帮助!

这里的活链接:http://justwhatdoyoucallthis.com/trynottogiveup/(当心资源猪)

下面是相关的脚本:

$.ajax({ 
    type: 'get', 
    url: 'problems.xml', /* ...which contains like 99 problems */ 
    dataType: 'xml', 
    success: function(problems) { 
     $(document).ready(function() { 
      var winWidth=$(window).width(); 
      var winHeight=$(window).height(); 
      $(problems).find('problem').each(function() { 
       var probType=$(this).attr('type'); 
       var probAppear=$(this).attr('appear'); 
       var probName=$(this).children('name').text(); 
       var probID=(probName.replace(/\s/g, '')).toLowerCase(); 
       var probIntensity=($(this).children('intensity').text()+5)*10; 
       var probInterval=$(this).children('interval').text(); 
       var probDuration=$(this).children('duration').text(); 
       var ranLeft=Math.random()*winWidth-(probIntensity/2); 
       var ranTop=Math.random()*winHeight-(probIntensity/2); 
       $('body').append('<p id="'+probID+'" class="'+probType+'" style="left: '+ranLeft+'px; top: '+ranTop+'px; height: '+probIntensity+'px; width: '+probIntensity+'px;"><span>'+probName+'</span></p>'); 
       (function showLoop() { 
        if(probAppear=='fade') { var fadeInDuration=1000; } else { var fadeInDuration=0; } 
        $('#'+probID).delay(probInterval*1000).fadeIn(fadeInDuration).delay(probDuration*1000).fadeOut(1000); 
        setTimeout(showLoop, 1000); 
       })(); 
      }); 
     }); 
    } 
}); 
+0

适用于Core i5/Linux 64位,firefox 17. BUt我认为一般使用jQuery动画操纵一堆DOM元素无论如何都会占用资源。可能是Canvas在这些事情上更有效率。 – hayavuk

+0

您可以随时尝试查看更改全局间隔值是否有助于您。 '$ .fx.interval = 50;'。从jQuery 1.8开始,默认值是13。 50仍然有一个平稳过渡,并会节省你一些CPU的强度。提高和降低它,直到找到适合您的动画的东西。这不是傻瓜证明。 – Ohgodwhy

回答

1

这里是你的代码的优化版本,但像bvukelic说,整个概念很可能是更高效的画布。

我在代码中看到的问题是,延迟和淡入淡出操作确实是同步调用的,但是超时是异步执行的,这意味着在一段时间后,对同一对象有多个操作流(并且这一百次)。

所以解决方法是将重复的超时作为回调附加到.fadeOut()动作。

$(function() { 
    var $win = $(window), 
     winWidth = $win.width(), 
     winHeight = $win.height(), 
     showLoop = function(prob) { 
      var fadeInDuration = prob.appear == 'fade' ? 1000 : 0; 
      $('#'+prob.id) 
       .delay(prob.interval*1000) 
       .fadeIn(fadeInDuration) 
       .delay(prob.duration*1000) 
       .fadeOut(1000, function() { 
        window.setTimeout(function() { 
         showLoop(prob); // synchronously repeated callback 
        }, 1000); 
       }); 
     }; 

    $.ajax({ 
     type: 'get', 
     url: 'problems.xml', /* ...which contains like 99 problems */ 
     dataType: 'xml', 
     success: function(problems) {   
      $('problem', problems).each(function() { 
       var $t = $(this), 
        probName = $('name', this).text(), 
        prob = { 
         type: $t.attr('type'), 
         appear: $t.attr('appear'), 
         name: probName, 
         id: probName.replace(/\s/g, '').toLowerCase(), 
         intensity: (parseInt($('intensity', this).text()) + 5) * 10, 
         interval: parseInt($('interval', this).text()), 
         duration: parseInt($('duration', this).text()), 
         pos: { 
          top = Math.random()*winHeight-(prob.intensity/2), 
          left = Math.random()*winWidth-(prob.intensity/2) 
         } 
        }; 

       $('<p>') 
        .append('<span>'+prob.name+'</span>') 
        .attr('id', prob.id) 
        .addClass(prob.type) 
        .width(prob.intensity) 
        .height(prob.intensity) 
        .css({ 
         top: prob.pos.top, 
         left: prob.pos.left, 
        }) 
        .appendTo('body'); 

       showLoop(prob); 
      }); 
     } 
    }); 
}); 
+0

我刚刚从这里学到了很多关于javascript的知识。该页面像冠军一样运行,我明白为什么。谢谢! –

+0

我很高兴我可以帮助你:) – Simon

+0

我真的很想看到这个项目,所以你可以发布一个网络链接,如果或只要你有它在线? – Simon

相关问题