$(document).ready(function(){ // Immerse yourself in squares. var dim = Math.round(($('#boxen').parent().width() - 16) / 8) * 8; $('#boxen').width(dim); $('#boxen').height(dim); var box_count = Math.pow(dim / 8, 2); // A queue of function references var work = []; for (var i=0; i<box_count; i++){ /* Instead of executing the code and moving on to the next iteration, just put the job in the queue as a function. */ var job = function(){ var r = Math.round(Math.random() * 255); var g = Math.round(Math.random() * 255); var b = Math.round(Math.random() * 255); var color = 'rgb(' + r + ', ' + g + ', ' + b + ')'; $('<li>').attr('style', 'background-color: ' + color).appendTo('#boxen'); }; work.push(job); } /* How many milliseconds the browser should work before unlocking and working on something else. */ var max_lock = 50; /* How long the breather should be. 1 millisecond is enough to prompt the browser to turn to another task and complete it before returning to this queue. */ var timeout = 1; // Turn over the queue for execution. do_work(work, max_lock, timeout, null); }); function do_work(work, max_lock, timeout, wrapup){ var curr_time, start_time = new Date().getTime(); while (work.length){ curr_time = new Date().getTime(); if (curr_time - start_time < max_lock){ // Pull the first job function from the queue and execute it. work.shift()(); }else{ /* We've worked on this long enough -- let's take a quick break, making a note to come back and continue. */ setTimeout(function(){ do_work(work, max_lock, timeout, wrapup); }, timeout); return false; } } // Optional callback function for when the queue is completed. if (wrapup !== null){ wrapup(); } }
<ul id="boxen"></ul>
#boxen{ background-color: #ccc; } #boxen li{ display: block; width: 8px; height: 8px; float: left; }