Ваша цепочка замыкания вызывает ваши проблемы. Объявляя встроенную функцию-обработчик, вы создали замыкание. Очевидно, вы сделали это, чтобы воспользоваться преимуществом цикла.
Однако, поскольку вы создали замыкание, вы играете по правилам определения замыкания. Эти правила гласят, что локальные переменные внутри родительской функции остаются активными и доступными, пока существует замыкание.
Вы пытаетесь передать, а затем использовать «action» и «dao_id» для своего закрытия, но вы передаете здесь ссылки, а не значения. Поэтому, когда ваши замыкания (обработчики) вызываются, они используют значение, которое ссылка была назначена последней. В вашем случае обработчик шага 3.
Правила области видимости закрытия достаточно запутанные, но вы также можете быть смущены тем фактом, что «action» и «dao_id» все еще живы, даже если блок цикла завершил выполнение. Ну, в JavaScript нет такой вещи, как область видимости блока. После объявления переменной она доступна до конца функции или до тех пор, пока она не будет удалена. В зависимости от того, что наступит раньше.
Все, что сказано, вам нужно разорвать цепь прицела. Вот два способа сделать это:
Попробуйте это:
for (var i = 0; i < profile.current + 1; i++) {
if ($('step_anchor_' + i).innerHTML.empty()) {
var action = profile.steps[i].action;
var dao_id = profile.steps[i].dao_id;
$('step_anchor_' + i).innerHTML = profile.steps[i].anchor;
$('step_anchor_' + i).observe('click', function(a, b){
return function(){pm.loadData(a, b, true)};
}(action, dao_id));
Effect.Appear('step_anchor_' + i, {
duration: 1,
delay: (down_delay++)
});
}
}
Или это:
function createHandler(action, dao_id) {
return function(){pm.loadData(action, dao_id, true);};
}
/* snip - inside some other function */
for (var i = 0; i < profile.current + 1; i++) {
if ($('step_anchor_' + i).innerHTML.empty()) {
var action = profile.steps[i].action;
var dao_id = profile.steps[i].dao_id;
$('step_anchor_' + i).innerHTML = profile.steps[i].anchor;
$('step_anchor_' + i).observe('click', createHandler(action, dao_id));
Effect.Appear('step_anchor_' + i, {
duration: 1,
delay: (down_delay++)
});
}
}