2012-10-24 8 views
0

У меня есть сетка ящиков (3x2), которую я бы хотел обновить в цикле, учитывая большой массив значений rgb, представляющих изменяющиеся цвета с течением времени. Пример одного элемента массива выглядит следующим образом:JS Постоянное обновление цветов CSS-фона в сетке - закрытие?

[[99,58221354166666, 99,20004050925925, +100,86330150462963], [+59,431727430555554, 58,59181712962963, +61,26002314814815], [+59,824817708333335, +58,83816550925926, +61,85647280092593], [+93,02857349537037, 95,04584201388889, +92,13913194444444], [ 48,46075810185185, +50,74021701388889, 46,878373842592595], [+84,57517939814815, +173,51900462962962, 62,35618923611111]]

ниже код обрабатывает значения RGB и все отлично. Каждый элемент массива соответствует «ящику» в сетке 3x2. К сожалению, у моей петли, похоже, есть проблема с закрытием, и я не могу понять это. Он только обновляет цвета сетки на последней итерации. Поэтому я переписал его, чтобы сохранить список функций, а затем называть их, но я не могу сказать, просто ли он выполняется так быстро, что я не вижу его или если он на самом деле не работает. Если я добавлю спать, скрипт будет зависать, и везде, где он зависает, он будет обновляться в течение одного момента, пока я не нажму кнопку продолжения. После чего он покажет мне последнее обновление (так что я перестал видеть последнее обновление, увидев два со скриптом, видимо, висящим).

c1 = $("#cell1"); 
c2 = $("#cell2"); 
c3 = $("#cell3"); 
c4 = $("#cell4"); 
c5 = $("#cell5"); 
c6 = $("#cell6"); 
var cells = [c1, c2, c3, c4, c5, c6]; 

$(document).ready(function() { 
    $.each(test, function(iGrid, grid) { 
     var ary_rgb = []; 
     var property = "background"; 
     var updates = []; 
     $.each(grid, function (iBox, box) { 
      var r = Math.floor(box[0]).toString(); 
      var g = Math.floor(box[1]).toString(); 
      var b = Math.floor(box[2]).toString(); 
      var rgb = 'rgb(' + r + ',' + g + ',' + b + ')'; 
      updates[iBox] = function() { return cells[iBox].css(property, rgb); }; 
     }); 

     for (var i=0; i<updates.length;i++) { 
      updates[i](); 
     } 
    }); 
}); 

я потратил несколько часов, пытаясь получить эту работу и чтение SO и другие сайты закрытия, но я просто не могу видеть, что я делаю неправильно. Я могу опубликовать остальную часть html, если это необходимо.

+0

Я не вижу здесь никаких проблем с закрытием. Трудно сказать, потому что это неполный фрагмент. И что такое 'test'? (здесь невозможно сказать). Кроме того, назначения 'c1' thru' c6' должны выполняться в обработчике '$ (document) .ready()'. Вы получите лучшую обратную связь, если бы вы могли создать runnable jsFiddle, который воспроизводит проблему. – meetamit

+0

http://jsfiddle.net/rBLLc/2/ Это прокомментировало и то, как я изначально пытался. – cdownard

ответ

0

Я думаю, что это то, что вы» не собираюсь, нет? http://jsfiddle.net/rBLLc/4/

В целом, как и вы предлагали, все ваши обновления происходили быстро, один за другим, и браузер никогда не имел возможности отображать изменения.

(Также была ошибка javascript в jsfiddle, из-за updates не определено).

Вам необходимо разделить обновления, используя setTimeout, как показано на рисунке.

+0

Большое вам спасибо. Я получаю это сейчас, внутренний цикл должен находиться внутри setTimeout. Я отслеживаю живые доминирующие значения для разделов на дисплее. Это потрясающе. – cdownard

0

Если вы говорите, что ящики не меняются, пока не будет запущено javascript, тогда это ожидаемое поведение. Страница не будет обновляться визуально до тех пор, пока все javascript не вернутся. Вы можете использовать setTimeout для возврата контроля после каждой эффективной итерации. Никогда не спите (спиновая петля) в javascript, используйте запрограммированный обратный вызов.

function runUpdate(update) { 
    if (update.length > 0) { 
     update[0](); 
    } 

    if(update.length > 1) { 
     setTimeout(function() { 
      runUpdate(update.slice(1)); 
     }, 0); 
    } 
} 

Замените петлю на runUpdates(updates);. Вы можете использовать параметр времени setTimeout, чтобы изменить скорость, с которой поля меняют цвет.

+0

Это просто замедляет последнее обновление. Когда я добавляю это и запускаю его, прикрепленный к скрипту js в приведенной выше ссылке, он просто замедляет его обновление в последнем поле. С массивом «test» у меня есть около 270 штук данных RGB. Кажется, что он страдает от той же проблемы, что и прежде, чем это было точно так, как вы сказали, после того, как javascript будет запущен, а затем обновит поля (по одному за раз). – cdownard

1

Я слишком устал/немой, чтобы понять ваш пример и выяснить, как он относится к закрытию, но я могу сказать, что он намного больше и сложнее, чем это нужно для того, что вы говорите, чего хотите. Вам не нужно использовать закрытие для этой задачи, кроме тех, которые созданы функциями jQuery. Кроме того, повторно:

Он обновляет только цвета сетке на последней итерации

, так как вы не использовали никаких функций синхронизации, нет никаких оснований для Вас, чтобы видеть больше, чем одно обновление.

Это очень простая демонстрация описанных вами: http://jsbin.com/unuvuq/2/edit. Обратите внимание на использование setTimeout - это то, что вам нужно, если вы хотите видеть каждое обновление в разное время.

Код с демонстрационной версии внизу. JS:

$(document).ready(function() { 

    var colours = [ 
     "aquamarine", 
     "crimson", 
     "goldenrod", 
     "forestgreen", 
     "dodgerblue", 
     "orange"]; 

    $('[id^="cell"]').each(function() { 
     var cell = $(this), 
      time = 500 * cell.index(); 
     setTimeout(function() { 
      cell.css('background', colours[cell.index()]); 
     }, time); 
    }); 

}); 

разметки:

<div class="container"> 
    <div id="cell1"></div> 
    <div id="cell2"></div> 
    <div id="cell3"></div> 
    <div id="cell4"></div> 
    <div id="cell5"></div> 
    <div id="cell6"></div> 
</div> 

CSS: (все произвольные значения выбраны только, чтобы позволить вам увидеть, что происходит)

.container { width: 200px; } 

div[id^="cell"] { 
    display: inline-block; 
    border: 3px solid #000; 
    height: 50px; 
    width: 50px; 
} 
+0

Мое обновление цветов работает. Я не хочу, чтобы обновленные фоны отображались медленно или что-то еще. Я хочу, чтобы они обновлялись каждый раз, когда я выполняю цикл, но в настоящее время он обновляется только с последним после завершения цикла. Сетка равна 3x2, как и вы, и у меня есть все значения RGB для каждого экземпляра полной сетки в массиве, называемом test (как показано здесь http://jsfiddle.net/rBLLc/2/). Когда я запускаю его в firefox или chrome, я получаю только последнее состояние сетки. Я не вижу, чтобы он обновлялся каждый раз, когда внешний цикл завершает итерацию. Ящики должны быстро обновляться. – cdownard

+0

Что значит «быстро»? Обновления могут происходить быстрее или медленнее в зависимости от времени, которое вы даете 'setTimeout'. Если вы не хотите использовать какую-либо функцию синхронизации, тогда все обновления должны происходить одновременно и быть мгновенными ... вот что вы говорите, что получаете. Итак, вам нужно одно мгновенное обновление или нет? – tuff

Смежные вопросы