Как я могу принудительно переформатировать после изменения DHTML в IE7?

У меня есть страница, на которой пользователь может динамически добавлять поля для загрузки файлов. Добавление блоков изменяет высоту div, в котором они находятся, но некоторые элементы div под ним остаются на том же месте, поэтому они начинают перекрываться с новыми элементами DOM.

Это корректно работает в IE8, Firefox, Chrome. Как я могу заставить IE7 переформатировать страницу с помощью нового DHTML?

Лучшее решение, которое я разработал, было следующим:

window.resizeBy(1, 0); 
setTimeout(UndoResize, 0);

Но это не работает с развернутым окном (восстанавливает окно).


person Freewalker    schedule 09.11.2009    source источник


Ответы (2)


Пытаться:

element.className = element.className;

на модифицированном div (или, возможно, на его родительском элементе или даже на более удаленном предке, в зависимости от различных факторов, таких как относительное позиционирование).

Поскольку className было присвоено значение, IE будет переформатировать и перерисовывать эту часть страницы в случае изменения CSS, влияющего на этот элемент. К счастью, он не оптимизирован для проверки того, действительно ли значение className изменилось по сравнению с его предыдущим значением, поэтому приведенное выше вызовет перекомпоновку, не нарушая ничего другого.

Я нашел один случай, когда этот исправленный IE6 сломал IE7, но попробуйте и посмотрите, сработает ли он для вас.

person NickFitz    schedule 09.11.2009
comment
Да! Эта проблема затрагивает элементы сразу под телом, поэтому я использую: document.body.className = document.body.className; Спасибо! - person Freewalker; 09.11.2009
comment
Это конкретно для IE? Например, вызывает ли это решение перекомпоновку в других браузерах, отличных от IE? Меня интересует соотношение цена/качество. - person Matt Kocaj; 12.07.2011
comment
@cottsak: Насколько мне известно, это будет иметь аналогичный эффект во всех (текущих) браузерах - на самом деле, я впервые понял эту идею из статьи на сайте Opera для разработчиков. Этот метод также упоминается в WAI-ARIA Primer W3C, раздел 3.1 w3.org/TR/2010/WD-wai-aria-primer-20100916/#exampletree — может потребоваться переключить имя класса или иным образом заставить браузер правильно перерисовать стили. - person NickFitz; 12.07.2011
comment
@Ник Фитц Кул. Итак, я могу предположить, что, поскольку Chrome и Firefox в этом мире не падают и не горят, как IE, что их производительность не пострадает от запуска этого без разбора? - person Matt Kocaj; 13.07.2011
comment
@Freewalker: document.body.className += ''; :) - person Steve Clay; 14.09.2011

Я только что потратил невероятное количество времени на эту абсолютно нелепую ошибку (проявляющуюся только в IE7), на веб-странице, слишком сложной для размещения кода здесь, где element.className = element.className не работал.

Окончательное решение для IE7 (ну, протестировано, по крайней мере, в том месте, где я столкнулся с ошибкой), кажется, выполняет ВСЕ строки ниже в качестве ловушки для любых изменений DOM:

try{
    element.parentNode.style.cssText += "";
    element.parentNode.style.zoom = 1;
    element.style.cssText += "";
    element.style.zoom = 1;
}catch(ex){}

Первые две строки (окруженные try-catch) уже давно есть в нашем фреймворке, но в каком-то конкретном случае их оказалось недостаточно, но добавление следующих двух исправило это.

Проверено как в развернутом, так и в не развернутом окне.

try/catch на месте, потому что в некоторых определенных обстоятельствах (например, внутри iframe) он может генерировать ошибку JS, которая сломает приложение (это информация от моего коллеги по команде, я сам с этим не сталкивался).

Наоборот, для IE8 element.className = element.className, кажется, делает свою работу (да, мы все любим условный код для каждой версии...)

Я люблю Win XP как операционную систему, но пока люди, привязанные к IE, не используют ее, нам приходится искать грязные исправления таких сумасшедших проблем... Чертовски грустно.


Изменить 2013.03.05

Фрагмент выше, похоже, работает в большинстве сценариев, но его недостаточно в одном месте. Теперь у нас есть такие вещи в нашем коде:

try {
    var s1 = domElt.parentNode.style, s2 = domElt.style;
    var dummyCss = "foo:foo;"; // do not add leading ';' here!
    s1.cssText += "";
    s1.zoom = 1;
    s2.cssText += dummyCss;
    s2.cssText = s2.cssText.replace(dummyCss, "");
} catch (ex) {}
person jakub.g    schedule 16.05.2012