Отказ от js как оптимизация js, часть 2
Предположим, у нас есть графическое меню на сайте. Нужно при наведении сменить изображение пункта на другое.
Эта задача для эпохи вебдваноля уже не так актуальна, мода на украшательства в навигации постепенно сходит на нет, но все-таки, если дизайнер решил, что в главном меню кровь-из-носа нужны выпукло-вогнутые плашки с Matisse ITC, что же делать в таком случае?
Ставшее почти классическим решение (вошедшее, среди прочего, в редактор Dreamweaver): по событию mouseover src у картинки меняется на нужный, по mouseout — обратно. Но вот беда, картинка еще не подгружена, а ее уже надо показать. Создаем объект Image и проталкиваем при его помощи в кеш изображение.
…полностью забывая про css и добавляя каши в код.
Избавиться от этого безобразия нам помогут так называемые спрайты. Чтобы понять, что это и чем именно помочь, опять начнем с основ css.
display — одно из важнейших свойств css, меняющее поведение элемента. Не вдаваясь (на этот раз) в дебри, лишь скажу, что задав ссылке display: block , мы можем заставить ее вести себя не как строчный элемент, а как блочный:
<style type="text/css">
a {
font-size: 24px;
background: aliceblue;
text-align: center;
}
a:hover {
background: navy
}
</style>
<a href="javascript://"> Я ссылка </a>
<a href="javascript://" style="display: block"> А я плашка </a>
Размеры активной области ссылки с display: block можно задавать явным образом через width и height , как и обычному диву. И как обычный див по умолчанию ссылка занимает всю доступную ширину. И то и другое нам на руку.
Рассмотрим другой пример и попутно избавимся от болезни некоторых навигационных меню (ну, например, в phpmyadmin), когда задник уже поменялся, но при щелчке не проиходит ничего, просто потому что на ссылку еще не навели.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
#menu {
border-collapse: collapse;
table-layout: fixed;
width: 100%;
}
#menu .menu-item {
padding: 0px;
border: solid black 1px;
}
#menu .menu-item a {
display: block; /* ! */
padding: 4px;
text-align: center;
background: aliceblue; /* ! */
text-decoration: none;
}
#menu .menu-item a:hover {
background: floralwhite; /* ! */
}
</style>
</head>
<body>
<table id="menu">
<tr>
<td class="menu-item"><a href="javascript://1">Lorem</a></td>
<td class="menu-item"><a href="javascript://2">Ipsum</a></td>
<td class="menu-item"><a href="javascript://3">Dolor</a></td>
<td class="menu-item"><a href="javascript://4">Sit</a></td>
<td class="menu-item"><a href="javascript://5">Amet</a></td>
</tr>
</table>
</body>
</html>
Ну а теперь, собственно, перейдем к озвученной проблеме. При наведении на ссылку можно менять положение ее фона при помощи background-position: x y; .
Сделаем что-то наподобие вот такого изображения:
Все, что нам нужно, это сделать это изображение фоном у всех нужных ссылок и у каждой из них показать лишь нужный фрагмент. И получится что-то вроде этого:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
#tpl-menu {
display: block;
padding: 0px; margin: 0px;
width: 440px; height: 50px;
}
#tpl-menu .tpl-menu-item {
float: left; /* display становится block автоматически */
display: inline; list-style: none outside; /* оба свойства — фиксы для IE6 */
padding: 0px; margin: 0px 5px;
width: 100px; height: 50px;
}
#tpl-menu .tpl-menu-item a {
display: block; /* ! */
height: 0px; padding: 50px 0px 0px 0px; overflow: hidden;
background: #f0f0f0 url(/files/u4363/sample-sprite.gif) 0px 0px no-repeat; /* ! */
}
#tpl-menu .tpl-menu-item-1 a {background-position: 0px 0px}
#tpl-menu .tpl-menu-item-1 a:hover {background-position: 0px -50px}
#tpl-menu .tpl-menu-item-2 a {background-position: -100px 0px}
#tpl-menu .tpl-menu-item-2 a:hover {background-position: -100px -50px}
#tpl-menu .tpl-menu-item-3 a {background-position: -200px 0px}
#tpl-menu .tpl-menu-item-3 a:hover {background-position: -200px -50px}
#tpl-menu .tpl-menu-item-4 a {background-position: -300px 0px}
#tpl-menu .tpl-menu-item-4 a:hover {background-position: -300px -50px}
</style>
</head>
<body>
<ul id="tpl-menu">
<li class="tpl-menu-item tpl-menu-item-1"><a href="javascript://1">Рыба</a></li>
<li class="tpl-menu-item tpl-menu-item-2"><a href="javascript://2">Мясо</a></li>
<li class="tpl-menu-item tpl-menu-item-3"><a href="javascript://3">Молоко</a></li>
<li class="tpl-menu-item tpl-menu-item-4"><a href="javascript://4">Масло</a></li>
</ul>
</body>
</html>
Как видите, ни грамма яваскрипта и использование одного графического файла вместо восьми (и отпавшая сама собой необходимость к принудительном кешировании), и при всем при этом еще и совместимость с текстовыми браузерами.
Ну, а если Вам нужно менять именно картинки, тоже нет ничего невозможного. Просто засовываем обе в одну ссылку, но показываем только одну. А при наведении — скрываем и показываем другую.
Но тут есть одно «но». В Опере, причем с незапамятных времен, изображения не подгружаются с сервера, если у них установлено display: none . Логично, или нет, но придется придумать другой способ скрывать изображения.
Для этого вспомним, что если у элемента position установлено в absolute , он не занимает места на странице. А еще то, что если элемент уходит за левую или верхнюю границу окна, полоса прокрутки не появляется (кроме некоторых версий Firefox 1.x, который, к счастью, уже отмер).
Итого имеем:
<style type="text/css">
a:hover .tpl-alternate-visible,
.tpl-alternate-hidden {
position: absolute;
left: -100000px; /* хватит? */
visibility: hidden; /* если не хватит */
}
a:hover .tpl-alternate-hidden,
.tpl-alternate-visible {
position: static;
visibility: visible;
}
</style>
<a href="javascript://">
<img class="tpl-alternate-visible" src="http://javascript.ru/forum/images/ca_serenity/misc/logo.gif" />
<img class="tpl-alternate-hidden" src="http://www.google.ru/logos/holiday09_3.gif" />
</a>
Правда, при просмотре без css мы увидим сразу два изображения. Обладатели медленного интернета и счастивые пользователи elinks, конечно, видели еще и не такое, но что же, нам их совсем не жалко?
Ну, вот, кажется, и все.
|
Элемент будет блочным несмотря на display:inline.
Хорошо, что Вы это заметили. Это неспроста.
Да, элемент будет блочным, и, казалось бы, свойство бесполезное, но IE6 благодаря этому считает флоаты правильно, т.е., без трехпиксельного отступа и удвоения ближнего поля.
margin назначается 2 раза.
Спасибо за внимательность!
Дописывал уже около трех часов ночи, и протупил. Сейчас удалю.
Во втором примере если курсор медленно проводить через границу рисунка, то изображения начинают ужасно прыгать (Firefox 3.5).
Изображения разного размера.
Соответственно, получается так: курсор наведен → картинка сменилась → курсор за картинкой, а, значит, уведен → картинка сменилась.
Уж извините за «грязный» пример. Но я думаю, я его оставлю как экспонат «как делать не стоит».
Кстати, Опера ведет себя по-другому в таких случаях — для нее смена :hover и курсора происходят только в случае, если курсор сдвинулся. Обычно это не нужно (хорошим тоном считается когда у пользователя ничего не убегает из-под курсора), но в маргинальных случаях следует это учесть.
Subzey, я тебе наверное уже показывал эту фиговину. Что скажешь про такую "оптимизацию js без js"? Есть две формочки и их надо, таксзть, тогглить по клику на ссылке. Я решил сделать так, чтобы тогглинг работал и без js, получилось как-то так:
http://ainop.ixth.net/examples/form/index2.html
Есть, правда, несколько больших "но":
Anonse erotyczne rzeszów
Roksa masaż krakow
Отправить комментарий
Приветствуются комментарии:Для остальных вопросов и обсуждений есть форум.