Я согласен с некоторыми комментариями. Есть много хороших библиотек JavaScript, которые не только облегчают написание кода, но и устраняют некоторые проблемы совместимости браузера.
Сказав это, вы можете изменить свои функции замирания для принятия обратного вызова:
function fadeIn(callback) {
return function() {
function step() {
// Perform one step of the animation
if (/* test whether animation is done*/) {
callback(); // <-- call the callback
} else {
setTimeout(step, 10);
}
}
setTimeout(step, 0); // <-- begin the animation
};
}
document.getElementById('fade_in').onclick = fadeIn(function() {
alert("Done.");
});
Таким образом, fadeIn
вернет функцию. Эта функция будет использоваться в качестве обработчика onclick
. Вы можете передать fadeIn
функцию, которая будет вызываться после выполнения последнего шага анимации. Внутренняя функция (возвращаемая fadeIn
) по-прежнему будет иметь доступ к callback
, потому что JavaScript создает вокруг нее замыкание .
Ваш анимационный код все еще может быть значительно улучшен, но это в двух словах то, что делает большинство библиотек JavaScript:
- Выполнять анимацию пошагово;
- Проверьте, готово ли вы;
- Вызвать обратный вызов пользователя после последнего шага.
И еще одна последняя вещь: анимация может быть довольно сложной. Если, например, вам нужен надежный способ определения продолжительности анимации, вам нужно использовать функции анимации (также то, что делают большинство библиотек). Если математика не ваша сильная сторона, это может быть не очень приятно ...
В ответ на ваш комментарий: вы говорите, что хотите, чтобы он продолжал работать так же; "Если функция bussy, ничего не произойдет."
Итак, если я правильно понимаю, вы хотите, чтобы анимация блокировалась. На самом деле, я могу сказать вам две вещи:
- Ваша анимация не блокируется (по крайней мере, не сами анимации - читайте ниже).
- Вы все равно можете заставить его работать так, как вам нравится, с любыми видами асинхронной анимации.
Это то, для чего вы используете done_or_not
. Это, на самом деле, общая схема. Обычно вместо строки используется логическое значение (true
или false
), но принцип всегда тот же:
// Before anything else:
var done = false;
// Define a callback:
function myCallback() {
done = true;
// Do something else
}
// Perform the asynchronous action (e.g. animations):
done = false;
doSomething(myCallback);
Я создал простой пример того вида анимации, который вы хотите выполнять, только с использованием jQuery. Вы можете посмотреть на это здесь: http://jsfiddle.net/PPvG/k73hU/
var buttonFadeIn = $('#fade_in');
var buttonFadeOut = $('#fade_out');
var fadingDiv = $('#fading_div');
var done = true;
buttonFadeIn.click(function() {
if (done) {
// Set done to false:
done = false;
// Start the animation:
fadingDiv.fadeIn(
1500, // <- 1500 ms = 1.5 second
function() {
// When the animation is finished, set done to true again:
done = true;
}
);
}
});
buttonFadeOut.click(function() {
// Same as above, but using 'fadeOut'.
});
Из-за переменной done
кнопки будут реагировать только после завершения анимации. И, как вы можете видеть, код действительно короткий и читаемый. Это преимущество использования библиотеки, такой как jQuery. Но, конечно, вы можете создать собственное решение.
Относительно производительности: большинство библиотек JS используют анимацию для выполнения анимации, которая обычно более производительна, чем фиксированные шаги. Это определенно выглядит более плавно для пользователя, потому что позиция зависит от пройденного времени , а не от количества пройденных шагов .
Надеюсь, это поможет. : -)