Как сделать перерисовку HTML-элемента в цикле Javascript? - PullRequest
4 голосов
/ 25 февраля 2009

У меня есть некоторый Javascript, который «оживляет» изменение цвета в элементе HTML следующим образом:

var element = document.getElementById("someid");
while (i < 255) {
    element.style.color = 'rgb(' + i + ',' + i + ',' + i + ')';
    i++;
    slowMeDown(); // This function runs for a few ms to slow the process down
}

Как видите, это меняет цвет с черного на белый, проходя через 255 оттенков серого между ними. Я бы хотел, чтобы он заметно «исчез», чтобы пользователь мог видеть, как текст постепенно исчезает.

Однако браузер (Chrome и IE - еще не тестировался на Firefox) обновляется только в конце функции, поэтому цвет просто меняется с черного на белый. Кто-нибудь знает, как сделать так, чтобы браузер перерисовывал во время цикла, чтобы я мог видеть текст исчезать?

Ответы [ 4 ]

9 голосов
/ 25 февраля 2009
function changeColor()
{
    changeColorIncremental(0);
}

function changeColorIncremental(i)
{
    var element = document.getElementById("someid");

    element.style.color = 'rgb(' + i + ',' + i + ',' + i + ')';

    if (i < 255) {
        // Note the 50 millisecond wait below.  Decrease this to speed up
        // the transition, and increase it to slow it down.
        setTimeout('changeColorIncremental(' + (i + 1) + ')', 50);
    }
}
3 голосов
/ 25 февраля 2009

Вы должны посмотреть в JQuery. Он сделает все это за вас, используя функции Effects или плагины.

Однако в ответ на вопрос:

Обычно веб-браузеры используют только один поток обновления пользовательского интерфейса, который также используется для выполнения кода Javascript. Поэтому браузер выполнит ваш цикл полностью и только после этого обновит страницу после ее завершения (т. Е. Все RGG = 255 255 255).

Попробуйте использовать window.setTimeout или window.setInterval для вызова функции, которая увеличивает значения RGB. Это позволяет потоку обновления пользовательского интерфейса браузера обновлять отображение после каждого вызова (между интервалом или тайм-аутом).

(Я полагаю, что все основные браузеры работают таким образом, включая Firefox).

Примечание: setInterval и setTimeout выполняют код в одном и том же потоке пользовательского интерфейса. Они просто добавляют обратный вызов таймера в цикл сообщений окна, и это вызывается и выполняется в правильное время.

Поэтому, если в то время выполнялся другой код Javascript или обновление пользовательского интерфейса, функция таймера должна ждать. Таким образом, функция не гарантируется в указанное время. Кроме того (в Windows) максимальное разрешение намного меньше 1 миллисекунды, часто около 1/20 секунды или около 50 миллисекунд.

2 голосов
/ 25 февраля 2009

Ваша функция slowMeDown () - плохой способ отложить вещи в Javascript. Причина в том, что реализации JS в браузерах являются однопоточными. Это означает, что одновременно выполняется только одна задача. Часто сам браузер «зависает» в ожидании завершения работы JS. Это то, что происходит в вашем случае - ваш цикл никогда не возвращает управление браузеру для фактического обновления элемента DOM.

Использование setTimeout () или setInterval (), как предложено некоторыми из других здесь, обходит это, возвращая управление потоком в браузер и запрашивая его перезвонить через указанное количество миллисекунд.

Кроме того, если вы намерены сделать так, чтобы текст исчез, рассмотрите возможность использования различных способов установить непрозрачность CSS (к сожалению, учитывая состояние поддержки браузера, вам придется установить три различных значения для объекта стиля) .

0 голосов
/ 25 февраля 2009

Я бы использовал colourChangeTimer = setInterval(function() { //colour change code }, 100);

Затем, после достижения значения 255 для всех значений, используйте clearTimeout(colourChangeTimer).

Извините за мое австралийское правописание.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...