IE, select, z-index: танцы с бубном
Сегодня столкнулся с офигенной корявостью Эксплорера. Задача, как казалось была тривиальной: надо было в начале загрузки файлов на сервер закрыть экран полупрозрачной пеленой, чтобы пользователь не тыкал куда не надо. Решение, упрощенно, было такое: создавался div с "position: absolute", покрывающий рабочую область, затем он выдвигался вперед за счет z-index, и устанавливалась прозрачность. Потом, при завершении загрузки элемент скрывался. Все бы не чего, но Internet Explorer, как обычно отличился. Наблюдался обалденный эфект, через "пелену" выступали все элементы select. Их невозможно было задвинуть на задний план при помощи изменения значения z-index.
Суть проблемы заключается в том, что IE по-особому работает с z-index. Он считается в пределах одного контейнера, а если элементы принадлежат разным контейнерам, то их z-index никак не будет пересекаться. Я перерыл кучу топиков в поисках решения проблемы, в основном советовали просто поместить элементы в один контейнер и расставить им нужный z-index, но этот вариант мне не подходил, так как эти элементы располагались в разных местах документа и никак не зависели друг от друга.
Спустя около четырех часов копания, я наткнулся на сногсшибательное решение! Это просто магия, шаманство, танцы с бубном. Как до такого решения можно дойти самостоятельно я не представляю, это надо перелистать весь MSDN как минимум! Вот так должен выглядеть ваш div, чтобы никакие select'ы в Эксплорере не пролезали через него:
<style>
.select-free {
position:absolute;
z-index:10;/*any value*/
overflow:hidden;/*must have*/
width:33em;/*must have for any value*/;
}
.select-free iframe {
display:none;/*sorry for IE5*/
display/**/:block;/*sorry for IE5*/
position:absolute;/*must have*/
top:0;/*must have*/
left:0;/*must have*/
z-index:-1;/*must have*/
filter:mask();/*must have*/
width:3000px;/*must have for any big value*/
height:3000px/*must have for any big value*/;
}
</style>
<div class="select-free">
your content here
<!--[if lte IE 6.5]><iframe></iframe><![endif]-->
</div>
Ребята с HedgerWow.com, респект вам и уважуха!

24 comments:
Только нужно осторожно использовать размер ифрейма. Если тупо как в примере - 3000px Х 3000px, то IE6 у клиента при отображениии вашей страницы отъест 90 мб. Если ифреймов несколько, то на машине с не очень большой памятью начнуться жуткие тормоза при отображении вашей страницы.
Обязательно учту. Большое спасибо!
Вместо 3000px можно написать 100% и памяти меньше жрет, и зависит уже от размера окна браузера.
А создать новый div через DOM с document.body как родительской веткой не вариант?
или я что-то не допонял?
Я уже не помню какие варианты я пробовал, чтобы решить эту проблему. Долго мучился, нашел вот этот вариант, он-то меня и спас.
Предыдущий пост был мой.
Я с таким эффектом столкнулся когда хотел сделать хинт над некоторыми словами. Казалось бы что сложного сделать скрытый div рядом со словом, а при наведении мыши его показать... сволочь ie с упорством прорисовывал картиночки с других div'ов поверх хинта. плюнул написал:
«body»«div id="hint"»«/div»...
...
«span onmouse...»Слово«/span»«div class="hidden"»Подсказка«/div»
...
«/body»
над нужным словом show_hint + position + hint.innerHTML=hidden.innerHTML
работает везде, результатом доволен.
А над элементами select нормально все?
На странице с хинтами у меня не было элементов select. про них не знаю, но раз у тебя они вылезали, то не вижу причины почему бы они у меня не вылезли.
А, кажется, до меня дошёл твой последний вопрос. Ты наверно не внимательно посмотрел мой пост: в результате всплывает div c id="hint" а ему передаётся текст из скрытого дива. а т.к. id="hint" имеет родителя body, то при z-index > других элементов на странице, он всегда наверху.
<html>
<body><style type="text/css">
.hint {
display: none;
}
#hint {
background: #FFFFE1;
border: 1px solid #AAAAAA;
margin-top: 1em;
margin-left: 1em;
opacity: 0.85;
* filter:alpha(opacity=85);
padding: 3px;
position: absolute;
text-align: left;
visibility: hidden;
width: 330px;
}
.h {
color:red;
}
</style>
<script type="text/javascript">
NS = ((navigator.appName=="Netscape") || (navigator.appName=="Opera")) ? true : false;
hint = false;
function show_hint(sender, hint_id, visible)
{
if (!hint)
hint = document.getElementById('hint');
if (visible)
{
var _hint = document.getElementById(hint_id);
hint.innerHTML = _hint.innerHTML;
attach_event(sender, 'mousemove', move_hint);
hint.style.visibility = 'visible';
}
else
{
hint.style.visibility = 'hidden';
hint.innerHTML = '';
detach_event(sender, 'mousemove', move_hint);
}
return true;
}
function move_hint(event)
{
hint.style.left = (NS ? event.pageX : event.x) + 'px';
hint.style.top = (NS ? event.pageY : event.y + document.documentElement.scrollTop + document.body.scrollTop) + 'px';
}
function attach_event(sender, event, func)
{
if (sender.addEventListener)
return sender.addEventListener(event, func, false);
else
return sender.attachEvent('on'+event, func);
}
function detach_event(sender, event, func)
{
if (sender.addEventListener)
return sender.removeEventListener(event, func, false);
else
return sender.detachEvent('on'+event, func);
}
</script>
<div id="hint"></div>
<p>Текст Текст Текст <span class="h" onmouseout="show_hint(this, 'hint1', 0)" onmouseover="show_hint(this, 'hint1', 1)">Текст</span><span id="hint1" class="hint">Подсказка1</span> Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст</p>
<p>Текст Текст Текст <span class="h" onmouseout="show_hint(this, 'hint2', 0)" onmouseover="show_hint(this, 'hint2', 1)">Текст</span><span id="hint2" class="hint">Подсказка2</span> Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст</p>
<p>Текст Текст Текст <span class="h" onmouseout="show_hint(this, 'hint3', 0)" onmouseover="show_hint(this, 'hint3', 1)">Текст</span><span id="hint3" class="hint">Подсказка3</span> Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст</p>
</body>
</html>
Решил не разглагольствовать, а выдернуть код и отправить. Понравится оставь, не понравится - удали. Если будут вопросы - отвечу только завтра.
Для данной проблемы можно использовать библиотеку mootools.net .Весит граммы, а может сделать много полезных эффектов.
Только надо будет вынимать искусственно id дочерних элементов, если такие имеются.
Код будет выглядеть так:
//устанавливает прозрачность
new Fx.Style('tvoj_id','opacity').start(1,0.2);
//убирает прозрачность
new Fx.Style('tvoj_id','opacity').start(0.2,1);
А проще всего вынести этот div вперед всего кода до закрытия body - он будет отображаться как верхний слой.
Задать ему абсолютное положение и ширину\высоту - 100%, а там уже играться с яваскриптом.
Спасибо, SatiriK(rus). Попробую ваши рекомендация, как подвернется удобный случай.
Aleksey
если в Вашем коде некоторые слова "Текст" заменить на, скажем:
<select><option>qwer</option></select>
то, получается, суть вопроса этот код не решает...
Делаю немного по другому. просто прятаю селекты, когда надо показать див, а потом обратно ставлю им видимость.
Огромное спасибо, как раз то что нужно! Писал аяксовый чат и столкнулся с проблемой двиганий окошек поверх основного контента сайта.
This is great info to know.
Спасибо большое! Select-ы попрятались сразу под дивом!
Спасибо! действительно помогло. теперь справиться бы с дрожанием блока. дергаться он стал. посмотрю у Темы Лебедева, вродь там что то было.
Только мин 10 потратил на обдумывание что и как работает.
НО ГЛАВНОЕ - ТЫ ОЧЕНЬ ПОМОГ!
ЕЩЕ РАЗ СПАСИБО!
Превеликое спасибо! Великое спасение для маленьких всплывающих окошек :-)
Хотел уже просто прятать все select-ы:
$$('select').each(function(elt){
elt.style.display = 'none';
});
но погуглил "select z-index ie" и нашел решение )
// kirilloid
Хе-хе. Сейчас открыли оригинальный пример у коллеги — не работает. Хотя у него такая же версия IE, как и у меня:
6.0.2900.2180.xpsp_sp2_rtm.040803-2158
В общем, воспользуемся проверенным mootools-ом.
// снова kirilloid
Категорически благодарен автору. Угробил два часа на поиски решения пока не наткнулся на эту статью. Правда и с этим пришлось поморочиться, прикрутив к своим условиям. Я немного изменил код, т.к. у меня не полное закрывание экрана дивом, а всплывающая подсказка (соответственно, пришлось прописывать размеры).
У меня IE6.0.2900.2180.xpsp_sp2_rtm.040803-2158 Так же в 9 опере и фаерфоксе 3.5 пробовал, всё ок. А вообще, извиняюсь, может ссылки запрещены, но вот тут dynarch.com/mishoo/calendar.epl календарь при его перемещении умеет скрывать находящиеся под ним элементы... ессно, с выключенными скриптами не работает =) так-что решение с чистым css имеет право жить. Спасибо.
I found this site using [url=http://google.com]google.com[/url] And i want to thank you for your work. You have done really very good site. Great work, great site! Thank you!
Sorry for offtopic
Post a Comment