Створюємо просте, розумне випадаюче меню з допомогою бібліотек Prototype і Scriptaculous

22

«Ми всі коли-небудь бачили меню у вигляді акордеона, ефектно смотрящих на сайтах Web 2.0, однак, безліч скриптів-«акордеонів» важкі, малокорисні для бібліотек, на яких засновані, і не забезпечують підбору висоти.»

Перед тим, як ми приступимо до практичних кроків, я Вам рекомендую завантажити вихідний код, щоб він був у Вас під рукою.

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

Крок 1 – Мета

Наше завдання – створити простий скрипт-«акордеон» на основі javascript-бібліотек Prototype і Scriptaculous. «Акордеон» повинен:

Підтримувати необмежену кількість випадаючих панелей

Бути повністю настроюється за допомогою CSS

Бути ненав’язливим – користувачі з вимкненим javascript повинні бачити весь вміст Вашого «акордеона»

Бути легковажним – з порівняно невеликим кодом, використовувати делегування для обмеження споживання пам’яті

Підтримувати будь-які види вмісту всередині

Гарантувати, що в разі перебору випадають панелей висота «баяна» залишиться сталою, що необхідно для уникнення дратівної ефекту «вистрибує сторінки»

Це — порівняно новий навчальний посібник, яке передбачає, що читач вже має певний обсяг знань Javascript, CSS, HTML, об’єктно-орієнтованого програмування та знання основ бібліотек Prototype і Scriptaculous. Однак повний source-код доступний і простий для читання і вивчення, навіть якщо ви не знайомі з використовуваної специфічної бібліотекою. Перед початком можна переглянути робочу версію «акордеона» в дії.

Створюємо просте, розумне випадаюче меню з допомогою бібліотек Prototype і Scriptaculous

Крок 2 — Почнемо з основної розмітки

Для початку ми створимо просту HTML-розмітку для нашого «акордеона».

Toggle 1
Toggle 2
Content 2
Toggle 3
Content 3
Toggle 4
Content 4

Крок 3 – Додамо трохи стилів

Далі нам потрібно додати трохи стилів до нашого випадаючого меню, щоб воно виглядало саме як акордеон. Для початку ми визначимо основні стилі, роботу над якими продовжимо в процесі роботи. Для більшої впевненості в тому, що «акордеон» буде працювати саме так, як задумано, слід включити сюди деякі додаткові стилі.

div#test-accordion{
margin: 10px;
border: 1px solid #aaa;}
div.accordion {
position: relative; /* required for bounding—works around a «peculiarity» in Prototype */
}
div.accordion-toggle{
position: relative; /* required for effect */
z-index: 10; /* required for effect */
background: #eee; /* required for effect—can be anything except «transparent» */
cursor: pointer;
}
div.accordion-toggle-active{
background: #fff;
}
div.accordion-content{
overflow: hidden; /* required for effect */
background: #aaa;
}

Крок 4 – Створюємо «акордеон» за допомогою Javascript

Prototype пропонує чудову основу для побудови категорій в Javascript і ми використовуємо цю функціональність для побудови нашого випадаючого меню. Цей клас буде містити всі властивості і методи випадаючого меню типу «акордеон»: поточну видиму панель, вміст «акордеона», методи розорювання і стиснення панелей і методи обробники подій для визначення того, що відбувається, коли користувачі клацають на «акордеон». Тепер опишемо основну структуру класу, властивості і методи, які нам знадобляться:

var Accordion = Class.create({
initialize: function(){
this.accordion = null; /* Stores a pointer to the accordion element */
this.contents = null; /* Array of pointers to the headings and content panes of the accordion */
this.options = null; /* Allows user to define the names of the css classes */
this.maxHeight = 0; /* Stores the height of the tallest content pane */
this.current = null; /* Stores a pointer to the currently expanded content pane */
this.toExpand = null; /* Stores a pointer to the content pane to expand when a user clicks */
this.isAnimating = false; /* Keeps track of whether or not animation is currently running */
},
checkMaxHeight: function(){}, /* Determines the height of the tallest content pane */
initialHide: function(){}, /* Hides the panes which are not displayed by default */
attachInitialMaxHeight: function(){}, /* Ensures that the height of the first content pane matches the tallest */
expand: function(el){}, /* Tells the animation function which elements to animate */
animate: function(){}, /* Performs the actual animation of the accordion effect */
handleClick: function(e){} /* Determine where a user has clicked and act based on that click */
});

Це – основні методи і властивості, які нам знадобляться під час створення нашого «акордеона». Кожен наступний крок проведе нас через побудову кожного методу, поки у нас не буде готовий працюючий «акордеон». Якщо в будь-якому місці інструкції вам знадобиться згадати, для чого потрібен той чи інший метод або властивість, в якості довідника можна використовувати вищевказаний код, повністю прокомментированный.

Крок 5 – Ініціалізуємо: початок

Класи Prototype мають спеціальний метод-конструктор initialize() — це означає, що він діє, коли користувач створює новий запит такого класу. Для будь-якого «акордеона» потрібно знати дві речі перед початком:

ID елемента «акордеона»

Початкову позицію «акордеона» за замовчуванням (якщо є щось крім першої позиції)

Отже, нам необхідно дозволити нашому конструктору прийняти ці два параметри. До того ж, наш конструктор повинен:

Повертати і зберігати випадаюче меню і його вміст в якості покажчиків до цих елементів

Встановлювати параметри, вибрані користувачем

Встановлювати поточний розкритий елемент

Визначати максимальну висоту, яку ми будемо використовувати, для всіх панелей вмісту і застосовувати її

Ховати панелі вмісту, які не показуються за замовчуванням

Додати обробник подій до «акордеону», щоб відстежувати кліки користувачів

Ось код для методу ініціалізації:

initialize: function(id, defaultExpandedCount) {
if(!$(id)) throw(«Attempted to initalize accordion with id: «+ id + » which was not found.»);
this.accordion = $(id);
this.options = {
toggleClass: «accordion-toggle»,
toggleActive: «accordion-toggle-active»,
contentClass: «accordion-content»
}
this.contents = this.accordion.select(‘div.’+this.options.contentClass);
this.isAnimating = false;
this.maxHeight = 0;
this.current = defaultExpandedCount ? this.contents[defaultExpandedCount-1] : this.contents[0];
this.toExpand = null;
this.checkMaxHeight();
this.initialHide();
this.attachInitialMaxHeight();
var clickHandler = this.clickHandler.bindAsEventListener(this);
this.accordion.observe(‘click’, clickHandler);
}

Бачите, ми розумно встановили всі значення за замовчуванням і застосували три методи, щоб все упорядкувати. Нарешті, ми прикріпили до «акордеону» обробник подій. Давайте створимо ці три методи і обробник подій.

Крок 6 – Обмежуємо самий довгий елемент

Однією з вимог до нашого випадаючого меню було те, що навіть коли демонструється найдовша панель вмісту, загальна висота «акордеона» залишиться постійною. Для досягнення цієї мети ми повторно пройдемося по нашим панелям вмісту, визначаючи, яка з них найдовша і встановимо максимальну висоту згідно з нею:

checkMaxHeight: function() {
for(var i=0; i this.maxHeight) {
this.maxHeight = this.contents.getHeight();
}
}
}

Крок 7 – Ховаємо все інше

Наше випадаюче меню повинно демонструвати тільки панель вмісту, встановлену як поточну панель, всі інші повинні бути за замовчуванням заховані. До того ж, нам потрібно встановити висоту цих панелей в 0 – це запобіжить поява панелі вмісту у всю довжину до того, як вона буде належним чином анімована.

initialHide: function(){
for(var i=0; iКрок 8 – Показуємо панель вмісту за промовчанням

Тепер, коли ми сховали все крім панелі за замовчуванням, нам потрібно переконатися, що панель вмісту за промовчанням відображається правильно – її назва повинна мати «активний» вигляд, а її висота повинна відповідати встановленій максимальній висоті:

attachInitialMaxHeight: function() {
this.current.previous(‘div.’+this.options.toggleClass).addClassName(this.options.toggleActive);
if(this.current.getHeight() != this.maxHeight) this.current.setStyle({height: this.maxHeight+»px»});
}

Крок 9 – Створюємо обробник подій

Якщо ви дотримуєтеся традиційного погляду на розміщення обробників подій, згідно з яким обробники приєднуються до тієї області, де виникає подія, то вас може збити з пантелику, що ми приєднуємо обробник подій до одного-єдиного елементу. Ми використовуємо делегування подій.

clickHandler: function(e) {
var el = e.element();
if(el.hasClassName(this.options.toggleClass) && !this.isAnimating) {
this.expand(el);
}
}

У цій функції дві частини. По-перше, ми визначаємо джерело події. Потім ми впевнимося, що клік припав на назву, і що в даний момент анімація ніяка не використовується. Якщо це так, то ми використовуємо метод expand() для початку обробки. Змінна, яку ми передаємо методу expand() – це заголовок, на який клікнув користувач.

Крок 10 – Починаємо процес

Тепер вже можна почати створювати ефект «акордеона». Ми вже знаємо, що метод expand() повинен приймати параметр – посилання на елемент, на який перейшли. Використовуючи цей параметр, метод визначає, яку з панелей вмісту розгорнути, і якщо вона ще не розгорнуто, то застосувати анімацію, щоб показати це дія в процесі.

expand: function(el) {
this.toExpand = el.next(‘div.’+this.options.contentClass);
if(this.current != this.toExpand){
this.toExpand.show();
this.animate();
}
},

Крок 11 – Робимо чорнову роботу

Зараз всі складові вже знаходяться на своїх місцях. Ми знаємо, яка з панелей показується, знаємо, який із заголовків клікнув користувач, а також знаємо, яку з панелей вмісту викликав користувач. Тепер потрібно створити анімацію «акордеона». Для цього ми створимо метод анімації, використовує клас Scriptaculous Effect.Parallel, щоб намалювати дві анімації спільно, і Effect.Scale, щоб змінити розмір кожної панелі вмісту. Метод анімації повинен виконати наступні кроки:

Створити масив, що буде використовуватися для зберігання об’єктів Effect.Scale.

Підготувати параметри для передачі в конструктор Effect.Scale для панелі вмісту, яка буде показуватися, і створити об’єкт.

Додати цей об’єкт в масив.

Підготувати параметри для передачі в конструктор Effect.Scale для панелей вмісту, які будуть прихованими, і створити об’єкт.

Додати цей об’єкт в масив.

Створити об’єкт Effect.Parallel , який буде одночасно запускати об’єкти Effect.Scale.

Повідомити про об’єкт початку операції

Запустити анімацію.

Очистити всі затрагивавшиеся стилі заголовків.

Повідомити про об’єкт завершення операції.

animate: function() {
var effects = new Array();
var options = {
sync: true,
scaleFrom: 0,
scaleContent: false,
transition: Effect.Transitions.sinoidal,
scaleMode: {
originalHeight: this.maxHeight,
originalWidth: this.accordion.getWidth()
},
scaleX: false,
scaleY: true
};
effects.push(new Effect.Scale(this.toExpand, 100, options));
options = {
sync: true,
scaleContent: false,
transition: Effect.Transitions.sinoidal,
scaleX: false,
scaleY: true
};
effects.push(new Effect.Scale(this.current, 0, options));
new Effect.Parallel(effects {
duration: 0.5,
fps: 35,
queue: {
position: ‘end’,
scope: ‘accordion’
},
beforeStart: function() {
this.isAnimating = true;
this.current.previous(‘div.’+this.options.toggleClass).removeClassName(this.options.toggleActive);
this.toExpand.previous(‘div.’+this.options.toggleClass).addClassName(this.options.toggleActive);
}.bind(this),
afterFinish: function() {
this.current.hide();
this.toExpand.setStyle({ height: this.maxHeight+»px» });
this.current = this.toExpand;
this.isAnimating = false;
}.bind(this)
});
}

Для повного опису параметрів, які ми передаємо об’єктів Effect.Scale і Effect.Parallel, дивіться документацію до Scriptaculous. Важливими аспектами методу є методи beforStart і afterFinish в нашому Effect.Parallel. Метод beforStart інформує «акордеон» про те, що він в даний момент анимируется. Цим запобігається можлива спроба обробника подій почати які-небудь зміни, поки відтворюється анімація. Таким же чином, заголовка, на який кликнули, встановлюється CSS-клас, відповідний активного імені. Метод afterFinish повністю приховує панель вмісту, яка була активною раніше (після того, як вона повністю захована завдяки анімації). Він також забезпечує те, що кінцева висота поточної панелі вмісту є правильною. Коли заміна сталася, він інформує наш «акордеон» про те, що розгортається панель стала активною і анімація закінчена.»>документацію до Scriptaculous. Важливими аспектами методу є методи beforStart і afterFinish в нашому Effect.Parallel. Метод beforStart інформує «акордеон» про те, що він в даний момент анимируется. Цим запобігається можлива спроба обробника подій почати які-небудь зміни, поки відтворюється анімація. Таким же чином, заголовка, на який кликнули, встановлюється CSS-клас, відповідний активного імені. Метод afterFinish повністю приховує панель вмісту, яка була активною раніше (після того, як вона повністю захована завдяки анімації). Він також забезпечує те, що кінцева висота поточної панелі вмісту є правильною. Коли заміна сталася, він інформує наш «акордеон» про те, що розгортається панель стала активною і анімація закінчена.

Крок 12 – Додамо ще стилю

В цей момент ми вже маємо пристойно виглядає «акордеон», який можна подивитися в дії тут. Але з невеликою допомогою CSS ми можемо змусити його виглядати ще більш видовищно. Отже, по-перше, ми створюємо швидкий робочий зразок Photoshop, так що можна приблизно зрозуміти ідею того, як все це буде виглядати. Пам’ятаючи про це, ми збираємося створити три картинки:

Зображення-логотип

Створюємо просте, розумне випадаюче меню з допомогою бібліотек Prototype і Scriptaculous

Кілька симпатичних фонових картинок

Створюємо просте, розумне випадаюче меню з допомогою бібліотек Prototype і Scriptaculous
Створюємо просте, розумне випадаюче меню з допомогою бібліотек Prototype і Scriptaculous

А ось обіцяний CSS-код:

body {
padding: 130px 50px 50px 50px;
background: #252422 url(../img/logo.gif) no-repeat;
background-position: 60px 40px;
font-family: «Lucida Grande», «Lucida Sans Unicode», Arial, Sans-serif;
font-size: 11px;
line-height: 18px;
}
div#test-accordion{
border: 1px solid #343230;
background-color: #21201f;
padding: 10px;
}
div.accordion {
position: relative; /* required for bounding */http://nettuts.com/wp-admin/users.php
width: 800px;
}
div.accordion-toggle{
position: relative; /* required for effect */
z-index: 10; /* required for effect */
background: #3f3c38 url(../img/off.jpg) repeat-x;
background-position: bottom;
color: #fff;
cursor: pointer;
margin-bottom: 1px;
padding: 9px 14px 6px 14px;
border-top: 1px solid #5d5852;
}
div.accordion-toggle:hover, div.accordion-toggle-active{
background-image: url(../img/on.jpg);
background-color: #6d493a;
border-top: 1px solid #a06b55;
}
div.accordion-content{
overflow: hidden; /* required for effect */
background: #302e2c;
color: #c4bab1;
border-bottom: 1px solid #000;
}
div.accordion-content p{
margin: 9px 24px 6px 24px;
}

Видно, що тут ми:

Додали трохи фонових стилів навколо сторінки і «акордеона».

Надали рамці «акордеона» постійний фоновий колір.

Рамка «акордеона» при русі мишею і активні заголовки всередині тепер використовують один і той же червонуватий колір.

Крок 13 – Запускаємо

Працюючу модель можна бачити тут. Ви можете додати власний CSS і картинки, щоб відточити вигляд сайту. Скачайте accordion.js&accordion.css.

Переклад і редакція: Ріг Віктор і Андрій Бернацький. Команда webformyself.

E-mail:[email protected]

Проект webformyself.com — Як створити свій сайт. Основи самостійного сайтобудування

P. S. Хочете опублікувати цікавий тематичний матеріал? Якщо відповідь «Так», то тисніть сюди.