функция обратного вызова jQuery, только работающая над последним циклом

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

, Но как осуществление программирования, и видя, что Вы работаете с C++, необходимо будет переопределить глобальное новое и удалить, а также malloc, свободный и перевыделение. Вы думали бы, что только новое переопределение и удаляет, был бы достаточно, но станд.:: строка и другие классы, вероятно, будут использовать malloc и особенно перевыделение.

Затем как только Вы имеете в распоряжении это, можно начать добавлять заголовки для проверки на перезаписи памяти, рекордные отслеживания стека на выделение и так далее.

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

6
задан DA. 13 October 2009 в 18:52
поделиться

4 ответа

Это обычная проблема, возникающая при объединении замыканий с циклами. JavaScript - это язык с поздним связыванием, и циклы не вводят новую область видимости. Итак:

for (var i= 0; i<5; i++) {
    $('#thing'+i).click(function() {
        alert(i);
    });
}

В этом коде есть только одна переменная i . Он начинается с 0 , а после завершения цикла присваивания остается на 5 . Событие щелчка на элементе # thing0 будет запущено только после завершения выполнения цикла, и к этому моменту значение i будет 5 . Вы не получите значение времени определения 0 , которого могли ожидать.

Это применимо не только к самой переменной цикла, но и ко всем другим переменным, которые вы повторно назначаете для каждого цикла цикла. Таким образом, в вашем примере значение barChartID внутри функции обратного вызова анимации всегда будет идентификатором, связанным с последним элементом в вашем цикле.

Обычный обходной путь - взять копию значения переменной цикла в define-time с помощью структуры, которая действительно вводит новую область видимости, а именно другую функцию:

$(barChartID + " img").animate({height: actualBarHeight}, 500, function(barChartID) {
    return function() {
        $(barChartID + " .value span").css('background-color','white');
    };
}(barChartID));

Подробнее о циклических замыканиях.

16
ответ дан 8 December 2019 в 05:22
поделиться

Это связано с тем, что ваша функция обратного вызова имеет неявный указатель на переменную barChartID . Вот как работают замыкания. Вы хотите создавать новую копию текущего значения barChartID на каждой итерации. Один из способов исправить это - запустить тело цикла for внутри функции. Я видел эту закономерность в новой книге Джона Ресига Secrets of the JavaScript Ninja

for(var i=0; i<barValues.length; i++) function(i){
    ...
}(i);
4
ответ дан 8 December 2019 в 05:22
поделиться

Поскольку вы используете jQuery, вы можете использовать функцию $ .each вместо цикла for. Обратный вызов, используемый вместо цикла, создаст новое закрытие.

$.each(barValues, function(i, barValue){
    actualBarHeight = Math.floor((barValue/chartMaxY)*barchartHeight);

    var barChartID = "#barChart" + (i+1)
    $(barChartID + " .value span").css('background-color','transparent');
    $(barChartID + " img").animate({ 
                    height: actualBarHeight
            }, 500, function(){$(barChartID + " .value span").css('background-color','white');}
    );

    $(barChartID + " .value span").html("$"+Math.floor(barValue));
    $(barChartID + " .value").css("bottom",actualBarHeight+"px");
    $(barChartID + " .ylabel").html(chartMaxY);
});
3
ответ дан 8 December 2019 в 05:22
поделиться

Вы можете попробовать кэшировать селектор диапазона, например:

var barChartID = "#barChart" + (i+1)
var span = $(barChartID + " .value span");
span.css('background-color','transparent');
$(barChartID + " img").animate({ 
    height: actualBarHeight
}, 500, function() {
    span.css('background-color','white');
});
0
ответ дан 8 December 2019 в 05:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: