Дважды в месяц мы возвращаемся к любимым постам наших читателей на протяжении всей истории Nettuts +. Этот учебник был впервые опубликован в феврале 2010 года.
MooTools — одна из самых гибких, модульных и хорошо написанных сред JavaScript. Так много людей используют его, но многие из них не оптимизируют свой код. В этом посте вы найдете пятнадцать простых советов, которые помогут сделать ваш код MooTools короче, быстрее и эффективнее.
1.Создайте свой собственный MooTools, создавайте или извлекайте из библиотек Google AJAX
Одним из больших преимуществ использования MooTools является то, что он невероятно модульный. Что это обозначает? Почти ничего не требуется, если вам это не нужно. Преимущество модульности MooTools заключается в том, что ваша ограниченная пользовательская сборка MooTools может сократить время загрузки JavaScript.
Хотите создать собственную сборку MooTools для вашего следующего проекта? Следуй этим шагам:
- Зайдите на http://mootools.net/core (и / или http://mootools.net/more, если вы хотите дополнительные плагины)
- Выберите плагины по вашему выбору. Не беспокойтесь об учете зависимостей — разработчик плагинов сделает это за вас!
- Выберите вариант сжатия по вашему выбору — YUI Compressor предоставит вам наименьшую возможную сборку MooTools
Это оно! Однако иногда вашему проекту требуется вся библиотека MooTools Core. В этом случае ваш сайт может сэкономить тысячи
запросов в день с помощью библиотек Google AJAX завершить сборку MooTools. Вы можете сделать это двумя способами:
<script type = "text / javascript" src = "http://ajax.googleapis.com/ajax/libs/mootools/1.2.4/mootools-yui-compressed.js"> </ script>
Этот первый метод просто включает MooTools на страницу в обычном режиме. Второй метод обеспечивает большую функциональность и производительность:
1
2
3
4
|
<script src=»http://www.google.com/jsapi»></script>
<script type=»text/javascript»>
google.load(«mootools», «1.2.4»);
</script>
|
Преимущество использования API библиотек Google AJAX заключается в том, что если другой веб-сайт использует API библиотек AJAX, эта версия MooTools уже кэшируется в их браузере, и сайт будет загружаться быстрее!
2. Используйте jQuery и MooTools вместе
Хотя лучше придерживаться одной библиотеки на данной странице, чтобы избежать лишних затрат, иногда вам не избежать множества фреймворков.
К счастью, MooTools может сосуществовать с любыми JavaScript-инфраструктурами, не основанными на прототипах. Вот как вы можете использовать jQuery и MooTools на одной странице:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
<!— jquery gets the «$» method —>
<script type=»text/javascript» src=»jquery-1.4.js» />
<!— mootools doesn’t steal the «$» method;
<script type=»text/javascript» src=»mootools.js» />
<!— let’s use them —>
<script type=»text/javascript»>
//with jquery, grab all links, make then red
$(‘a’).css(‘color’,’red’);
//with mootools, get the content div, set it’s background color to pink
document.id(‘content’).setStyle(‘background’,’pink’);
//with mootools, get the content div, set it’s background color to pink
//this time, we’ll give mootools the «$» method
(function($) {
$(‘content’).setStyle(‘background’,’pink’);
})(document.id);
</script>
|
Благодаря долларовому безопасному режиму MooTools, MooTools больше не использует метод «$», если он уже используется!
3. Сохраните элементы и коллекции элементов
Разработчикам часто нужно собирать один элемент или набор элементов. Например, вам может понадобиться захватить все элементы А на странице, изменить их цвет и создать из них всплывающие подсказки.
// захватить ссылки, изменить цвет * / $$ ('# footer a'). setStyle ('color', '# f00'); // сделать ссылки всплывающими подсказками var tippers = new Tips ($$ ('# footer a'));
Код выше крайне неэффективен. Зачем запрашивать DOM дважды (с $$), если вы можете собрать все элементы один раз? Давайте сделаем это более эффективным:
// "сохранить" ссылки в переменную var links = $$ ('# footer a'); // захватить ссылки, изменить цвет * / links.setStyle ( 'цвет', '# f00'); // сделать ссылки всплывающими подсказками var tippers = new Tips (ссылки);
Вы можете сделать это еще короче, но это не так легко читается:
var tippers = new Tips ($$ ('# footer a'). setStyle ('color', '# f00'));
Читаемость важна, поэтому я бы не советовал кодировать таким образом, если вы работаете с командой.
4. Используйте методы элементов в коллекциях элементов
Циклический просмотр массива элементов не является уникальным для любой платформы JavaScript:
// для каждой ссылки ... $$ ('a'). each (function (a) { // добавляем ссылку на элемент a.addEvents ({ mouseenter: function () {// анимация вправо if (! a.retrieve ('oPad')) {a.store ('oPad', a.getStyle ('padding-left'))); } a.tween ( 'обивка левый', 30); }, mouseleave: function () {// анимация назад влево a.tween ( 'обивка левый', a.retrieve ( 'oPad')); } }); });
Многие разработчики не знают, что в коллекциях Element используются те же методы, что и в Elements, поэтому не нужно их циклически проходить — просто примените желаемую функциональность к коллекции:
$$ ( 'а'). AddEvents ({ mouseenter: function () {// анимация вправо if (! this.retrieve ('oPad')) {this.store ('oPad', this.getStyle ('padding-left'))); } this.tween ( 'обивки левой', 30); }, mouseleave: function () {// анимация назад влево this.tween ( 'обивки левой', this.retrieve ( 'oPad')); } });
Обратите внимание, что ключевое слово «this» используется для ссылки на текущий элемент в коллекции, а не на саму коллекцию.
5. Используйте MooTools Alias
Метод «псевдоним» MooTools позволяет переименовывать или псевдоним существующего метода. Возьмите следующий фрагмент кода, который в настоящее время находится в исходном коде MooTools Core:
Array.alias ('forEach', 'each');
Приведенный выше код позволяет вам вызывать each
метод вместо forEach
. Использование each
них более читабельно, тихий стандарт между большинством JavaScript-фреймворков, и даже экономит несколько байт в вашем коде. Если вы предпочитаете давать собственные методы MooTools ‘Native или Class’, не стесняйтесь!
Например, метод Element Class для удаления элемента из DOM:
$ ( 'MyElement') распоряжаться ().
Предположим, что ваше веб-приложение посвящено определенной теме, и вы хотите придерживаться этой терминологии для своего кода. Вот несколько примеров:
Element.alias ( 'Dispose', 'может'); // сайт карьеры? Element.alias ( 'распоряжаться', 'голень'); // тюремный сайт?
Какими бы ни были ваши причины для вызова метода с другим именем, просто не бойтесь этого делать!
6. Создание пользовательских псевдо-селекторов
Доступ к коллекции элементов в DOM является основной обязанностью любой платформы JavaScript. К сожалению, это также может облагать налогом, и требуемые псевдо-селекторы не всегда доступны. К счастью, MooTools позволяет легко реализовать ваши собственные псевдо-селекторы! Давайте
создайте псевдоселектор с именем «disabled», который возвращает элемент, если он отключен.
// захватить отключенные элементы Selectors.Pseudo.disabled = function () { вернуть this.disabled; } // как ты это используешь var disabledInputs = $$ ('input: disabled');
Просто добавьте ваш селектор в объект Selectors.Pseudo. Если новая псевдо-функция возвращает «истина», элемент соответствует и будет возвращен.
Определение ваших собственных псевдо-селекторов — отличный способ контролировать ваши селекторы!
7. Реализуйте методы на существующих объектах
Философия MooTools заключается в том, что допустимо и даже рекомендуется модифицировать собственные прототипы (String, Function, Number и т. Д.), Когда это необходимо.
Внедрение новых методов на этих аборигенах даст им еще больше возможностей. Давайте создадим метод String, который превратит любую строку текста в
Формат «твит» (добавьте ссылки для @ reply, ссылок и т. д.):
String.implement ({ toTweet: function () { вернуть this.replace (/ (https?: \ / \ / \ S +) / gi, '<a href="$1"> $ 1 </a>') .replace (/ (^ | \ s) @ (\ w + ) / g, '$ 1 <a href="http://twitter.com/$2"> @ $ 2 </a>') .replace (/ (^ | \ s) # (\ w +) / g, '$ 1 <a href="http://search.twitter.com/search?q=%23$2"> # $ 2 </a> '); } });
Теперь вы можете вызвать «toTweet» для любой строки, и вы получите строку обратно как «твит». Вот несколько примеров:
// установить html элемента в значение твита var el = $ ('myElement'); el.set ( 'HTML', el.get ( 'HTML') toTweet ().); // устанавливает html элемента в связанное значение твита. // оповещаем твитируемое значение alert ('Yo @NetTuts, зайдите на мой сайт #MooTools: http: //davidwalsh.name'.toTweet ()); // оповещения: Yo <a href="http://twitter.com/nettuts"> @NetTuts </a>, посмотрите мой <a href = "http://search.twitter.com/search?q= Сайт% 23MooTools "> MooTools </a>: <a href="http://davidwalsh.name"> http://davidwalsh.name </a>
Реализация пользовательских методов на объектах усиливает каждый существующий и будущий экземпляр этого объекта.
8. Расширение существующих классов
Философия ООП MooTools предусматривает сверхмощную модель наследования. Расширение существующих классов позволяет избежать повторения кода, расширить возможности существующих объектов и использовать существующие функциональные возможности. MooTools Core, More и ваши пользовательские классы расширяют существующие функциональные возможности. Рассмотрим класс Request
:
var Request = новый класс ({ Реализует: [Цепочка, События, Опции], параметры: {/* onRequest: $ пусто, onComplete: $ пусто, onCancel: $ пусто, onSuccess: $ пусто, onFailure: $ пусто, onException: $ пусто, * / URL: '', данные: '', заголовки: { 'X-Requested-With': 'XMLHttpRequest', «Принять»: «текст / JavaScript, текст / HTML, приложение / XML, текст / XML, * / *» }, асинхронно: верно, формат: ложь, метод: «пост», ссылка: «игнорировать», isSuccess: null, эмуляция: правда, urlEncoded: правда, кодировка: 'utf-8', evalScripts: false, evalResponse: ложь, noCache: ложь }, initialize: function (options) { this.xhr = new Browser.Request (); this.setOptions (варианты); this.options.isSuccess = this.options.isSuccess || this.isSuccess; this.headers = new Hash (this.options.headers); }, onStateChange: function () { if (this.xhr.readyState! = 4 ||! this.running) return; this.running = false; this.status = 0; $ Попытка (функция () { this.status = this.xhr.status; } .Bind (это)); this.xhr.onreadystatechange = $ empty; if (this.options.isSuccess.call (this, this.status)) { this.response = {text: this.xhr.responseText, xml: this.xhr.responseXML}; this.success (this.response.text, this.response.xml); } еще { this.response = {text: null, xml: null}; this.failure (); } }, isSuccess: function () { return ((this.status> = 200) && (this.status <300)); }, processScripts: function (text) { if (this.options.evalResponse || (/(ecma|java)script/).test(this.getHeader('Content-type '))) return $ exec (text); вернуть text.stripScripts (this.options.evalScripts); }, success: function (text, xml) { this.onSuccess (this.processScripts (text), xml); }, onSuccess: function () { this.fireEvent ('complete', arguments) .fireEvent ('success', arguments) .callChain (); }, сбой: функция () { this.onFailure (); }, onFailure: function () { this.fireEvent ('complete'). fireEvent ('fail', this.xhr); }, setHeader: function (name, value) { this.headers.set (имя, значение); верни это; }, getHeader: function (name) { вернуть $ try (function () { вернуть this.xhr.getResponseHeader (name); } .Bind (это)); }, check: function () { if (! this.running) возвращает true; switch (this.options.link) { case 'cancel': this.cancel (); вернуть истину; case 'chain': this.chain (this.caller.bind (this, arguments)); вернуть ложь; } вернуть ложь; }, отправить: функция (опции) { if (! this.check (options)) возвращает this; this.running = true; var type = $ type (параметры); if (type == 'string' || type == 'element') options = {data: options}; var old = this.options; options = $ extended ({data: old.data, url: old.url, метод: old.method}, options); var data = options.data, url = String (options.url), method = options.method.toLowerCase (); switch ($ type (data)) { case 'element': data = document.id (data) .toQueryString (); перемена; case 'object': case 'hash': data = Hash.toQueryString (data); } if (this.options.format) { var format = 'format =' + this.options.format; данные = (данные)? формат + '&' + данные: формат; } if (this.options.emulation &&! ['get', 'post']. содержит (метод)) { var _method = '_method =' + method; данные = (данные)? _method + '&' + data: _method; method = 'post'; } if (this.options.urlEncoded && method == 'post') { var encoding = (this.options.encoding)? «; charset = '+ this.options.encoding:' '; this.headers.set ('Content-type', 'application / x-www-form-urlencoded' + кодировка); } if (this.options.noCache) { var noCache = 'noCache =' + new Date (). getTime (); данные = (данные)? noCache + '&' + data: noCache; } var trimPosition = url.lastIndexOf ('/'); if (trimPosition> -1 && (trimPosition = url.indexOf ('#'))> -1) url = url.substr (0, trimPosition); if (data && method == 'get') { url = url + (url.contains ('?')? '&': '?') + data; данные = ноль; } this.xhr.open (method.toUpperCase (), url, this.options.async); this.xhr.onreadystatechange = this.onStateChange.bind (this); this.headers.each (function (value, key) { пытаться { this.xhr.setRequestHeader (ключ, значение); } catch (e) { this.fireEvent ('исключение', [ключ, значение]); } }, это); this.fireEvent ( 'запрос'); this.xhr.send (данные); if (! this.options.async) this.onStateChange (); верни это; }, отмена: функция () { if (! this.running) вернуть this; this.running = false; this.xhr.abort (); this.xhr.onreadystatechange = $ empty; this.xhr = new Browser.Request (); this.fireEvent ( 'отмена'); верни это; } });
Затем рассмотрим Request.JSONP, который расширяет Request:
Request.JSON = новый класс ({ Расширяется: запрос, параметры: { безопасный: правда }, initialize: function (options) { this.parent (варианты); this.headers.extend ({'Accept': 'application / json', 'X-Request': 'JSON'}); }, success: function (text) { this.response.json = JSON.decode (text, this.options.secure); this.onSuccess (this.response.json, текст); } });
Вы видите, насколько мал класс Request.JSONP
? При добавлении Extends: Request
класс Request.JSONP
получает все методы класса запросов. По сути, этот небольшой фрагмент кода становится мощным, потому что он расширяет Request
. Вы даже можете добавить расширения к расширениям. Теперь рассмотрим Request.JSONP
а затем класс Request.Twitter
Скотта Кайла :
//Request.JSONP / * --- скрипт: Request.JSONP.js description: Определяет Request.JSONP, класс для междоменного JavaScript через внедрение скрипта. лицензия: лицензия в стиле MIT авторы: - Аарон Ньютон - Гильермо Раух требует: - ядро: 1.2.4 / элемент - ядро: 1.2.4 / Запрос - /Журнал обеспечивает: [Request.JSONP] ... * / Request.JSONP = новый класс ({ Реализует: [Цепочка, События, Опции, Журнал], параметры: {/* onRetry: $ empty (intRetries), onRequest: $ empty (scriptElement), onComplete: $ empty (данные), onSuccess: $ empty (данные), onCancel: $ empty (), log: false, * / URL: '', данные: {}, повторные попытки: 0, время ожидания: 0, ссылка: «игнорировать», callbackKey: 'callback', injectScript: document.head }, initialize: function (options) { this.setOptions (варианты); if (this.options.log) this.enableLog (); this.running = false; this.requests = 0; this.triesRemaining = []; }, check: function () { if (! this.running) возвращает true; switch (this.options.link) { case 'cancel': this.cancel (); вернуть истину; case 'chain': this.chain (this.caller.bind (this, arguments)); вернуть ложь; } вернуть ложь; }, отправить: функция (опции) { if (! $ chk (arguments [1]) &&! this.check (options)) возвращает this; var type = $ type (параметры), old = this.options, index = $ chk (arguments [1])? Аргументы [1]: this.requests ++; if (type == 'string' || type == 'element') options = {data: options}; options = $ extended ({data: old.data, url: old.url}, options); if (! $ chk (this.triesRemaining [index])) this.triesRemaining [index] = this.options.retries; var оставшийся = this.triesRemaining [index]; (Функция () { var script = this.getScript (параметры); this.log ('скрипт извлечения JSONP с URL:' + script.get ('src')); this.fireEvent ('request', script); this.running = true; (Функция () { если (осталось) { this.triesRemaining [index] = оставшиеся - 1; if (script) { script.destroy (); this.send (options, index) .fireEvent ('retry', this.triesRemaining [index]); } } else if (script && this.options.timeout) { script.destroy (); . This.cancel () fireEvent ( 'неудача'); } }). задержка (this.options.timeout, this); }). задержка (Browser.Engine.trident? 50: 0, это); верни это; }, отмена: функция () { if (! this.running) вернуть this; this.running = false; this.fireEvent ( 'отмена'); верни это; }, getScript: function (options) { var index = Request.JSONP.counter, данные; Request.JSONP.counter ++; switch ($ type (options.data)) { case 'element': data = document.id (options.data) .toQueryString (); перемена; case 'object': case 'hash': data = Hash.toQueryString (options.data); } var src = options.url + (options.url.test ('\\?')? '&': '?') + (options.callbackKey || this.options.callbackKey) + '= Request.JSONP.request_map.request _' + index + (данные? '&' + data: ''); if (src.length> 2083) this.log ('JSONP' + src + 'завершится ошибкой в Internet Explorer, который устанавливает ограничение длины в 2083 байта для URI'); var script = новый элемент ('script', {type: 'text / javascript', src: src}); Request.JSONP.request_map ['request_' + index] = function () {this.success (arguments, script); } .Bind (это); return script.inject (this.options.injectScript); }, success: function (args, script) { if (script) script.destroy (); this.running = false; this.log ('JSONP успешно получен:', args); this.fireEvent ('complete', args) .fireEvent ('success', args) .callChain (); } }); Request.JSONP.counter = 0; Request.JSONP.request_map = {};
… и теперь Request.Twitter:
Request.Twitter = new Class ({ Расширяется: Request.JSONP, параметры: { linkify: правда, URL: 'http://twitter.com/statuses/user_timeline/ndomterm‹.json', данные: { Количество: 5 } }, initialize: function (term, options) { this.parent (варианты); this.options.url = this.options.url.substitute ({термин: термин}); }, success: function (data, script) { if (this.options.linkify) data.each (function (tweet) { tweet.text = this.linkify (tweet.text); }, это); // сохранить последующие вызовы новее if (data [0]) this.options.data.since_id = data [0] .id; this.parent (данные, скрипт); }, linkify: function (text) { // изменено из TwitterGitter Дэвидом Уолшем (davidwalsh.name) // предоставлено Джереми Пэрришем (rrish.org) вернуть text.replace (/ (https?: \ / \ / [\ w \ -:;? & = +.% # \ /] +) / gi, '<a href="$1"> $ 1 </a> «) .replace (/ (^ | \ W) @ (\ w +) / g, '$ 1 <a href="http://twitter.com/$2"> @ $ 2 </a>') .replace (/ (^ | \ W) # (\ w +) / g, '$ 1 # <a href="http://search.twitter.com/search?q=%23$2"> $ 2 </a> «); } });
Вы видите, как эффект водопада от расширения объектов может сделать самых маленьких классов абсолютным зверем в классе?
Поэкспериментируйте с моделью наследования MooTools и не повторяйте код!
9. Создание пользовательских событий
Я уже объяснил, насколько гибок механизм выбора MooTools, система классов и насколько модульна структура. 1 Почему вы ожидаете чего-то отличного от системы событий MooTools? Создание пользовательских событий в MooTools настолько просто, насколько это возможно. Вот основная схема вашего пользовательского события MooTools:
Element.Events.altClick = { base: 'click', // событие "base" условие: функция (событие) { возвращение event.alt; // Alt Key? }, onAdd: function () { // сделать что-то, когда событие добавлено }, onRemove: function () { // сделать что-нибудь, когда событие удалено } };
Вот отличный пример пользовательского события — прослушивание «alt» и «click» одновременно:
// Alt Click Element.Events.altClick = { база: «клик», условие: функция (событие) { возвращение event.alt; // Alt Key? } }; //использование $ (document.body) .addEvent ('altClick', function () { alert («Вы меня щелкнули!»); });
Или вы можете просто определить пользовательское событие, чтобы определенная функция выполнялась каждый раз, когда назначается этот тип события. В моем следующем примере, каждый раз, когда событие клика назначается элементу, курсор этого элемента будет автоматически заменен на курсор «указатель».
/ * обновить курсор при добавлении / удалении события клика * / Element.Events.click = { Основание: «нажмите», onAdd: function () { if (this.setStyle) { this.store ( 'оригинал-курсор', this.getStyle ( 'курсор')); this.setStyle ( 'курсор', 'указатель'); } }, onRemove: function () { if (this.setStyle) { this.setStyle ( 'курсор', this.retrieve ( 'оригинал-курсор')); } } };
Вы заметите, что если событие click удаляется, оригинальный курсор будет восстановлен.
10. События в стиле jQuery
Хотя синтаксис события MooTools отличается от синтаксиса jQuery, это не обязательно должно быть! С минимальным количеством JavaScript вы можете сделать так, чтобы синтаксис событий MooTools отражал jQuery.
MooTools хранит все свои события в объекте Element.NativeElements
:
Element.NativeEvents = { click: 2, dblclick: 2, mouseup: 2, mousedown: 2, contextmenu: 2, // кнопки мыши колесо мыши: 2, DOMMouseScroll: 2, // колесо мыши mouseover: 2, mouseout: 2, mousemove: 2, selectstart: 2, selectend: 2, // движение мыши клавиша: 2, клавиша: 2, клавиша: 2, // клавиатура фокус: 2, размытие: 2, изменение: 2, сброс: 2, выбор: 2, отправка: 2, // элементы формы загрузка: 1, выгрузка: 1, до загрузки: 2, изменение размера: 1, перемещение: 1, DOMContentLoaded: 1, readystatechange: 1, // окно ошибка: 1, отмена: 1, прокрутка: 1 // разное };
По сути, все, что вам нужно сделать, — это циклически проходить по каждому типу элемента и реализовывать метод класса Element, называемый как тип события
это имитирует то, что делает addEvent:
// хешируем element.natives, чтобы вы могли с ним что-то делать var hash = new Hash (Element.NativeEvents); // удаляем элементы которые нужно заменить, добавляем их замены hash.erase ( 'Mouseover') Стирание ( 'MouseOut') Стирание ( 'DOMMouseScroll')..; hash.include ( 'MouseEnter', 1) .include ( 'MouseLeave', 1); // инициализируем это var eventHash = new Hash ({}); // для каждого типа события добавляем в хеш hash.getKeys (). каждая (функция (событие) { eventHash [event] = function (fn) { this.addEvent (событие, п); верни это; }; }); //Сделай это Element.implement (eventHash);
Теперь вы можете слушать такие события, как:
$ ('myElement'). click (function () { // делать вещи });
11. Добавить события при создании элемента
Если у вас есть опыт программирования с MooTools, в какой-то момент вы, без сомнения, создали элемент и впоследствии добавили к нему события:
var myElement = новый элемент ('a', { href: 'mypage.php', текст: «Нажмите здесь!» }); myElement.addEvent ('click', function (e) { // остановить событие if (e) e.stop (); // делать вещи });
Можно сказать, что в этом нет ничего плохого, но вы можете просто добавить эти события во время создания элемента:
var myElement = новый элемент ('a', { href: 'mypage.php', текст: «Нажмите здесь!», События: { click: function () { // остановить событие if (e) e.stop (); // делать вещи } } });
12. Реализуйте события внутри классов
Продление классов обсуждалось в совете № 8 выше. Теперь давайте рассмотрим функциональность * реализовать * в классах MooTools. Какая разница? Участник MooTools Марк Обцена лучше всех говорит в своей статье под названием « The Moo Herd IV: для этого есть класс» :
MooTools имеет два встроенных мутатора: Расширяет и Реализует. Мутатор Extends берет переданное ему имя класса и заставляет новый класс наследовать непосредственно от него, в то время как Implements принимает переданный класс (или классы) и добавляет свои методы в новый класс (или смешивает их — таким образом, mixin).
Разница между расширением и реализацией, давайте вернемся к этому. Реализация событий в ваших классах MooTools может сделать ваши классы намного более гибкими. Рассмотрим следующий простой класс Overlay:
var Overlay = новый класс ({ Реализует: [Опции, События], параметры: { id: «оверлей», цвет: «# 000», продолжительность: 500, непрозрачность: 0,5, zIndex: 5000 }, initialize: function (контейнер, параметры) { this.setOptions (варианты); this.container = document.id (container); this.overlay = новый элемент ('div', { id: this.options.id, непрозрачность: 0, стили: { позиция: «абсолютная», background: this.options.color, осталось: 0, верх: 0, 'z-index': this.options.zIndex }, .}) Вводят (this.container); this.tween = new Fx.Tween (this.overlay, { длительность: this.options.duration, ссылка: «отмена», свойство: «непрозрачность», onStart: function () { this.overlay.setStyles ({ ширина: «100%», height: this.container.getScrollSize (). y }); } .Bind (это) }); }, open: function () { this.tween.start (this.options.opacity); верни это; }, close: function () { this.tween.start (0); верни это; } });
Конечно, класс делает то, что должен, но это не так гибко, как могло бы быть. Теперь давайте реализуем события onClick, onClose, onHide, onOpen и onShow:
var Overlay = новый класс ({ Реализует: [Опции, События], // СОБЫТИЯ ОСУЩЕСТВЛЯЮТСЯ ЗДЕСЬ! параметры: { id: «оверлей», цвет: «# 000», продолжительность: 500, непрозрачность: 0,5, zIndex: 5000 / *, onClick: $ пусто, onClose: $ пусто, onHide: $ пусто, onOpen: $ пусто, onShow: $ пусто * / }, initialize: function (контейнер, параметры) { this.setOptions (варианты); this.container = document.id (container); this.overlay = новый элемент ('div', { id: this.options.id, непрозрачность: 0, стили: { позиция: «абсолютная», background: this.options.color, осталось: 0, верх: 0, 'z-index': this.options.zIndex }, События: { click: function () {// НАЖМИТЕ СОБЫТИЕ this.fireEvent ( 'щелчок'); } .Bind (это) } .}) Вводят (this.container); this.tween = new Fx.Tween (this.overlay, { длительность: this.options.duration, ссылка: «отмена», свойство: «непрозрачность», onStart: function () { this.overlay.setStyles ({ ширина: «100%», height: this.container.getScrollSize (). y }); } .Bind (это), onComplete: function () { this.fireEvent (this.overlay.get ('opacity') == this.options.opacity? 'show': 'hide'); // ПОКАЗАТЬ ИЛИ СКРЫТЬ СОБЫТИЕ } .Bind (это) }); }, open: function () { this.fireEvent ( 'открытый'); // ОТКРЫТОЕ СОБЫТИЕ this.tween.start (this.options.opacity); верни это; }, close: function () { this.fireEvent ( 'закрыть'); // ЗАКРЫТЬ СОБЫТИЕ this.tween.start (0); верни это; } });
Что хорошего в добавлении событий в класс, так это то, что они позволяют вам предоставлять больше опций и запускать функциональность при выполнении наших методов класса. В приведенном выше примере вы можете выполнять любые функции, когда наложение открывается, закрывается, показывает, скрывает или щелкает.
По сути, вы добавили в класс два крошечных фрагмента кода:
Реализует: [События]
… и ниже, где бы вы ни хотели, чтобы событие было сигнализировано …
this.fireEvent ('someEvent', [аргумент1, аргумент2]);
Итак, как вы можете контролировать эти события при создании экземпляра класса? Добавьте их в опции, как это:
var overlay = new Overlay ({ onClick: function () { this.hide (); }, onOpen: function () { alert («Спасибо, что открыли!»); } });
Вам будет трудно найти класс, который не получит пользу от реализации событий!
13. Используйте делегирование событий
Делегирование событий — это процесс добавления события к родителю для всех его дочерних элементов вместо назначения события каждому отдельному дочернему элементу. Преимущество делегирования события заключается в том, что вы можете добавить дочерние элементы к родительскому элементу, не назначая событие этому новому элементу. Если вы решили удалить событие, вам нужно только удалить его из одного элемента.
Итак, вместо:
$$ ('a'). addEvent ('click', function () { // делать вещи - индивидуально назначенные });
…ты делаешь это:
$ ('myContainer'). addEvent ('click: relay (a)', function () { // присваивается родителю всех элементов A (в данном случае, #myContainer), чтобы прослушивать событие щелчка элемента A }) /
Не позволяйте псевдосинтаксису «: relay ()» одурачить вас; Element.Delegation переписывает методы события для: relay.
14. Используйте Class.toElement
Одним из скрытых камней в классе MooTools является метод Class.toElement. Class.toElement играет небольшую роль, но может помочь вам, когда дело доходит до доступа к первичному элементу в классе, особенно если вы не знаете, что это за элемент в противном случае. Реализовать toElement
в вашем классе легко:
var myClass = new Class ({ Реализует: [Опции], initialize: function (контейнер, параметры) { this.container = $ (контейнер); }, toElement: function () { вернуть this.container; } });
Как только вы определили toElement, вы можете использовать свой класс как элемент:
var myInstance = new MyClass ('myElement'); myInstance.setStyle ('color', '# f00'). set ('html', 'Это мой элемент!');
Посмотрите на это — класс, фактически управляемый методами Element.
15. «вернуть это» в рамках методов цепочки
Итак, мы все видели, как JavaScript-фреймворки позволяют вам чертовски цеплять методы. Цепочка выглядит так:
$ ('myElement'). setStyles ('color', '# f00'). set ('html', 'Click Here'). fade ('out'). addClass ('cssClass'). addEvent ('click' , функция (е) { if (e) e.stop (); предупреждение ( 'Клики'!); });
Святая цепочка Бэтмен! Хотите, чтобы ваши классы цеплялись всегда? Нет проблем — все, что вам нужно сделать, это вернуть « this
»:
var myClass = new Class ({ // параметры, инициализация, инструменты и т. д. doSomething: function () { // сделать целую кучу функций здесь и ... верни это; }, doAnotherThing: function () { // сделать целую кучу функций здесь и ... верни это; }, doYetAnotherThing: function () { // сделать целую кучу функций здесь и ... верни это. } });
Так как вы поместили return this
в каждом методе, теперь вы можете сделать:
var klass = new myClass (); . Klass.doSomething () doAnotherThing () doYetAnotherThing ().
Обязательно возвращайте this
везде, где это имеет смысл. Это может значительно облегчить работу с вашим Class
и ваш код будет короче!
БОНУС! Используйте Fx ярлыки на элементах
MooTools эффекты неоспоримо самый мягкий из любых рамок JavaScript. Библиотека Fx
также предоставляет множество возможностей управления через многочисленные опции. Давайте посмотрим на базовую анимацию, которая увядает элемент до 50%:
var myTween = new Fx.Tween ('myElement', { продолжительность: 500, кадр / с: 200, // здесь куча вариантов }); // исчезают до 50% $ ('myElement'). addEvent ('click', function () { myTween.start ( 'непрозрачности', 0,5); });
Знаете ли вы, что вам не нужно было печатать все это? Вы можете использовать ярлыки элементов, такие как:
$ ( 'MyElement') выцветанию (0,5). // исчезновение: Fx.Tween $ ( 'MyElement') Tween ( 'ширина', 300). // анимация движения: Fx.Tween $ ( 'MyElement'). Морф ({ ширина: 200, высота: 300 }); // morph: Fx.Morph
Вышеприведенные фрагменты, конечно, зависят от того, хотите ли вы использовать параметры по умолчанию. На самом деле вы можете установить пользовательские параметры для этих ярлыков для каждого элемента:
$ ('myElement'). set ('tween', {duration: 500, fps: 200}). tween ('width', 300);
Сохраните себя несколько байтов, используя Fx ярлыки!
MooTools FTW!
Надеюсь, я дал вам несколько советов, как улучшить код JavaScript MooTools, сделать его короче, быстрее и эффективнее. Есть какие-то свои собственные советы, чтобы поделиться? Разместите их в комментариях ниже!