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

Здесь ситуация. У меня есть некоторые JavaScript, который выглядит так:

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

Когда я делаю это действие отправки формы и запускаю его из браузера, отличного от IE, он быстро меняет видимость двух диапазонов и запускает длинную операцию JavaScript. Если я делаю это в IE, он не выполняет своп до тех пор, пока onSubmit() полностью не вернется.

Я могу принудительно перерисовать дом, вставив окно предупреждения следующим образом:

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

Кроме того, очевидный рефакторинг jquery не влияет на поведение IE:

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

Такое поведение существует в IE8 и IE6. Есть ли способ принудительно перерисовать DOM в этих браузерах?

6 ответов

Решение

Может ли ваша longRunningOperation вызываться асинхронно?

Mozilla (возможно, также IE) будет кэшировать / задерживать выполнение изменений в DOM, которые влияют на отображение, так что он может рассчитывать все изменения сразу, а не многократно после каждого оператора.

Для принудительного обновления (для принудительного немедленного, синхронного перекомпоновки или ретрансляции) ваш javascript должен прочитать свойство, на которое повлияло изменение, например расположение someSpan и otherSpan.

(Эта деталь реализации Mozilla упоминается в видео " Быстрее HTML и CSS: Внутренние компоненты движка Layout для веб-разработчиков".)

Чтобы продолжить то, что говорит ChrisW:

вот сценарий очистки для прошивки DOM, поэтому вам не нужно вызывать alert(""); (находится по адресу http://amolnw.wordpress.com/category/programming/javascript/):

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

Меня устраивает!!! Спасибо за чаевые.

У меня была эта проблема в Chrome 21 при перетаскивании слова с буквой по убыванию ('g'). Он оставлял на экране след от мотылька, который исчезал в следующий раз, когда что-то заставляло экран обновляться. Решение ChrisW (опрос свойства, чувствительного к макету) не сработало.

Что сработало, так это добавление пустого div в 1 пиксель вверху страницы, а затем удаление его через миллисекунду, вызвав следующую функцию в конце операции перетаскивания:

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

Примечание: вам нужна задержка. Просто добавляя и удаляя div не работает Так же div должен быть добавлен над той частью страницы, которая должна быть перерисована.

Вы также можете обернуть свою долгосрочную функцию в setTimeout(function(){longTerm();},1);

element.focus() у меня работает в 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";
}
Другие вопросы по тегам