Обновление DOM при длительной работе

У меня есть кнопка, которая запускает функцию длительного запуска, когда она нажата. Теперь, когда функция работает, я хочу изменить текст кнопки, но у меня возникают проблемы в некоторых браузерах, таких как Firefox, IE.

HTML:

<button id="mybutt" class="buttonEnabled" onclick="longrunningfunction();"><span id="myspan">do some work</span></button>

JavaScript:

function longrunningfunction() {
    document.getElementById("myspan").innerHTML = "doing some work";
    document.getElementById("mybutt").disabled = true;
    document.getElementById("mybutt").className = "buttonDisabled";

    //long running task here

    document.getElementById("myspan").innerHTML = "done";
}

Теперь это имеет проблемы в Firefox и IE, (в Chrome все работает нормально)

Поэтому я подумал о том, чтобы поместить это в установленное время:

function longrunningfunction() {
    document.getElementById("myspan").innerHTML = "doing some work";
    document.getElementById("mybutt").disabled = true;
    document.getElementById("mybutt").className = "buttonDisabled";

    setTimeout(function() {
        //long running task here
        document.getElementById("myspan").innerHTML = "done";
    }, 0);
}

но это не работает ни для Firefox! кнопка отключается, меняет цвет (из-за применения нового CSS), но текст не меняется.

Я должен установить время 50 мс, а не просто 0 мс, чтобы заставить его работать (измените текст кнопки). Теперь я нахожу это глупым по крайней мере. Я могу понять, будет ли это работать с задержкой 0 мс, но что произойдет в более медленном компьютере? может быть, Firefox потребуется 100 мс в установленное время? это звучит довольно глупо. Я пробовал много раз, 1 мс, 10 мс, 20 мс ... нет, это не обновит. только с 50мс.

Поэтому я последовал совету в этой теме:

Принудительное обновление DOM в Internet Explorer после манипуляций с javascript dom

поэтому я попробовал:

function longrunningfunction() {
    document.getElementById("myspan").innerHTML = "doing some work";
    var a = document.getElementById("mybutt").offsetTop; //force refresh

    //long running task here

    document.getElementById("myspan").innerHTML = "done";
}

но это не работает (FIREFOX 21). Тогда я попробовал:

function longrunningfunction() {
    document.getElementById("myspan").innerHTML = "doing some work";
    document.getElementById("mybutt").disabled = true;
    document.getElementById("mybutt").className = "buttonDisabled";
    var a = document.getElementById("mybutt").offsetTop; //force refresh
    var b = document.getElementById("myspan").offsetTop; //force refresh
    var c = document.getElementById("mybutt").clientHeight; //force refresh
    var d = document.getElementById("myspan").clientHeight; //force refresh

    setTimeout(function() {
        //long running task here
        document.getElementById("myspan").innerHTML = "done";
    }, 0);
}

Я даже попробовал clientHeight вместо offsetTop, но ничего. DOM не обновляется.

Может ли кто-нибудь предложить надежное решение, желательно не хакерское?

заранее спасибо!

как предложено здесь я также пытался

$('#parentOfElementToBeRedrawn').hide().show();

но безрезультатно

Принудительная перерисовка / обновление DOM на Chrome / Mac

TL; DR:

поиск надежного кросс-браузерного метода для принудительного обновления DOM без использования setTimeout (предпочтительное решение из-за различных временных интервалов, необходимых в зависимости от типа длинного кода, браузера, скорости компьютера и setTimeout, от 50 до 100 мс в зависимости по ситуации)

jsfiddle:http://jsfiddle.net/WsmUh/5/

Ответы на вопрос(11)

Ваш ответ на вопрос