setblink(id)
вызывает функцию немедленно. Переполнение стека является признаком немедленного, а не отложенного выполнения, поскольку setTimeout
планирует выполнение на более позднее время, поэтому будущий вызов не будет перенесен в текущий стек вызовов.
Поскольку setblink
принимает аргумент, оберните его в аннулированную анонимную функцию для отложенной оценки .
function setblink(id) {
var elm = document.getElementById(id);
if (elm.color == "red"){
elm.color = "black";
}
else{
elm.color = "red";
}
setTimeout(function () {setblink(id)},500);
}
for (var x in repsToBlink){
(function (id) {
setTimeout(function () {setblink(id)},500);
})(repsToBlink[x]);
}
Код требует дополнительных улучшений.
Если repsToBlink
является массивом, вы должны циклически обрабатывать целочисленные индексы из repsToBlink
(for (...;...;...)
), а не свойства (for ... in
). Однако если вместо этого вы будете использовать объект с идентификаторами и индексами (а не значениями), for ... in
будет уместным.
Выше приведено срабатывание отдельного таймера для каждого id
(что может перегружать браузер). Перемещая цикл в функцию, которая становится единственной функцией, подлежащей планированию, требуется только один таймер.
Поскольку вы периодически запускаете функцию, setInterval
является более подходящим.
Всякий раз, когда вы удаляете и идентифицируете из repsToBlink
, проверьте, есть ли еще какие-либо; если нет, отмените интервал.
(function () {
var repsToBlink, repCount=0, blinkInterval;
function startBlinking(ids) {
addRepsToBlink(ids);
if (! blinkInterval) {
blinkInterval = setTimeout(blinkAll, 500);
}
}
function addRepsToBlink(ids) {
for (var i=0; i<ids.length; ++i) {
addRep(ids[i]);
}
}
function addRep(id) {
if (! id in repsToBlink) {
++repCount;
repsToBlink[ids[i]] = true;
}
}
function removeRep(id) {
if (id in repsToBlink) {
delete repsToBlink[id];
--repCount;
if (!repCount) {
clearInterval(blinkInterval);
blinkInterval=0;
}
}
}
function blinkAll() {
for (id in repsToBlink) {
blink(id);
}
}
function blink(id) {
var elm = document.getElementById(id);
if (elm.color == "red"){
elm.color = "black";
} else {
elm.color = "red";
}
}
window.startBlinking = startBlinking;
window.addRepsToBlink = addRepsToBlink;
window.addRep = addRep;
window.removeRep = removeRep;
})();