MooTools

индекс
138,77

Пример создания анимированного меню

В своей работе я часто сталкиваюсь с однотипными задачами. Для того чтобы не топтаться на одном месте, развиваться как разработчик, да и просто не скучать от однотипной работы, я придумываю небольшие фишки в проектах.
Так, при создании админки для одного из моих клиентов, я решил сделать анимированное меню при помощи фреймворка Mootools. В этой статье я расскажу, как создавалось меню и немного опишу функции и методы фреймворка, которые мне в этом помогли. Статья написана как для людей, которые только начинают изучение mootools, так и для тех, кто желает начать изучение этого фреймворка, но, возможно, не знают с чего начать.



Необходимо сразу отметить, что разговор о преимуществах данного фреймворка, а также о его недостатках останется за пределами этой статьи.

И так, для начала нам необходимо создать статическое меню. Вот мой вариант кода:

html

<div class="bord"></div>
<div class="head">
    <a class="headParagraph">Настройки</a>
    <a class="headParagraph">Разделы</a>
    <a class="headParagraph">Статьи</a>
    <a class="headParagraph">Галереи</a>
    <a class="headParagraph">Языки</a>
    <a class="headParagraphExit" href="#">Выход</a>
</div>

CSS

.head{
	margin: 0 auto;
	padding: 15px 20px 3px 20px;
	width: 90%;
	height: 17px;
}

.bord{
	border-top: 2px solid #000;
	top: 35px;
	left: 3%;
	width: 94%;
	position: absolute;
}

.headParagraph{
	float: left;
	margin-right: 40px;
	cursor: pointer;
	font-size: 16px;
	color: #444;
	margin-top: 0;
}

.headParagraphExit{
	float: right;
	cursor: pointer;
	text-decoration: none;
	color: #000;
	font-sizq: 20px;
}


Для создания эффекта “падающей” ссылки используется класс Fx.Morph, который позволяет изменять свойства элемента в рамках CSS.

Объявляется класс таким образом:

var myEffect = new Fx.Morph('myElement', {duration: 'long', transition: Fx.Transitions.Sine.easeOut});


Свойство duration может принимать значения long или short — это влияет на скорость выполнения эффекта(переход от одного значения свойства элемента к другому). Transition определяет вид анимации эффекта, подробнее со списком принимаемых значений этого свойства можно ознакомиться в официальной документации.

Для запуска эффекта нам необходимо объявить о том, какие свойства и как будут меняться в наших объектах. Для этого существует метод start, который и запускает эффект:

myEffect.start({
	'height': [10, 100],
	'width': [900, 300]
});


В этом примере наш элемент поменяет значение ширины и высоты — высота увеличится с 10px до 100px, а ширина уменьшится соответственно с 900px до 300px.
Возможно так же несколько других вариантов объявлений этого метода, например:

myEffect.start({
	'height': 100,
	'width': 300
});


или

myEffect.start('.myClassName');


В первом примере наш элемент поменяет свои свойства с текущих значений на те, что мы указываем в методе, а во втором случае актуальные на данный момент свойства поменяются на описанные в классе myClassName.

Итак, для того чтобы наши ссылки “падали“ и возвращались в первоначальное положение, создадим класс, который будет менять свойства margin-top и color наших ссылок, и назовем его selected.

.selected{
	margin-top: 25px;
	color: #000;
}


Теперь для того чтобы наша ссылка “падала”, необходимо применить к ней класс selected, а чтобы возвращалась в первоначальное — положение класс headParagraph.

Для обращения к нашим элементам меню можно воспользоваться одним из двух способов, предусмотренных в mootools — это либо обращение по id элемента, либо обращение к массиву элементов по имени класса, которому принадлежит элемент, или по имени тэга обращаемся в группе однотипных элементов.
В первом случае обращение к элементу выглядит как $(‘id_element’). Во втором случае $$(‘#tag_name.class’), $$(‘#tag_name’), $$(‘.class’) возвращает массив элементов соответствующих одному из условий.

В нашем случае будем использовать второй вариант обращения, для того чтобы получить массив элементов.

$$('.headParagraph').each(function(element, index){
	element.addEvent('click',function(){
		var myEffect = new Fx.Morph(element, {
                duration: 'short', 
                transition: Fx.Transitions.Elastic.easeInOut
                });
		myEffect.start('.selected');
		$$('.headParagraph').each(function(otherElement, otherIndex){
			if(element!=otherElement){
				var myOtherEffect = new Fx.Morph(otherElement, {
                                duration: 'short', 
                                transition: Fx.Transitions.Back.easeOut
                                });
				myOtherEffect.start('.headParagraph');
			}
		});
	});
});


Необходимо отметить, что конструкция $$('.headParagraph').each(function(element, index){...}); перебирает поочередно все элементы массива $$('.headParagraph'), присваивая переменной element значение текущего элемента массива, а переменной index — ключ этого элемента.
Разберем немного подробнее код, который я привел выше. Каждому элементу в цикле к событию onClick мы привязываем анимацию:

element.addEvent('click',function(){
    var myEffect = new Fx.Morph(element, {
        duration: 'short', 
        transition: Fx.Transitions.Elastic.easeInOut
    });
    myEffect.start('.selected');
    …
});


А конструкция

$$('.headParagraph').each(function(otherElement, otherIndex){
    if(element!=otherElement){
        var myOtherEffect = new Fx.Morph(otherElement, {
            duration: 'short', 
            transition: Fx.Transitions.Back.easeOut
        });
        myOtherEffect.start('.headParagraph');
    }
});


служит для того, чтобы при клике по одному из разделов нашего меню, тот раздел, который является на данный момент активным — возвращался в первоначальную позицию.

Конечный результат можно увидеть по этой ссылке.

Если у вас появятся какие-либо вопросы, с радостью готов на них ответить в комментариях или по хабрапочте. Ну а если читателей заинтересует данная тематика, то продолжение не заставит себя долго ждать.
+19
31 октября 2008, 14:41
34

комментарии (18)

0
xxicb #
Да, кстати, буду рад, если вы будете оставлять отзывы о качестве статьи (:
+1
neon #
У вас очень удачно получилось вписать длинную строку кода в дизайн хабра.
картинка большая, так что только ссылка
0
xxicb #
Ой, спасибо что сказали, сейчас же исправлю
0
neon #
А на моём мониторе и так отлично =)
0
xxicb #
На мем тоже было, я думал хабр автоматически перенесет строку )):
0
taliban #
а если запоминать выбранный элемент, то потом не надо будет бегать по всему меню =) а только ему поменять класс на «не выбранный»
0
bebopkid #
duration может быть задан не только как 'long' или 'short', но и в миллисекундах, естественно.
+1
sanch3z #
Html-код можно было «посемантичней» написать.
–2
AxL1232 #
А что в Вашем понятии «семантика» в вебе, позвольте поинтересоваться?
0
gentleman #
Читайте мат часть.

P.S. В данном случае — использование списка для навигации.
0
AxL1232 #
Читайте мат часть учите матчасть.
Я представляю себе что такое семантика, хоть и весьма смутно, а потому и прошу просвятить меня в этом вопросе. Почему-то все, кого ни спроси, отвечают в таком духе. А что дает эта семантика? И мне не интересны цитаты с википедии. Мне интересна практическая сторона этого вопроса. В частности: почему, например, навигация должна быть списком? Тем более в данном случае — это лишние данные, а следовательно и больший объем загружаемого файла. Это если один список такой ничего не заметно, а если их много больше?
0
gentleman #
Согласен с вашим недовольством. Для меня семантика — использование элементов разметки, название которых соответствует их содержанию. Вполне просто на мой взгляд. Ведь css позволяет сделать из того же «b» сделать ячейку таблицы или параграф, только вот зачем?

P.S. о целесообразности списков читайте ниже.
0
Usmekhaiouschiysia #
А вот интересно, почему навигации семантически близок список, а не, скажем, абзац?
Ссылки вроде бы идут списком? Ну так и абзацы, и главы идут списком, один за другим.
0
gentleman #
Отключите стили, например. При использовании списков вложенное меню будет отображаться вполне адекватно.
0
Usmekhaiouschiysia #
Угу, как идущие один за другим пункты с буллетами — это адекватно чему? Если заключать не в список, а в абзацы например — получатс идущий один за другим пункты без буллетов. Кроме буллетов — никакой разницы.
–2
garex #
2автор: «Итак», «также» // F7 в word`е.
0
tapin13 #
Спасибо! Все отлично!
Просто и понятно. Идея в упавшем меню тоже забавна.
+1
Yarc #
Отлично! Давайте же наполним блог MooTools качественными статьями.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.