2009-09-09 3 views
24

Hier ist die Situation. Ich habe einige Javascript, das wie folgt aussieht:Erzwingen einer DOM-Aktualisierung im Internet Explorer nach Javascript Dom Manipulation

function onSubmit() { 
    doSomeStuff(); 
    someSpan.style.display="block"; 
    otherSpan.style.display="none"; 
    return doLongRunningOperation; 
} 

Als ich dies eine Form Aktion einreichen machen, und es aus einem nicht-IE-Browser ausführen, es schnell die zwei Spannweiten Sichtbarkeit austauscht und den langen Javascript-Betrieb laufen. Wenn ich dies in IE mache, macht es den Swap erst, nachdem onSubmit() vollständig zurückgegeben wurde.

ich ein dom neu gezeichnet durch Kleben eine Warnung zwingen kann, in etwa so:

function onSubmit() { 
    doSomeStuff(); 
    someSpan.style.display="block"; 
    otherSpan.style.display="none"; 
    alert("refresh forced"); 
    return doLongRunningOperation; 
} 

Auch die offensichtliche jquery Refactoring hat keinen Einfluss auf das Verhalten IE:

function onSubmit() { 
    doSomeStuff(); 
    $("#someSpan").show(); 
    $("#otherSpan").hide(); 
    return doLongRunningOperation; 
} 

Dieses Verhalten gibt es auf IE8 und IE6. Gibt es trotzdem ein neues DOM in diesen Browsern zu erzwingen?

+0

Erstens, was Sie in der longRunningOperation tun? –

+0

Haben Sie versucht, die Sichtbarkeitsfunktion auf ihre eigene Funktion zu verschieben? – seth

+0

longRunningOperation führt Formularvalidierung durch. Die Form ist in einer kleinen Teilmenge von Fällen groß. –

Antwort

2

Kann Ihr longRunningOperation asynchron aufgerufen werden?

+1

Sie haben recht, aber mit etwas Arbeit. Ich habe die lang andauernde Operation asynchron aufgerufen, hatte mein submit-Ereignis den Wert false zurückgegeben, und das Async-Ereignis sendet wirklich mein Formular. Dies führte zu korrektem Verhalten in allen Browsern, erforderte jedoch viel Arbeit und fühlt sich irgendwie klugig an. –

+1

Es mag sich klugig anfühlen, aber das beste Design der Client-Seite Ihrer App wird so aussehen, dass der Browser reaktionsbereit bleibt. Wenn Sie lange laufende Prozesse starten, hängen Sie den Browser (großes NEIN!), So dass es am besten ist, die Zeit damit zu verbringen, zu entwerfen, wie asynchrone Operationen verwaltet werden. Wie auch immer .. viel Spaß! – misteraidan

17

Mozilla (vielleicht auch IE) speichert/verzögert die Ausführung von Änderungen am DOM, die sich auf die Anzeige auswirken, so dass es alle Änderungen auf einmal und nicht wiederholt nach jeder Anweisung berechnen kann.

Um ein Update zu erzwingen (um einen sofortigen, synchronen Reflow oder Relayout zu erzwingen), sollte Ihr Javascript eine Eigenschaft lesen, die von der Änderung betroffen ist, z. der Speicherort von someSpan und anderenSpan.

(Dieses Mozilla Implementierungsdetail ist Faster HTML and CSS: Layout Engine Internals for Web Developers im Video erwähnt.)

+0

interessant. Ich wusste das nicht. –

+0

Ich werde das im AM versuchen. –

+0

Ich habe das versucht, konnte es aber nicht zum Laufen bringen. –

3

Sie können Ihre Langzeitfunktion auch in ein setTimeout (function() {longTerm();}, 1);

6

fortzusetzen, was ChrisW sagt:

hier Skript Spülung DOM zu blinken, so müssen Sie Alarm nicht nennen („“); (Bei http://amolnw.wordpress.com/category/programming/javascript/ gefunden):

function flushThis(id){ 
    var msie = 'Microsoft Internet Explorer'; 
    var tmp = 0; 
    var elementOnShow = document.getElementById(id); 
    if (navigator.appName == msie){ 
     tmp = elementOnShow.parentNode.offsetTop + 'px'; 
    }else{ 
     tmp = elementOnShow.offsetTop; 
    } 
} 

Es funktioniert für mich !!! Danke für den Tipp.

5

Ich hatte dieses Problem in Chrome 21 Ziehen eines Wortes, das einen Buchstaben mit einem Abseiler ('g') hatte. Es hinterließ eine Spur von Mottenstaub auf dem Bildschirm, die verschwinden würde, wenn das nächste Mal etwas den Bildschirm auffrischen würde. ChrisWs Lösung (Abfragen einer layout-sensitiven Eigenschaft) funktionierte nicht.

Was Arbeit tat, war eine 1-Pixel leer div am oberen Ende der Seite hinzuzufügen, ist es dann später eine Millisekunde zu entfernen, um am Ende der Ziehoperation die folgenden Aufruf die Funktion:

// Needed by Chrome, as of Release 21. Triggers a screen refresh, removing drag garbage. 
function cleanDisplay() { 
    var c = document.createElement('div'); 
    c.innerHTML = 'x'; 
    c.style.visibility = 'hidden'; 
    c.style.height = '1px'; 
    document.body.insertBefore(c, document.body.firstChild); 
    window.setTimeout(function() {document.body.removeChild(c)}, 1); 
} 

Hinweis: Sie benötigen die Verzögerung. Das Hinzufügen und Entfernen der div funktioniert nicht. Außerdem muss div über den Teil der Seite hinzugefügt werden, der neu gezeichnet werden muss.

+0

War diese Lösung besser als nur asynchron die Funktion aufzurufen? –

+0

Hatte ein Problem mit einer Bildschirmaktualisierung in IE10 und dies hat den Trick, im Gegensatz zu den anderen. –

+1

IE8 hier. Dies ist die einzige Lösung, die für mich funktioniert hat. Vielen Dank. –

1

element.focus() funktioniert für mich in IE10

function displayOnOff(){ 
    var elm = document.getElementById("myDiv"); 
    elm.style.display="block"; 
    elm.focus(); 
    for(var i=0; i<1000000; i++){ 
     console.log("waiting..............."); 
    } 
    elm.style.display = "none"; 
} 
Verwandte Themen