Скрытие и открытие элементов на странице Javascript'ом - вещь довольно обыденная, казалось бы. Но и тут есть пара маниакальных тонкостей, о которых мало кто вспоминает.
Хочу поделиться своим опытом реализации "доступных немигающих динамических скрытых блоков через раннее внедрение в CSS проверки на Javascript".
С этим самым скрытием есть такая проблема: если элементы на странице изначально скрыты (CSS'ом), то для браузера без Javascript'а этот контент становится недоступен. Тут же напрашиваются два варианта решения проблемы:
"Ну и кто сейчас работает без JS?" В общем-то, точка зрения понятна, но во-первых, есть такие юзеры, а во-вторых, я обычно люблю делать вещи хорошо, если есть возможность. Поэтому этот вариант отпадает.
Оставить элементы по умолчанию открытыми, а потом уже самим Javascript'ом скрыть. Таким образом, у людей без JS все будет видно, а у остальных - все будет работать, как задумано.
Но вот этот второй вариант содержит подвох, который заключается в этом слове "потом". На практике "потом" означает событие OnLoad, в котором все эти скрытия и производятся. И при достаточно немаленькой страничке и достаточно рваном коннекте становится заметен гадкий визуальный эффект: на страницу грузится тонна мусора, а потом в какой-то момент это скачком исчезает. Yikes!
Чтобы это обойти, в принципе можно вставлять вызов функции сворачивания в код страницы после каждого объекта, который надо свернуть. В итоге, при достаточно неединичном количестве таких блоков мы получаем кучу:
<div id="....">.....</div>
<script type="text/javascript">document.getElementById('....').style.display='None';</script>
... раскиданных по всему коду. Yikes!
Так вот, если вам это не нравится так же, как и мне, вот вариант, к которому я в итоге пришел.
Обычно я стараюсь выносить Javascript во внешние файлы: так с ним удобней работать. И обычно в процессе работы над проектом так или иначе появляется .js-файлик, в котором лежат общие для всех файлов функции. И обычно он подключается в самом начале файла, но после открывающего <body> (позже объясню, почему так). Такая же ситуация и с CSS-файлами: обычно есть главный общий файл, который присутствует на всех страницах.
В главный js-файлик я вставляю такую простую строчку:
document.body.className+=' js';
Таким образом, к body в самом начале загрузки страницы добавляется класс 'js'. И его теперь можно использовать в CSS'е, где он работает как признак "Javascript включен", потому что если нет Javascript'а, то он и не назначится.
Теперь должно быть понятно, почему скрипт вставляется после тега, а не на пару строчек раньше: парой строчек раньше еще никакого body у документа не существует, и вы получите ошибку.
Дальше для всех элементов, которые хочется иметь скрытыми, дописывается class="hidden". Если там класс уже есть, то hidden можно дописать через пробел: классов может быть сколько угодно. А в главный CSS пишется простое правило скрытия элементов:
.js .hidden {
Display:None;
}
Это правило сработает для любого элемента с классом hidden, находящегося внутри элемента с классом js. Как раз наша ситуация! А поскольку CSS соврменные браузеры применяют к элементам как только они считываются, то это скрытие будет работать мгновенно, без всяких перемигиваний, так как класс js для body мы проставили в самом начале загрузки страницы, а hidden стоит прямо на элементах.
Впоследствие эти элементы вы можете скрывать-открывать любыми методами, которые вам нравятся.
Теперь осталось объяснить невообразимое название, которым я в начале статьи "наградил" этот подход:
Надеюсь, окажется полезным!
Комментарии: 10
Адищев Евгений
28.07.05 14:47
Здорово!
Действительно очень изящно. Уже прикрутил на своём сайте.
Александр Шугард
5.08.05 01:55
Любопытный подход. Спасибо. Возьму на заметку.
Weblog by Dmitry Kuznetsov | Дмитрий Кузнецов: веблог » o KAK!
1.02.06 19:02
[...] Изящное динамическое скрытие элементов с помощью CSS. Собственно, это стоит почитать. [...]
Денис Брюхов
30.04.06 15:39
Иван, был бы очень признателен, думаю не я один, если бы вы выложили небольшой пример для иллюстрации вашего подхода. Спасибо.
Иван Сагалаев
30.04.06 16:27
Как-то не подумал, что он понадобится :-).
Но вот, пожалуйста: http://softwaremaniacs.org/blog/wp-content/js-hidden/
Nab
30.04.06 17:10
Изящно, и красиво, а еще можно было бы чтоб не зависеть от места вставки, сделать функцией, на определение наличия body с небольшой задержкой, ну и потом уже добавлять ему js...
http://consolamentor.livejournal.com/
10.02.08 00:44
А я как дурак хотел сделать именно через OnLoad. Хорошо, что гугл вывел на вашу статью!
Спасибо, это решение намного лучше!
Муркт
10.02.08 11:59
Спасибо предыдущему комментатору за комментарий, я увидел его в РСС, и прочёл про этот замечательный метод :)
Иван Сагалаев
10.02.08 13:12
Работают, значит, комментарии :-). Хорошо :-)
irium
19.05.08 19:05
Действительно, очень изящное и красивое решение!
Сразу видно, что его придумал человек с ПРАВИЛЬНЫМ программистским мышлением, а не верстальщик-гуманитарий :)