Odświeżanie DOM przy długiej pracy

Mam przycisk, który uruchamia długą funkcję po kliknięciu. Teraz, gdy funkcja jest uruchomiona, chcę zmienić tekst przycisku, ale mam problemy w niektórych przeglądarkach, takich jak 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";
}

Teraz ma to problemy w Firefoksie i IE (w Chrome działa dobrze)

Więc pomyślałem, żeby to umieścić w rozliczeniu:

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);
}

ale to nie działa ani dla Firefoksa! przycisk zostaje wyłączony, zmienia kolor (dzięki zastosowaniu nowego css), ale tekst się nie zmienia.

Muszę ustawić czas na 50ms zamiast tylko 0ms, aby to działało (zmień tekst przycisku). Teraz uważam to za głupie. Mogę zrozumieć, czy zadziałałoby to z opóźnieniem 0ms, ale co by się stało na wolniejszym komputerze? może firefox będzie potrzebował 100 ms w programie rozliczeniowym? to brzmi dość głupio. Próbowałem wiele razy, 1 ms, 10 ms, 20 ms ... nie, nie odświeży go. tylko z 50ms.

Więc zastosowałem się do wskazówek w tym temacie:

Wymuszanie odświeżania DOM w Internet Explorerze po manipulacji javascript dom

więc spróbowałem:

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";
}

ale to nie działa (FIREFOX 21). Potem spróbowałem:

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);
}

Próbowałem nawet clientHeight zamiast offsetTop, ale nic. DOM nie jest odświeżany.

Czy ktoś może zaoferować niezawodne rozwiązanie, najlepiej nie hacky?

z góry dziękuję!

jak sugerowałem tutaj, próbowałem też

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

bezskutecznie

Wymuś odświeżanie / odświeżanie DOM w Chrome / Mac

TL; DR:

szukanie NIEZAWODNEJ metody między przeglądarkami, aby wymusić odświeżenie DOM BEZ użycia setTimeout (preferowane rozwiązanie z powodu różnych wymaganych odstępów czasu w zależności od rodzaju długiego kodu, przeglądarki, szybkości komputera i setTimeout wymaga od 50 do 100 ms w zależności od w sytuacji)

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

questionAnswers(11)

yourAnswerToTheQuestion