Статьи

Сексуальные анимированные вкладки с помощью MooTools

Одним из современных, привлекательных способов размещения большого количества контента в небольшом пространстве является использование системы вкладок. Из этого туториала Вы узнаете, как создать сексуальную анимированную систему вкладок с CSS-спрайтами, файлами cookie и заменой анимированных вкладок.


Вкладки MooTools

Есть несколько предположений и замечаний, которые мы собираемся использовать в этой системе:

  • Мы будем использовать самую последнюю версию MooTools: 1.2.4.
  • Клиент должен поддерживать JavaScript.
  • Мы будем использовать PHP для любых сценариев на стороне сервера. Любой серверный язык по вашему выбору также будет работать с соответствующим синтаксисом / методами.

Учебное пособие также предполагает базовые знания JavaScript. Небольшой опыт работы с MooTools или фреймворком JavaScript поможет.

Так как же работает эта удивительная система? Вот основная схема:

  • Когда страница загружается, мы выводим два списка UL с элементами списка: первый список содержит вкладки, второй список содержит элементы содержимого вкладок.
  • Для каждого набора вкладок, который мы выводим, мы проверяем наличие файла cookie, который может сказать нам, какая вкладка должна отображаться на основе предыдущего посещения. Если файл cookie отсутствует, мы предполагаем первую вкладку.
  • Когда пользователь щелкает вкладку, текущий элемент содержимого для этой вкладки выходит из поля зрения, а содержимое новой вкладки перемещается.
  • Мы сохраняем индекс вкладки в файле cookie для целей будущей загрузки (т. Е. Хотим, чтобы последняя нажатая вкладка была первой, отображаемой на следующей странице / посещении).

Сама система довольно пуленепробиваемая. Если пользователь не разрешает использование файлов cookie, начальная вкладка для каждого списка всегда будет 0.
Если поддержка JavaScript отсутствует, вкладки не будут отображаться на экране, поскольку мы будем отображать: нет; их изначально.

HTML для создания системы вкладок и соответствующих элементов контента невероятно прост по своей структуре.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
<div class=»tab-container»>
    <ul id=»tabs1″ class=»tabs»>
        <li>Tab 1</li>
        <li>Tab 2</li>
        <li>Tab 3</li>
        <li>Tab 4</li>
    </ul>
    <div class=»clear»></div>
    <ul id=»contents1″ class=»tabs-content»>
        <li>This is the content for tab 1.</li>
        <li>This is the content for tab 2.</li>
        <li>This is the content for tab 3.</li>
        <li>This is the content for tab 4.</li>
    </ul>
</div>

Позже в этом уроке мы будем модифицировать вышеупомянутый HTML с PHP, чтобы создать более надежную систему.

Вкладки MooTools

Как и в любой комбинации CSS и HTML, вы можете стилизовать вкладки и их элементы содержимого так, как вам нравится.
Я решил использовать CSS-спрайты в стиле Facebook для моих вкладок с примерами.
Поймите, что вы захотите стилизовать следующие элементы определенным образом, чтобы система работала:

  • Элементы содержимого вкладки должны иметь высоту 0, а их переполнение скрыто. Это позволяет, так сказать, скрывать все элементы контента при загрузке страницы.
  • Между CSS-селекторами «ul.tabs li a» и «ul.tabs li a.active» вам нужно назначить «активный» селектор другим образом, чтобы пользователь знал его текущую выбранную вкладку.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
/* tabs structure */
.tab-container { width:320px;
ul.tabs { list-style-type:none;
    ul.tabs li { float:left;
    ul.tabs li a { padding:5px 10px;
    ul.tabs li a.active { border-color:#028433;
        ul.tabs li a.active:hover { text-decoration:none;
    ul.tabs li:hover { text-decoration:underline;
ul.tabs-content { margin:10px 0 0 0;
    ul.tabs-content li { height:0;
 
/* clears floats */
div.clear { clear:both;
         
/* ie fixes */
* html ul.tabs-content li { float:left;
*+ html ul.tabs-content li { width:99%;

Обратите внимание, что нам нужно реализовать несколько исправлений, относящихся к Internet Explorer; некрасиво, но необходимо.

MooTools Javascript Framework

Одним из больших преимуществ MooTools является мощная система Class.
Классы MooTools обеспечивают гибкие, организованные и расширяемые функциональные возможности.
Наш класс MooTools будет называться «TabSet». Поскольку класс TabSet выполняет много действий,
давайте разберем каждую часть класса.

Первая строка всегда дает классу имя:

1
2
/* give the class a name */
var TabSet = new Class({

Далее нам нужно создать объект, который будет содержать параметры нашего класса:

1
2
3
4
5
6
7
8
9
options: { //default tab options
    activeClass: ‘active’, //css class
    cookieName: », //no name means no cookie
    cookieOptions: { //options for the cookie, if cookie’s wanted
        duration: 30, //30 days
        path: ‘/’
    },
    startIndex: 0 //start with this item if no cookie or active
},

Наши параметры позволяют нам определить:

  • activeClass: класс CSS, который должен быть назначен выбранной (или «активной») вкладке.
  • cookieName: имя файла cookie, который будет представлять этот набор вкладок. Если вы не определили имя куки, куки не будут использоваться.
  • cookieOptions: объект, который содержит параметры для cookie.
  • startIndex: вкладка, чтобы сделать активным изначально. Начинается с 0. Переопределяется переменной activeClass, если найден файл cookie.

Имея только три опции в классе, TabSet будет считаться относительно простым классом.

Далее мы реализуем две опции и события:

1
Implements: [Options,Events],

Реализация опций и событий позволит нам правильно обрабатывать данные опции и
запускать пользовательские события Load и Change в наших списках в любом месте класса.

Далее мы определяем метод «initialize», который запускается при создании каждого экземпляра класса:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
initialize: function(tabs,contents,options) {
    //handle arguments
    this.setOptions(options);
    this.tabs = $$(tabs);
    this.contents = $$(contents);
    //determine the «active» tab
    var active = (Cookie.read(this.options.cookieName) || this.options.startIndex);
    this.activeTab = this.tabs[active].addClass(this.options.activeClass);
    this.activeContent = this.contents[active].setStyle(‘height’,’auto’);
    //run each tab/content combo through the «processItem» method which we’ll see below
    this.tabs.each(function(tab,i) { this.processItem(tab,this.contents[i],i); },this);
    //tabs are ready — fire the load event!
    this.fireEvent(‘load’);
},

Далее идет метод рабочей лошадки нашего класса TabSet: processItem:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    processItem:function(tab,content,i) {
        var contentHeight = content.getScrollSize().y;
        //add a click event to the tab
        tab.addEvent(‘click’,function() {
            //if it’s not the active tab
            if(tab != this.activeTab) {
                //stopper
                if(e) e.stop();
                //remove the active class from the active tab
                this.activeTab.removeClass(this.options.activeClass);
                //make the clicked tab the active tab
                (this.activeTab = tab).addClass(this.options.activeClass);
                //tween the old tab content up
                //tween the new content down
                this.activeContent.set(‘tween’,{
                    onComplete:function() {
                        this.activeContent = content.fade(‘in’).set(‘tween’,{ onComplete: $empty }).tween(‘height’,contentHeight);
                        //fire the tab change event
                        this.fireEvent(‘change’,[tab,content]);
                    }.bind(this)
                }).setStyles({
                    height: contentHeight,
                    overflow: ‘hidden’
                }).fade(‘out’).tween(‘height’,0);
                //save the index to cookie
                if(this.options.cookieName) Cookie.write(this.options.cookieName,i);
            }
        }.bind(this));
    }
});

Вот основная схема того, что делает метод processItem:

  1. Принимает соответствующую вкладку, элемент содержимого и его индекс …
  2. Вычисляет высоту элемента содержимого.
  3. Добавляет событие нажатия на вкладку, которая:
    1. Проверяет, что эта вкладка еще не активна (мы не хотим анимировать или изменять что-либо, если они нажимают на уже активную вкладку)
    2. Удаляет «активный» класс CSS из текущей вкладки и добавляет его к вкладке, которую только что щелкнули.
    3. Выводит содержимое текущей вкладки из поля зрения, а затем отображает новое содержимое. Событие «change» вызывается, когда анимация завершена.
    4. Сохраняет индекс новой вкладки в файле cookie, чтобы при перезагрузке пользователем страницы или переходе на другую страницу новая вкладка первоначально выбиралась.

А теперь пример использования нашего класса:

1
2
3
4
5
window.addEvent(‘domready’,function() {
    var tabset = new TabSet($$(‘#tabs1 li a’),$$(‘#contents1 li’),{
        cookieName: ‘demo-list’
    });
});

Мы предоставляем нашему экземпляру вкладку LI A и содержание LI. Мы также предоставляем аргумент необязательных опций. Вот как легко использовать этот класс! Вот полный класс с использованием:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/* class */
var TabSet = new Class({
    options: {
        activeClass: ‘active’, //css class
        cookieName: »,
        cookieOptions: {
            duration: 30, //30 days
            path: ‘/’
        },
        startIndex: 0 //start with this item if no cookie or active
    },
    Implements: [Options,Events],
    initialize: function(tabs,contents,options) {
        //handle arguments
        this.setOptions(options);
        this.tabs = $$(tabs);
        this.contents = $$(contents);
        //determine the «active» tab
        var active = (Cookie.read(this.options.cookieName) || this.options.startIndex);
        this.activeTab = this.tabs[active].addClass(this.options.activeClass);
        this.activeContent = this.contents[active].setStyle(‘height’,’auto’);
        //process each tab and content
        this.tabs.each(function(tab,i) {
            this.processItem(tab,this.contents[i],i);
        },this);
        //tabs are ready — load it!
        this.fireEvent(‘load’);
    },
    processItem:function(tab,content,i) {
        var contentHeight = content.getScrollSize().y;
        //add a click event to the tab
        tab.addEvent(‘click’,function(e) {
            //stop!
            if(e) e.stop();
            //if it’s not the active tab
            if(tab != this.activeTab) {
                //remove the active class from the active tab
                this.activeTab.removeClass(this.options.activeClass);
                //make the clicked tab the active tab
                (this.activeTab = tab).addClass(this.options.activeClass);
                //tween the old tab content up
                //tween the new content down
                this.activeContent.set(‘tween’,{
                    onComplete:function() {
                        this.activeContent = content.fade(‘in’).set(‘tween’,{ onComplete: $empty }).tween(‘height’,contentHeight);
                        //fire the tab change event
                        this.fireEvent(‘change’,[tab,content]);
                    }.bind(this)
                }).setStyles({
                    height: contentHeight,
                    overflow: ‘hidden’
                }).fade(‘out’).tween(‘height’,0);
                //save the index to cookie
                if(this.options.cookieName) Cookie.write(this.options.cookieName,i,this.options.cookieOptions);
            }
        }.bind(this));
    }
});
 
 
/* usage */
window.addEvent(‘load’,function() {
    var tabset = new TabSet($$(‘#tabs1 li a’),$$(‘#contents1 li’),{
        cookieName: ‘demo-list’
    });
});
MooTools Cookies

Помните, как я сказал, что мы изменим наш оригинальный HTML с помощью PHP? Сейчас самое время Так как мы можем
если для нашего TabSet установлен файл cookie, мы должны попытаться обнаружить его при выводе HTML-кода вкладки.
Почему? Потому что мы хотим, чтобы вкладки загружались плавно. Мы также хотим учесть пользователей, у которых не включен JavaScript или файлы cookie.
Без этого PHP вы можете заметить небольшой «скачок» в активной области содержимого.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php
    /*
        Removes a desired variable from the querystring
        Credit: http://www.addedbytes.com/code/querystring-functions/
    */
    function remove_querystring_var($url, $key) {
        $url = preg_replace(‘/(.*)(\?|&)’ . $key . ‘=[^&]+?(&)(.*)/i’, ‘$1$2$4’, $url . ‘&’);
        $url = substr($url, 0, -1);
        return ($url);
    }
     
    /* generate the urls */
    $demo_tabs_url = remove_querystring_var($_SERVER[‘REQUEST_URI’],’demo-list’);
    $demo_tabs_url.= (is_numeric(strpos($demo_tabs_url,’demo-list’)) ? ‘&’ : ‘?’).’demo-list=’;
     
    /* current tab */
    $current_tab = isset($_COOKIE[‘demo-list’]) ?
     
?>
 
<div class=»tab-container»>
    <ul id=»tabs1″ class=»tabs»>
        <li><a href=»<?php echo $demo_tabs_url.’0′; ?>» <?php echo $current_tab == ‘0’ ?
        <li><a href=»<?php echo $demo_tabs_url.’1′; ?>» <?php echo $current_tab == ‘1’ ?
        <li><a href=»<?php echo $demo_tabs_url.’2′; ?>» <?php echo $current_tab == ‘2’ ?
        <li><a href=»<?php echo $demo_tabs_url.’3′; ?>» <?php echo $current_tab == ‘3’ ?
    </ul>
    <div class=»clear»></div>
    <ul id=»contents1″ class=»tabs-content»>
        <li <?php echo $current_tab == ‘0’ ?
        <li <?php echo $current_tab == ‘1’ ?
        <li <?php echo $current_tab == ‘2’ ?
        <li <?php echo $current_tab == ‘3’ ?
    </ul>
</div>

Некоторые пользователи не включают JavaScript или куки в целях безопасности. Мы все еще хотим, чтобы наша система работала на них. Если вы помните из предыдущего блока кода,
мы используем ссылки с ключом строки запроса «demo-list», чтобы обозначить изменение на вкладке. Следующий блок PHP в верхней части страницы (до ЛЮБОГО вывода) будет
Помогите нам изменить значение cookie на запрошенную вкладку.

01
02
03
04
05
06
07
08
09
10
11
<?php
    /* handle the cookies */
    if($_GET[‘demo-list’]) {
        /* set the new cookie */
        setcookie(‘demo-list’,(int) $_GET[‘demo-list’],time()+60*60*24*30,’/’);
        if($_COOKIE[‘demo-list’]) {
            header(‘Location: ‘.remove_querystring_var($_SERVER[‘REQUEST_URI’],’demo-list’));
            exit();
        }
    }
?>

Обратите внимание, что мы обновляем страницу только в том случае, если можем убедиться, что файл cookie был установлен. Если файл cookie не был установлен, у пользователя отключены файлы cookie.

MooTools Cookies

Вот краткий обзор преимуществ класса MooTools TabSet:

  • Наш класс реализует События, чтобы мы могли создавать собственные события и обработчики событий.
  • Компоновка всей системы полностью контролируется простым HTML и CSS.
  • Использование файлов cookie для запоминания предыдущей вкладки — это значительное улучшение юзабилити
  • Сам класс, который является классом MooTools, позволяет легко реализовать его из проекта в проект.

Я всегда выступал за кодирование желаемой функциональности MooTools «встроенным», прежде чем превращать его в класс. Вот встроенный код JavaScript MooTools:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
$$(‘ul.tabs’).each(function(tabList) {
    //get the content list
    var tabContentList = tabList.getNext(‘ul.tabs-content’),
        //get the name of the cookie, which is the «title» attribute of the tab list
        cookie = ‘demo-list’,
        //the start tab index
        startIndex = Cookie.read(cookie) ||
        //get the actual tab LI items
        tabs = tabList.set(‘title’,»).getElements(‘li’),
        //get the content LI items
        lis = tabContentList.getElements(‘li’),
        //the tab (LI) that is currently active
        activeTab = tabs[startIndex].addClass(‘active’),
        //the content LI that is currently active
        activeContent = lis[startIndex].setStyle(‘height’,’auto’);
    //for every tab within this tab/content relationship…
    tabs.each(function(tab,i) {
        //stopper
        if(e) e.stop();
        //calculate the respective content item’s height
        var content = lis[i], contentHeight = content.getScrollSize().y;
        //add the click event to the tab which…
        tab.addEvent(‘click’,function() {
            //if it’s not the currently activated tab…
            if(tab != activeTab) {
                //add and remove the active class from old vs. new tab
                activeTab.removeClass(‘active’);
                (activeTab = tab).addClass(‘active’);
                //start the wipe up, wipe down effect
                activeContent.set(‘tween’,{
                    onComplete:function() {
                        activeContent = content.fade(‘in’).set(‘tween’,{ onComplete: $empty }).tween(‘height’,contentHeight);
                    }
                }).setStyles({
                    height: contentHeight,
                    overflow: ‘hidden’
                }).fade(‘out’).tween(‘height’,’0′);
                //write to cookie
                Cookie.write(cookie,i);
                //fin!
            }
        });
    });
    //fire click event
    activeTab.fireEvent(‘click’);
});

Обратите внимание, что все операторы «var» в верхней части становятся аргументами или опциями для класса. Переход от встроенного JavaScript MooTools к классу чрезвычайно прост!

Вкладки MooTools

Есть еще идеи для этого класса? Обязательно поделитесь ими в комментариях ниже!

Знаете ли вы, что вы можете заработать до 600 долларов за написание учебника PLUS и / или скринкаст для нас? Мы ищем подробные и хорошо написанные учебники по HTML, CSS, PHP и JavaScript. Если у вас есть такая возможность, пожалуйста, свяжитесь с Джеффри по адресу [email protected].

Обратите внимание, что фактическая компенсация будет зависеть от качества окончательного урока и скринкаста.

Написать ПЛЮС учебник
  • Подпишитесь на нас в Твиттере или подпишитесь на ленту Nettuts + RSS для получения лучших учебных материалов по веб-разработке.