Статьи

12 шагов к мастерству MooTools

Это руководство о понимании и освоении библиотеки MooTools . Это достигается благодаря высокоуровневому ознакомлению с историей и основами библиотеки Core: с чего начать, где исследовать, что освоить и многое другое.


шаг 1

Основой платформы MooTools является прототипная модель наследования JavaScript. В классических языках, таких как C ++ или Java, класс представляет собой нечто вроде типа данных или того, что Джефф Мотт назвал «планом». Эти чертежи затем используются при создании объектов. На самом деле, в этих языках ничего не создается, пока оператор «new» явно не вызовет их.

Однако в JavaScript все создается немедленно, даже до того, как вы создадите объекты с помощью оператора «new». Для языка-прототипа это фактически означает отсутствие чертежей и «классов» . Вместо этого мы используем некоторые объекты в качестве полностью функциональных баз для других объектов. Как сказал Дуглас Кроуфорд, именно таким образом JavaScript становится «более способным и предлагает более выразительную силу». Давайте взглянем:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function Nerd(iq) {
    this.iq = iq;
    this.glasses = true;
    this.pants = ‘high’;
}
 
function SuperPowers() {
    this.strongerThanLocomotive = true;
    this.fasterThanBullet = true;
    this.canLeapBuildings = true;
}
 
Nerd.prototype = new SuperPowers();
 
Nerd.prototype.willWinGirl = function (hotness) {
    if(this.iq > (hotness * 20) || this.strongerThanLocomotive){
        console.log(‘maybe’);
    }
    else {
        console.log(‘nope’);
    }
}
 
new Nerd(140).willWinGirl(10);

Приведенный выше пример на самом деле является довольно популярным средством представления концепции прототипирования. Однако, если вы находите это слишком абстрактным, возможно, лучший способ приблизиться к этому — взглянуть на создание прототипа нативного конструктора JavaScript, такого как String, Array и т. Д. Например:

1
2
3
4
5
6
7
Array.prototype.eachhhh = function (fn) {
    for (var i = 0, l = this.length; i < l; i++) fn(this[i]);
}
 
[0,1,2,3].eachhhh(function(item){
    console.log(item);
});

Создание прототипов простых шаблонов кода, таких как цикл for выше, может сэкономить массу времени при работе над большими проектами. При использовании инфраструктуры MooTools важно начать думать о каждом конструкторе как о расширяемом; это сэкономит ваше время и сделает ваш код более гибким. Более того, именно этот метод наследования лежит в основе MooTools, а использование возможностей этих сред означает использование прототипов. Конечно, MooTools делает этот процесс намного проще для вас, чтобы получить к нему доступ и воспользоваться им, но мы подробнее расскажем о том, как это сделать, позже в этой статье.


шаг 2

Кстати, в 2006 году Крис Хейлман уже увлекался буквальным синтаксисом объекта … говорил о нарезанном хлебе и прочем сумасшествии. Во всяком случае, именно по этой причине я не буду слишком подробно останавливаться на этом предмете, вместо этого я предполагаю, что вы когда-нибудь сталкивались с этим синтаксисом или, по крайней мере, можете понять его с помощью простого примера ниже.

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
//this is not object literal notation
var variable1 = null;
var variable2 = false;
 
function1(){
// some code
}
 
function2(){
// some code
}
 
// the above becomes object literal notation below…
 
var SomeVariableName = {
 
    variable1: null,
    variable2: false,
     
    init:function(){
    },
     
    function1:function(){
    // some code
    },
     
    function2:function(){
    // some code
    }
}

Как и большинство языков программирования, в JavaScript существует большое количество стилистических предпочтений и «лучших практик». Работая с MooTools, вы обнаружите, что в них нет недостатка, в том числе: чрезмерной цепочки, использования заглавных букв в именах классов, объявления переменных через запятую и т. Д. Однако среди них, пожалуй, наиболее важна нотация литералов объектов. понимание не только того, как структурирована сама структура MooTools, но и того, как на самом деле воспользоваться этой средой при разработке собственного кода. Мы будем развивать эту идею далее в оставшейся части этой статьи, и, как вы увидите, все примеры с этого момента будут использовать этот синтаксис.


шаг 3

Если в JavaScript нет «классов», то почему все эти шумихи вокруг Motools и классов? В мае прошлого года Аарон Ньютон опубликовал превосходную сравнительную статью о jQuery и MooTools . Среди прочего, он очень точно обратился к этому вопросу о классах: «Несмотря на свое имя, функция класса MooTools на самом деле не является классом и не создает их. Она имеет шаблоны проектирования, которые могут напоминать вам о классах в более традиционный язык программирования, но на самом деле Class — это все об объектах и ​​наследовании прототипов ».
По мере того, как Аарон продолжает детализировать, инфраструктура MooTools требует мощных и в конечном итоге простых способов организации и структурирования вашего кода, способов, которые элегантны, но также знакомы , и не только семантически, но и способны вести себя в классических шаблонах проектирования. Фактически, вы обнаружите, что использование «классов» в вашей кодовой базе открывает ваш код для многих мощных шаблонов программирования: посредник, миксин и т. Д.

Простой класс MooTools будет выглядеть примерно так (обратите внимание на синтаксис):

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
var YourClass = new Class({
 
    variable1: false,
 
    initialize: function(){
        this.toggleVariable();
    },
     
    toggleVariable: function(){
        this.variable1 = !variable1;
    }
 
});
 
var yourClassInstance = new YourClass();
yourClassInstance.toggleVariable();

Не слишком сложно, правда? Как только вы начнете структурировать свой код в таких классах, вы обнаружите, что ваш репозиторий кода станет не только намного более организованным и управляемым, но и фактически меньшим!


шаг 4

Так как именно он становится меньше? Возвращаясь к прототипной модели наследования JavaScript и ее связи с конструктором Class, MooTools предоставляет нам Extends и Implements. Как свойства, оба имеют основополагающее значение для создания ваших подклассов MooTools и делают весь этот беспорядок прототипирования немного более интуитивным. На высоком уровне Extends предоставляет вашему подклассу доступ ко всем методам его базового класса, где методы и свойства с одинаковыми именами перезаписываются (не волнуйтесь, они все еще доступны через метод parent ()). Подобно Extends, Implements принимает свойства одного или нескольких других классов, но без модели наследования.

Рассмотрим вкратце модный плагин Digitarald для загрузки Mootools. В этой программе Харальд определяет несколько классов, один из которых называется классом «Файл». Файл содержит основные функциональные возможности, которые необходимы файловому объекту для взаимодействия с его загружающей программой, и по этой причине он идеально подходит для расширения; можно создать подкласс «Файл изображения», подкласс «Текстовый файл» и т. д. Путем моделирования вашего кода таким образом вы можете создавать свой код, а не извлекать его. Рассмотрим пример ниже, как использовать Extends:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
var YourSubClass = new Class({
     
    Extends: YourClass, //here we are extending «YourClass» from our previous example
 
    variable2: false,
 
    initialize: function(){
        this.parent();
    },
     
    //here we are overwriting the toggle Variable function of «YourClass» with a new function
    toggleVariable: function(){
        this.variable1 = !variable1;
        this.variable2 = !this.variable1;
    }
});

шаг 5

Наиболее распространенный сценарий использования, который я нахожу с Implements, включает в себя либо конструктор Events, либо конструктор Options в моих классах. Как следует из названия, реализация Events позволяет как прикреплять, так и запускать пользовательские события на вашем объекте, такие как onComplete, onFailure, onSuccess, onAnything. Этот уровень абстракции становится особенно полезным, когда вы начинаете делиться своим кодом между несколькими проектами, где события ведут себя как посредники между вашим текущим проектом и вашими плагинами. Таким образом, вы можете, наконец, избавиться от этих неприятных отношений один-к-одному в своих плагинах. Например:

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
var YourSubClass = new Class({
     
    Implements: Events, //here we tell MooTools to implement Events in our sub class (this wont effect the bass «YourClass»)
     
    Extends: YourClass,
 
    variable2: false,
 
    initialize: function(){
        this.parent();
    },
     
    toggleVariable: function(){
        this.variable1 = !variable1;
        this.variable2 = !this.variable1;
        //afterToggle() — calling «afterToggle» would have made this function a necessary include of YourSubClass
        this.fireEvent(‘toggled’);
    }
});
 
var yourSubClassInstance = new YourSubClass();
 
var afterToggle = function(){
    alert(‘i\’ve just been toggled!’);
};
 
//here we add a listener for the custom event, just like we would any other event
yourSubClassInstance.addEvent(‘toggled’, afterToggle);

Помимо событий, вы часто захотите реализовать опции 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
var YourSubClass = new Class({
     
    //One of the many cool things about the implements property is that it excepts an array.
    Implements: [Events,Options], //Here we include Options
     
    Extends: YourClass,
 
    //options are set if the invoker does not explicitly specify a value.
    options: {
        variable2: false
    },
     
    initialize: function(options){
        this.setOptions(options);
        this.parent();
    },
     
    toggleVariable: function(){
        this.variable1 = !variable1;
        this.options.variable2 = !this.variable1;
        this.fireEvent(‘toggled’);
    }
});
 
// this will start the class with variable2 = true.
var yourSubClassInstance = new YourSubClass({
    variable2: true
});

шаг 6

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

1
2
3
4
5
6
7
8
9
var global = true;
 
var aFunction = function(){
    var local = true;
}
 
$(‘button’).addEvent(‘click’, function(){
    this.addClass(‘clicked’);
});

При ссылке на переменную в вашем коде JavaScript выдувается из текущей исполняемой позиции через все доступные уровни переменных, пока не обнаружит первое и ближайшее совпадение положительного совпадения. Такое поведение часто менее чем желательно, особенно когда имеешь дело с событиями внутри литералов объекта, поскольку они содержат свои собственные ссылки. Часто разработчики полагаются на так называемые «лексические замыкания», чтобы обойти подобные проблемы, сохраняя собственную ссылку в переменной с другим именем. Тем не менее, MooTools предоставляет альтернативные средства для достижения этой цели с помощью метода bind (), который не только чище, но и намного элегантнее. Рассмотрим пример ниже:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
 
    addEvents: function(){
        $(‘button’).addEvent(‘click’, function(){
            //binding substitutes the current self reference for that of the object passed in
            this.toggleVariable();
        }.bind(this));
    },
     
    toggleVariable: function(){
        //code
    },
     

шаг 7

В приведенном выше примере мы нацелились на уже существующий элемент в DOM и добавили к нему прослушиватель событий. Однако сегодня не редкость, когда целые веб-приложения загружают свой контент динамически с использованием JavaScript. С развитием JSON возможность генерировать разметку на лету становится все более необходимой. Введите конструктор элемента MooTools. Новым в этом конструкторе является то, что он поддерживает читабельность, несмотря на большую емкость для дополнительных свойств (опять же, благодаря буквенной нотации объекта!). Элемент принимает объект событий, объект стилей, а также любые отдельные свойства, такие как class, id, src, href, title и т. Д. При этом он также загружен множеством методов, полный список которых доступен в документации MooTools. здесь Ниже приведен простой пример того, как начать:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
var el = new Element(‘div’, {
    id: ‘button’,
    ‘html’: ‘hellloooo’,
    styles: {
        display: ‘block’,
        position: ‘relative’,
        float: ‘left
    },
    events: {
        click: function(){
            //your code
        }
    }
});

шаг 8

Теперь, когда у вас есть свой динамический элемент, не было бы замечательно вставить его в DOM? MooTools предоставляет действительно удобный список методов для этого, включая:

  • inject — помещает один элемент относительно вызывающего элемента: ‘before’, ‘after’, ‘top’, ‘bottom’
  • захватить — как впрыскивать, но наоборот
  • принять — работает как захват принять, он может принять массив элементов, и вы не можете указать точное отношение
  • обертывания — работает как захват, но вместо перемещения захваченного элемента с его места, этот метод перемещает этот элемент вокруг своей цели

Из этих методов я обнаружил, что способность accept принимает массив элементов абсолютно незаменим, особенно при структурировании больших количеств динамической разметки. Рассмотрим пример ниже:

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
var el = new Element(‘div’, {
    id: ‘button’,
    styles: {
        display: ‘block’,
        position: ‘relative’,
        float: ‘left
    },
    events: {
        click: function(){
            //your code
        }
    }
}).adopt(
 
    this.createSpan(), // returns an element which can later be overwritten by a subclass
     
    new Element(‘a’, {
        href: ‘http://somewebsite.com’
    }).adopt(
     
        new Element(‘strong’, {
            ‘html’: ‘world’
        })
         
    )
).inject($(document.body),’top’);

Приведенный выше пример создает действительно объектно-ориентированный подход к манипулированию DOM. Когда вы станете супер-ниндзя, джедаем, джанки, ботаником, MooTools, вы можете использовать описанный выше метод, чтобы начать абстрагирование функций, которые возвращают элементы или массивы элементов, что позволяет вашим подклассам нацеливаться на конкретные методы при изменении вашего отображения. Потрясающие.


шаг 9

JavaScript Object Notation или JSON — это легкий формат обмена данными, который всем нравится (особенно после работы с XML). Самое замечательное в JSON, конечно, то, что его структура изначально распознается JavaScript, а многие крупные сайты открывают свои данные для публики через API, на самом деле нет причин, по которым вы не должны тратить время на знакомство с ним. Больше не является кошмарным кросс-браузерным кошмаром, независимо от того, отправляете ли вы данные в бэкэнд-сервис или запрашиваете еще одну порцию твитов из твиттера, конструктор MooTools Request делает JSON и JSONP невероятно простыми. Он работает с несколькими прослушивателями событий и недавно истек тайм-аут, который совершенно необходим, как только вы начинаете входить в JSONP. (Что вам и нужно! Это так весело.) Вот простой пример:

1
2
3
4
5
6
7
8
9
var JSONRequest = new Request.JSON({
    url: «http://yoursite.com/tellMeSomething.php»,
    onFailure: function(){
        alert(‘oh nooo!’);
    },
    onSuccess: function(response){
        alert(‘hooray!: ‘ + response.result);
    }
});

шаг 10

На высоком уровне конструктор Fx позволяет изменять любое свойство CSS элемента HTML, который сам принимает один элемент и ряд необязательных свойств (длительность, тип перехода и т. Д.) Для создания плавных эффектов анимации цветов, слайдов. , прокрутки и т. д. Более того, конструктор Fx полностью совместим с уравнениями Облегчения Роберта Пеннера, которые являются отличным способом добавить нотку уникальности для ваших переходов, таких как отскок, упругость, грех и т. д.

Если вы « хардкор », вы можете добиться всех эффектов анимации, используя Fx.Tween (анимация в стиле css) или Fx.Morph (несколько одновременных анимаций в стиле). Конечно, помимо них есть Fx.Slide, Fx.Scroll, Fx.Accordian и т. Д. Вот простой пример использования Fx.Tween:

1
2
var myFx = new Fx.Tween($(‘button’));
myFx.start(‘background-color’, ‘#000’, ‘#f00’);

Если вам не хочется углубляться в эту тему, ознакомьтесь с учебником по FX для Open, чтобы получить достаточно полное введение в конструктор.


шаг 11

Первоначально появившись в необычной загрузке Digitarald, объект Swiff позволяет JavaScript вашей страницы взаимодействовать с Flash. Это значительно упрощает взаимодействие с уникальными функциями Flash, такими как видео, звук, потоковая передача файлов и функции доступа к буферу обмена. Более того, Swiff позволяет передавать значения и управлять Flash-фильмом, используя соглашения, знакомые вам по JavaScript и Mootools. Интеграция флэш-памяти таким образом особенно полезна, поскольку мы начинаем предпринимать шаги к тому, чтобы предлагать HTML5 в качестве прогрессивного усовершенствования, где, если у пользователя нет плагина Flash, Swiff можно использовать для управления аудио или видео в старых браузерах. Между тем, проверьте простой пример ниже:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
var flashObject = new Swiff(‘sounds.swf’, {
    id: ‘mySoundManager’,
    width: 1,
    height: 1,
    vars: {
        myVariable: true, //pass variables into flash on load
    },
    callBacks: {
        //call custom events from your flash object
        someEvent: function(){
            //code
        }
    }
});
 
Swiff.remote(flashObject, ‘playMySound’) //calls the function «playMySound» from within flash

шаг 12

Теперь, когда более пятнадцати участников внесли свой вклад в официальный репозиторий плагинов и более ста неофициальных плагинов уже в Forge, неудивительно, что «Сообщество» — это то, что команда MooTools хотела, чтобы мы, разработчики, забрали с 2009 года. Действительно, люди действительно приняли это Framework, и теперь с Forge у нас есть отличное место, чтобы встретиться и начать делиться идеями. Вы найдете Дэвида Уолша, Аарона Ньютона, 3n и многих других, активно вносящих удивительный код и создающих среду, способную вдохновлять и приносить пользу. В конце концов, самый полезный способ выбрать среду MooTools — это взаимодействовать с разработчиками вокруг вас и в конечном итоге понимать, над чем они работают и как они это делают.

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

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

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