Показать сообщение отдельно
  #1 (permalink)  
Старый 18.08.2011, 10:24
Аспирант
Отправить личное сообщение для RUVATA Посмотреть профиль Найти все сообщения от RUVATA
 
Регистрация: 08.02.2011
Сообщений: 41

Принудительный рендеринг, отрисовка, redraw, reflow ; во время работы с COM(ActiveX)
Всем доброго времени суток...
Проблема истрепала кучу нервов и времени, потому хочу поделиться соображениями, частичным решением, найденным материалом, дабы столкнувшиеся не корячились как я.

Все началось с того, что клиентской части внутреннего сайта понадобилась работа с Excel на конечном компе юзверя, подумав, почитав, решили в пользу IE + ActiveX, а для филиалов не имеющих доступ к внутреннему сайту передать сие творение в виде *.hta (HTML Application) (типо убиваем двух зайцев )
(тем более прецедент уже есть - система "Контур Экстерн" которая только в IE и работатет)

Ну вот и понеслась... логику отработали быстро, опыт COM-взаимодействия с Excel благо богатый, с JavaScript тоже проблем не имеем.
Вот казалось бы и все, логика выполняется верно на связках:
WinXP+IE8, Win7+IE8, Win7+IE9 (как в виде страницы сайта с разрешения юзверя, так и в виде *.hta приложения)
Расчеты, чтение/заполнение таблиц, работа с файловой системой занимают от 5-6 до 15-20 сек, так что было решено анимировать процесс, дабы было видно что идет обработка. И тут началось...
Пошли по классическому пути через setTimeout, setInterval, после нескольких неудач решили особо не мудрить - разбили логику на несколько последовательных функций, между которыми и будет происходить некая анимация - изменяться текст в
<textarea id='satus'>Здесь будет статус выполнения</textarea>

модель такая:
myAnimation('выполняется myFunction1')
myFunction1()
    myAnimation('выполняется myFunction2')
myFunction2()
    myAnimation('выполняется myFunction3')
myFunction3()
    myAnimation('выполняется myFunction4')
myFunction4()
    myAnimation('выполняется myFunction5')
myFunction5()
    myAnimation('выполняется myFunction6')
myFunction6()
    myAnimation('Готово')

function myAnimation(text){
var element = document.getElementById("status");	
element.value = text
};

и что вы думаете ?
все myFunction*() успешно выполняются одна за одной... а вот в 'satus' отрисовывается только 'выполняется myFunction1'... и висит, потом когда все расчеты закончатся быстро мелькает 'выполняется myFunction6' и 'Готово'
Часы "гугления", с десяток постов на разных форумах, все без толку.
Вроде все должно работать... а не не работает.
Так вот ИСТИНА !!! :
Это особенность "осла", как только осел начинает работать с COM-компонентами, он в целях повышения производительности
вырубает весь автоматический рендеринг(обоход DOM мол слишком дорогое удовольствие во время работы с COM), и пока объект "захвачен" без пинка ничего отрисовывать не станет...
как же дать ему "пинка"!
вот здесь, представлен такой список свойств елемента, обращение к которым вызовет принудительный reflow&redraw:
Цитата:
1. offsetTop, offsetLeft, offsetWidth, offsetHeight,
2. scrollTop/Left/Width/Height,
3. clientTop/Left/Width/Height,
4. getComputedStyle() или currentStyle в IE.
так вот... в нашем случае (работа с COM) currentStyle, который Вам везде будут советовать и к нему Вас приведет гугление - НЕ СРАБОТАЕТ НИ В ОДНОМ IE!!!
В IE8, IE9 (в виде html, на XP или Win7, и только на Win7 в виде *.hta) - нам помогут свойства и 1-го пункта
т.е. изменив функцию таким образом:
function myAnimation(text){
var element = document.getElementById("status");	
element.value = text
element.offsetHeight
};

мы добьёмся анимации...
для *.hta в WinXP даже такой трюк не срабатывает
хотя здесь представлено несколько иных способов, в том числе и среди коментов предлагают
Цитата:
I use the following:

elm.style.display=”none”;
var redrawFix = elm.offsetHeight;
elm.style.display=”block”; // or other value if required

This works in all browsers I have needed it for – Opera, Konqueror, Safari and IE (including IE8 RC1 for which I just needed a redraw fix too). I haven’t ever needed it for Firefox though..
ни один не работает для *.hta на WinXP... для этой связки я так и не нашел решения.
Ответить с цитированием