Rendi il tuo codice MooTools più breve, più veloce e più forte

Due volte al mese, rivisitiamo alcuni dei post preferiti dei nostri lettori da tutta la storia di Nettuts +. Questo tutorial è stato pubblicato per la prima volta nel febbraio 2010.

MooTools è uno dei framework JavaScript più flessibili, modulari e ben scritti disponibili. Così tante persone lo usano ma molti di loro non ottimizzano il loro codice. Questo post ti fornirà quindici semplici suggerimenti per rendere il tuo codice MooTools più breve, più veloce e più forte.


1. Crea il tuo MooTools Build o Pull From Google AJAX Libraries

Uno dei grandi vantaggi dell'utilizzo di MooTools è che è incredibilmente modulare. Cosa significa? Quasi nulla è richiesto a meno che non ne abbiate bisogno. Il vantaggio della modularità di MooTools è che il tuo build MooTools personalizzato e limitato può far sì che il tempo di caricamento di JavaScript sia breve.

MooTools Core Builder

Vuoi creare un build personalizzato MooTools per il tuo prossimo progetto? Segui questi passi:

  • Vai a http://mootools.net/core (e / o http://mootools.net/more se desideri plug-in aggiuntivi)
  • Seleziona i plugin di tua scelta. Non preoccuparti di contabilizzare le dipendenze - il builder del plugin lo fa per te!
  • Seleziona l'opzione di compressione che preferisci: il compressore YUI fornirà a te la più piccola build possibile di MooTools

Questo è tutto! A volte, tuttavia, il tuo progetto richiede l'intera libreria MooTools Core. In tal caso, il tuo sito Web può salvarsi da solo migliaia
di richieste al giorno utilizzando le librerie AJAX di Google completano la compilazione di MooTools. Puoi fare questo in due modi:

Questo primo metodo include semplicemente MooTools nella pagina per normale. Il secondo metodo consente maggiori funzionalità e prestazioni:

 

La cosa fantastica dell'utilizzo dell'API delle librerie AJAX di Google è che se un altro sito Web utilizza l'API della libreria AJAX, quella versione di MooTools è già memorizzata nella cache del browser e il sito verrà caricato più velocemente!


2. Usa jQuery e MooTools insieme

Mentre è meglio attenersi a una libreria in una data pagina per evitare un sovraccarico, a volte non è possibile evitare di avere più framework.
Fortunatamente MooTools può coesistere con qualsiasi framework JavaScript non basato su prototipi. Ecco come puoi usare jQuery e MooTools nella stessa pagina:

 

Grazie a Dollar Safe Mode di MooTools, MooTools non assume più il metodo "$" se è già in uso!


3. Salva elementi ed elementi Collezioni

Gli sviluppatori spesso devono raccogliere un elemento o una raccolta di elementi. Ad esempio, potrebbe essere necessario prendere tutti gli elementi A all'interno della pagina, cambiarne il colore e creare suggerimenti da essi.

// seleziona i link, cambia colore * / $$ ('# footer a'). setStyle ('color', '# f00'); // make links tooltips var tippers = new Tips ($$ ('# footer a'));

Il codice sopra è gravemente inefficiente. Perché interrogare il DOM due volte (con $$) se è possibile raccogliere tutti gli elementi una volta? Rendiamolo più efficiente:

// "salva" i collegamenti in una variabile var links = $$ ('# footer a'); // seleziona i link, cambia colore * / links.setStyle ('color', '# f00'); // crea collegamenti tooltips var tippers = nuovi suggerimenti (collegamenti);

Potresti renderlo ancora più breve, ma non è così leggibile:

var tippers = new Tips ($$ ('# footer a'). setStyle ('color', '# f00'));

La leggibilità è importante, quindi non consiglierei di codificare in questo modo se lavori con una squadra.


4. Usa i metodi degli elementi sulle raccolte di elementi

Ciclare attraverso una serie di elementi non è univoco per qualsiasi framework JavaScript:

// per ogni collegamento ... $$ ('a'). each (function (a) // aggiungi il link che nudging all'elemento a.addEvents (mouseenter: function () // si anima a destra se (! a .retrieve ('oPad')) a.store ('oPad', a.getStyle ('padding-left')); a.tween ('padding-left', 30);, mouseleave: function () // ritorna a sinistra a.tween ('padding-left', a.retrieve ('oPad'));););

Quello che molti sviluppatori non sono consapevoli del fatto che le raccolte di elementi hanno gli stessi metodi di Elements, quindi non c'è bisogno di scorrerle tra loro - basta applicare la funzionalità desiderata alla raccolta:

$$ ('a'). addEvents (mouseenter: function () // si anima a destra se (! this.retrieve ('oPad')) this.store ('oPad', this.getStyle ('padding -left ')); this.tween (' padding-left ', 30);, mouseleave: function () // ritorna a sinistra this.tween (' padding-left ', this.retrieve (' oPad ')););

Si noti che la parola chiave "this" viene utilizzata per fare riferimento all'elemento "corrente" all'interno della raccolta, non alla raccolta stessa.


5. Usa MooTools Alias

Il metodo "alias" di MooTools consente di rinominare o alias un metodo esistente. Prendi il seguente snippet di codice che è attualmente nella fonte di MooTools Core:

Array.alias ('forEach', 'each');

Il codice sopra ti permette di chiamare il ogni metodo invece di per ciascuno. utilizzando ogni è più leggibile, uno standard silenzioso tra la maggior parte dei framework JavaScript, e consente anche di risparmiare pochi byte nel codice. Se si preferisce dare un nome personalizzato ai metodi nativi o di classe di MooTools, si senta libero di farlo!

Ad esempio, il metodo della classe Elemento per rimuovere un elemento dal DOM è:

$ ( 'MyElement') dispose ().;

Supponiamo che la tua app web riguardi un determinato argomento e desideri rimanere all'interno di tale terminologia per il tuo codice. Ecco alcuni esempi:

Element.alias ( 'disporre', 'can'); // sito di carriera? Element.alias ( 'disporre', 'gambo'); // sito del carcere?

Qualunque siano le tue ragioni per chiamare un metodo con un nome diverso, non aver paura di farlo!


6. Creare selettori di pseudo personalizzati

L'accesso a una raccolta di elementi nel DOM è una responsabilità principale di qualsiasi framework JavaScript. Sfortunatamente può anche essere tassativo e gli pseudo selettori che vuoi non sono sempre disponibili. Fortunatamente MooTools ti permette di implementare facilmente i tuoi pseudo selettori! Diamo
crea uno pseudo selettore denominato "disabled" che restituisce un elemento se è disabilitato.

// cattura elementi disabilitati Selectors.Pseudo.disabled = function () return this.disabled;  // come lo usi var disabledInputs = $$ ('input: disabled');

Basta aggiungere il selettore all'oggetto Selectors.Pseudo. Se la nuova funzione pseudo restituisce "true", l'elemento è una corrispondenza e verrà restituito.

Definire i propri pseudo selettori è un ottimo modo per prendere il controllo dei selettori!


7. Implementare metodi su oggetti esistenti

La filosofia di MooTools è che è accettabile, anche incoraggiato, modificare i prototipi nativi (String, Function, Number, ecc.) Quando necessario.
Implementare nuovi metodi su questi Nativi li rafforzerà ancora di più. Creiamo un metodo String che trasformi qualsiasi stringa di testo in
formato "tweet" (aggiungi link per @ reply's, links, ecc.):

String.implement (toTweet: function () return this.replace (/ (https?: \ / \ / \ S +) / gi, '$ 1'). Replace (/ (^ | \ s) @ (\ w +) /g,'$1@$2').replace(/(^|\s)#(\+)/g,'$1#$2 '););

Ora puoi chiamare "toTweet" su qualsiasi stringa e otterrai la stringa come "tweet". Ecco alcuni esempi:

// imposta l'html di un elemento su un valore tweet var el = $ ('myElement'); el.set ( 'html', el.get ( 'html') toTweet ().); // imposta l'html dell'elemento su un valore tweet collegato. // avvisare l'avviso del valore tweeted ('Yo @NetTuts, controlla il mio sito Web #MooTools: http: //davidwalsh.name'.toTweet ()); // avvisi: Yo @NetTuts, controlla il mio sito Web MooTools: http://davidwalsh.name

L'implementazione di metodi personalizzati su oggetti rafforza tutte le istanze esistenti e future di tale oggetto.


8. Estendere le classi esistenti

La filosofia OOP di MooTools consente un modello di ereditarietà superpotente. L'estensione delle classi esistenti consente di evitare la ripetizione del codice, potenziare gli oggetti esistenti e sfruttare le funzionalità esistenti. MooTools Core, More e le tue classi personalizzate estendono le funzionalità esistenti. Considera il Richiesta classe:

var Request = new Class (Implementa: [Chain, Events, Options], options: / * onRequest: $ vuoto, onComplete: $ vuoto, onCancel: $ vuoto, onSuccesso: $ vuoto, onFailure: $ vuoto, onException: $ vuoto, * / url: ", data:", intestazioni: 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'text / javascript, text / html, application / xml, text / xml, * / * ', async: true, formato: false, metodo:' post ', link:' ignore ', isSuccess: null, emulation: true, urlEncoded: true, encoding:' utf-8 ', evalScripts: false, evalResponse: false, noCache: false, initialize: function (options) this.xhr = new Browser.Request (); this.setOptions (options); this.options.isSuccess = this.options.isSuccess || this.isSuccess; .headers = new Hash (this.options.headers);, onStateChange: function () if (this.xhr.readyState! = 4 ||! this.running) return; this.running = false; this.status = 0; $ try (function () this.status = this.xhr.status; .bind (this)); this.xhr.onreadystatechange = $ vuoto; if (this.options.isSuccess.call (questo, questo. statistica us)) this.response = text: this.xhr.responseText, xml: this.xhr.responseXML; this.success (this.response.text, this.response.xml);  else 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); return 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(); , failure: function() this.onFailure(); , onFailure: function() this.fireEvent('complete').fireEvent('failure', this.xhr); , setHeader: function(name, value) this.headers.set(name, value); return this; , getHeader: function(name) return $try(function() return this.xhr.getResponseHeader(name); .bind(this)); , check: function() if (!this.running) return true; switch (this.options.link) case 'cancel': this.cancel(); return true; case 'chain': this.chain(this.caller.bind(this, arguments)); return false;  return false; , send: function(options) if (!this.check(options)) return this; this.running = true; var type = $type(options); if (type == 'string' || type == 'element') options = data: options; var old = this.options; options = $extend(data: old.data, url: old.url, method: 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(); break; case 'object': case 'hash': data = Hash.toQueryString(data);  if (this.options.format) var format = 'format=' + this.options.format; data = (data) ? format + '&' + data : format;  if (this.options.emulation && !['get', 'post'].contains(method)) var _method = '_method=' + method; data = (data) ? _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' + encoding);  if (this.options.noCache) var noCache = 'noCache=' + new Date().getTime(); data = (data) ? 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; data = null;  this.xhr.open (method.toUpperCase (), url, this.options.async); this.xhr.onreadystatechange = this.onStateChange.bind (this); this.headers.each (function (value, key) try this.xhr.setRequestHeader (chiave, valore); catch (e) this.fireEvent ('exception', [key, value]);, Questo); this.fireEvent ( 'richiesta'); this.xhr.send (dati); se (! this.options.async) this.onStateChange (); restituiscilo; , cancel: function () if (! this.running) restituisce questo; this.running = false; this.xhr.abort (); this.xhr.onreadystatechange = $ vuoto; this.xhr = new Browser.Request (); this.fireEvent ( 'cancellare'); restituiscilo; );

Quindi considera Request.JSONP, che estende la richiesta:

Request.JSON = new Class (Estende: Request, options: secure: true, initialize: function (options) this.parent (options); 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 , testo);  );

Vedete quanto è piccolo il Request.JSONP la classe è? Aggiungendo Estende: richiesta, il Request.JSONP la classe ottiene tutti i metodi della classe richiesta. Essenzialmente, questo piccolo frammento di codice diventa una centrale elettrica perché si estende Richiesta. È anche possibile aggiungere estensioni alle estensioni. Ora considera Request.JSONP e poi Scott Kyle's Request.Twitter classe:

//Request.JSONP / * --- script: Descrizione Request.JSONP.js: Definisce Request.JSONP, una classe per JavaScript cross-domain tramite script injection. licenza: autori di licenze in stile MIT: - Aaron Newton - Guillermo Rauch richiede: - core: 1.2.4 / Element - core: 1.2.4 / Request - / Log fornisce: [Request.JSONP] ... * / Request.JSONP = new Classe (Implementazioni: [Catena, Eventi, Opzioni, Log], opzioni: / * onRetry: $ vuoto (intRets), onRequest: $ vuoto (scriptElement), onComplete: $ vuoto (dati), onSuccesso: $ vuoto (dati ), onCancel: $ empty (), log: false, * / url: ", data: , tentativi: 0, timeout: 0, collegamento:" ignore ", callbackKey:" callback ", injectScript: document.head , initialize: function (options) this.setOptions (options); if (this.options.log) this.enableLog (); this.running = false; this.requests = 0; this.triesRemaining = [];, check: function () if (! this.running) return true; switch (this.options.link) case 'cancel': this.cancel (); restituisce true; case 'chain': this.chain (this. caller.bind (this, arguments)); return false; return false;, send: function (options) if (! $ chk (argomenti [1]) &&! this.check (opzioni)) restituisce questo; var tipo = $ tipo (opzioni ), vecchio = this.options, index = $ chk (argomenti [1])? argomenti [1]: this.requests ++; if (type == 'string' || type == 'element') options = data: options; options = $ extend (data: old.data, url: old.url, options); if (! $ chk (this.triesRemaining [index])) this.triesRemaining [index] = this.options.retries; var rimanente = this.triesRemaining [indice]; (function () var script = this.getScript (opzioni); this.log ('JSONP che recupera lo script con url:' + script.get ('src')); this.fireEvent ('richiesta', script); .running = true; (function () if (remaining) this.triesRemaining [index] = restante - 1; if (script) script.destroy (); this.send (options, index) .fireEvent ('retry ', this.triesRemaining [indice]); else if (script && this.options.timeout) script.destroy (); this.cancel (). fireEvent (' failure ');). delay (questo .options.timeout, this);). delay (Browser.Engine.trident? 50: 0, this); restituiscilo; , cancel: function () if (! this.running) restituisce questo; this.running = false; this.fireEvent ( 'cancellare'); restituiscilo; , getScript: function (options) var index = Request.JSONP.counter, data; Request.JSONP.counter ++; switch ($ type (options.data)) case 'element': data = document.id (options.data) .toQueryString (); rompere; caso 'oggetto': caso '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?' & '+ data: "); if (src.length> 2083) this.log (' JSONP '+ src +' fallirà in Internet Explorer, che impone una lunghezza di 2083 byte limite sugli URI '); var script = new Element (' script ', type:' text / javascript ', src: src); Request.JSONP.request_map [' request_ '+ index] = function () this. success (argomenti, script); .bind (this); return script.inject (this.options.injectScript);, success: function (args, script) if (script) script.destroy (); this.running = false; this.log ('JSONP ha recuperato con successo:', args); this.fireEvent ('complete', args) .fireEvent ('success', args) .callChain ();); Request.JSONP.counter = 0; Request.JSONP.request_map = ;

... e ora Request.Twitter:

Request.Twitter = new Class (Extends: Request.JSONP, options: linkify: true, url: 'http://twitter.com/statuses/user_timeline/term.json', data: count: 5 , initialize: function (term, options) this.parent (options); this.options.url = this.options.url.substitute (term: term);, success: function (data, script)  if (this.options.linkify) data.each (function (tweet) tweet.text = this.linkify (tweet.text); this); // mantiene le chiamate successive più nuove if (data [0]) this. options.data.since_id = data [0] .id; this.parent (data, script);, linkify: function (testo) // modificato da TwitterGitter da David Walsh (davidwalsh.name) // per gentile concessione di Jeremy Parrish (rrish.org) return text.replace (/ (https?: \ / \ / [\ w \ -:;? & = +.% # \ /] +) / gi, '$ 1') .replace (/ ( ^ | \ W) @ (\ w +) / g, '$ 1 @ $ 2') .replace (/ (^ | \ W) # (\ w +) / g, '$ 1 # $ 2'););

Vedete come un effetto cascata di estendere gli oggetti può rendere la classe più piccola una bestia assoluta di una classe?
Sperimenta con il modello di ereditarietà di MooTools e non ripetere il codice!


9. Crea eventi personalizzati

Ho già spiegato quanto sia flessibile il motore di selezione di MooTools, il sistema di classe è e quanto sia modulare il framework.1 Perché ti aspetteresti qualcosa di diverso dal sistema di eventi di MooTools? La creazione di eventi personalizzati all'interno di MooTools è tanto semplice quanto lo è. Ecco una descrizione di base dell'evento personalizzato MooTools:

Element.Events.altClick = base: 'click', // la condizione dell'evento "base": function (event) return event.alt; // tasto alt? , onAdd: function () // fa qualcosa quando viene aggiunto l'evento, onRemove: function () // fa qualcosa quando l'evento viene rimosso;

Ecco un ottimo esempio di un evento personalizzato: ascolto di "alt" e "clic" contemporaneamente:

// alt click Element.Events.altClick = base: 'click', condizione: function (event) return event.alt; // tasto alt? ; // usage $ (document.body) .addEvent ('altClick', function () alert ('Mi hai fatto alt-clic!'););

Oppure puoi semplicemente definire un evento personalizzato in modo che una funzione specifica venga eseguita ogni volta che viene assegnato quel tipo di evento. Nel mio prossimo esempio, ogni volta che un evento click viene assegnato a un elemento, il cursore di quell'elemento verrà automaticamente modificato nel cursore "puntatore".

/ * Aggiorna cursore su Aggiungi / Rimuovi evento click * / Element.Events.click = base: 'click', onAdd: function () if (this.setStyle) this.store ('original-cursor', this. getStyle ( 'cursore')); this.setStyle ( 'cursore', 'puntatore'); , onRemove: function () if (this.setStyle) this.setStyle ('cursor', this.retrieve ('original-cursor')); ;

Noterai che se l'evento click viene rimosso, il cursore originale verrà ripristinato.


10. Eventi in stile jQuery

Mentre la sytax degli eventi di MooTools è diversa da quella di jQuery, non deve essere così! Con una quantità minima di JavaScript puoi far sì che la sintassi dell'evento di MooTools rifletta jQuery.

MooTools tiene tutti i suoi eventi nel Element.NativeElements oggetto:

Element.NativeEvents = click: 2, dblclick: 2, mouseup: 2, mouse: 2, contextmenu: 2, // mouse buttons mousewheel: 2, DOMMouseScroll: 2, // mouse wheeloverover: 2, mouseout: 2, mousemove : 2, seleziona tart: 2, selectend: 2, // movimento del mouse keydown: 2, pressione del tasto: 2, keyup: 2, // keyboard focus: 2, blur: 2, modifica: 2, reset: 2, selezionare: 2, inviare: 2, // caricare gli elementi del modulo: 1, scaricare: 1, beforeunload: 2, ridimensionare: 1, spostare: 1, DOMContentLoaded: 1, readystatechange: 1, // errore della finestra: 1, abort: 1, scroll: 1 // misc;

In sostanza, tutto ciò che devi fare è scorrere ciclicamente ogni tipo di elemento e implementare un metodo sulla classe Element, chiamato come il tipo di evento,
che simula cosa fa addEvent:

// hash the element.natives in modo che tu possa fare qualcosa con esso var hash = new Hash (Element.NativeEvents); // rimuove gli elementi che devono essere sostituiti, aggiungi i loro sostituti hash.erase ('mouseover'). cancella ('mouseout'). cancella ('DOMMouseScroll'); hash.include ( 'mouseenter', 1) .include ( 'mouseLeave', 1); // inizializza questo var eventHash = new Hash (); // per ogni tipo di evento, aggiungi all'hash hash.getKeys (). each (function (event) eventHash [event] = function (fn) this.addEvent (event, fn); return this;;) ; // fallo accadere Element.implement (eventHash);

Ora puoi ascoltare eventi come:

$ ('myElement'). click (function () // do stuff);

11. Aggiungi eventi durante la creazione dell'elemento

Se hai esperienza di codifica con MooTools, ad un certo punto hai senza dubbio creato un elemento e successivamente aggiunto degli eventi:

var myElement = new Element ('a', href: 'mypage.php', testo: 'Clicca qui!'); myElement.addEvent ('click', function (e) // interrompe l'evento if (e) e.stop (); // do stuff);

Non c'è niente di sbagliato in quanto sopra, per dire, ma potresti semplicemente aggiungere quegli eventi durante la creazione degli elementi:

var myElement = new Element ('a', href: 'mypage.php', testo: 'Clicca qui!', eventi: click: function () // interrompi l'evento if (e) e.stop () ; //fare cose   );

12. Implementare eventi all'interno delle classi

L'estensione delle classi è stata discussa nel suggerimento n. 8 sopra. Ora esploriamo la funzionalità * implement * all'interno delle classi di MooTools. Qual è la differenza? Il contributore di MooTools Mark Obcena lo dice meglio nel suo articolo intitolato Up The Moo Herd IV: C'è una classe per questo:

MooTools ha due mutatori incorporati: Estende e Implementa. Il mutatore Extends prende il nome della classe passato su di esso e fa ereditare la nuova classe direttamente da esso, mentre Implements prende la classe (o le classi) passate e aggiunge i loro metodi alla nuova classe (o li mescola in, quindi mixin).

Con la differenza tra estendere e implementare, torniamo ad esso. Implementare eventi all'interno delle classi di MooTools può rendere le tue lezioni molto più flessibili. Considera la seguente classe Overlay semplice:

var Overlay = new Class (Implementa: [Opzioni, Eventi], opzioni: id: 'overlay', colore: '# 000', durata: 500, opacità: 0.5, zIndex: 5000, initialize: function (container, opzioni) this.setOptions (opzioni); this.container = document.id (container); this.overlay = new Element ('div', id: this.options.id, opacity: 0, styles: position: 'absolute', background: this.options.color, left: 0, top: 0, 'z-index': this.options.zIndex,). inject (this.container); this.tween = new Fx. Tween (this.overlay, duration: this.options.duration, link: 'cancel', proprietà: 'opacity', onStart: function () this.overlay.setStyles (width: '100%', height: this .container.getScrollSize (). y); .bind (this));, open: function () this.tween.start (this.options.opacity); restituisci this;, close: function ( ) this.tween.start (0); restituisci questo;);

Certo, la classe fa quello che dovrebbe, ma non è così flessibile come potrebbe essere. Ora implementiamo gli eventi onClick, onClose, onHide, onOpen e onShow:

var Overlay = new Class (Implementa: [Opzioni, Eventi], // EVENTI IMPLEMENTATI QUI! opzioni: id: 'overlay', colore: '# 000', durata: 500, opacità: 0.5, zIndex: 5000 / * , onClick: $ vuoto, onClose: $ vuoto, onHide: $ vuoto, onOpen: $ vuoto, onShow: $ vuoto * /, initialize: function (contenitore, opzioni) this.setOptions (options); this.container = document .id (container); this.overlay = new Element ('div', id: this.options.id, opacity: 0, styles: position: 'absolute', background: this.options.color, left: 0 , in alto: 0, 'z-index': this.options.zIndex, eventi: click: function () // CLICK EVENT this.fireEvent ('click'); .bind (this)). inject (this.container); this.tween = new Fx.Tween (this.overlay, duration: this.options.duration, link: 'cancel', proprietà: 'opacity', onStart: function () this.overlay .setStyles (width: '100%', height: this.container.getScrollSize (). y); .bind (this), onComplete: function () this.fireEvent (this.overlay.get ('opacity ') == this.options.opacity?' mostra ':' nascosto e '); // SHOW O HIDE EVENT .bind (this)); , open: function () this.fireEvent ('open'); // OPEN EVENT this.tween.start (this.options.opacity); restituiscilo; , close: function () this.fireEvent ('close'); // CLOSE EVENT this.tween.start (0); restituiscilo; );

La cosa fantastica dell'aggiunta di eventi a una classe è che gli eventi consentono di dare più opzioni e attivare la funzionalità quando i nostri metodi di classe vengono eseguiti. Nell'esempio precedente, è possibile eseguire qualsiasi funzionalità quando l'overlay si apre, si chiude, mostra, nasconde o viene fatto clic.
In sostanza hai aggiunto due minuscoli frammenti di codice alla classe:

Strumenti: [Eventi]

... e i seguenti ovunque desideri che un evento venga segnalato ...

this.fireEvent ('someEvent', [argument1, argument2]);

Quindi, come puoi controllare questi eventi quando crei un'istanza della classe? Aggiungili nelle opzioni come questa:

var overlay = new Overlay (onClick: function () this.hide ();, onOpen: function () alert ('Grazie per l'apertura!'););

Saresti difficile trovare una classe che non trarrebbe beneficio dall'implementazione degli eventi!


13. Usa la delegazione degli eventi

La delega degli eventi è il processo di aggiunta di un evento a un genitore per tutti i suoi figli invece di assegnare l'evento a ogni singolo figlio. Il vantaggio della delega degli eventi è che è possibile aggiungere elementi secondari all'elemento padre senza dover assegnare l'evento a quel nuovo elemento. Se decidi di rimuovere l'evento, devi solo rimuoverlo da un elemento.

Quindi, invece di:

$$ ('a'). addEvent ('click', function () // do stuff - assegnato individualmente);

… tu lo fai:

$ ('myContainer'). addEvent ('click: relay (a)', function () // assegnato al genitore di tutti gli elementi A (in questo caso, #myContainer), per ascoltare un elemento click event) /

Non lasciatevi ingannare dalla pseudo-sintassi ": relay ()"; Element.Delegation riscrive i metodi evento per ospitare: relay.


14. Utilizzare Class.toElement

Una gemma nascosta nella classe di MooTools è il metodo Class.toElement. Class.toElement svolge un ruolo limitato, ma può aiutarti quando si accede all'elemento primario all'interno di una classe, specialmente se non si conosce quale elemento è altrimenti. Implementazione toElement sulla tua classe è facile:

var myClass = new Class (Implementa: [Options], initialize: function (container, options) this.container = $ (container);, toElement: function () return this.container;);

Una volta definito toElement, puoi utilizzare la classe come un elemento:

var myInstance = new MyClass ('myElement'); myInstance.setStyle ('color', '# f00'). set ('html', 'Questo è il mio elemento!');

Guarda che - una classe virtualmente manipolata dai metodi Element.


15. "restituire questo" all'interno dei metodi per la concatenabilità

Quindi abbiamo visto tutti come i framework JavaScript ti permettono di incatenare i metodi. Il concatenamento ha questo aspetto:

$ ('myElement'). setStyles ('color', '# f00'). set ('html', 'Clicca qui'). fade ('out'). addClass ('cssClass'). addEvent ('click' , function (e) if (e) e.stop (); alert ('Clicked'!););

Santo concatenamento Batman! Vuoi che le tue classi si intrecciano per sempre? Nessun problema: tutto ciò che devi fare è tornare "Questo":

var myClass = new Class (// opzioni, inizializza, implementa, ecc. doSomething: function () // fa un sacco di funzionalità qui e ... restituisce this;, doAnotherThing: function () // fa un intero un sacco di funzionalità qui e ... return this;, doYetAnotherThing: function () // fa un sacco di funzionalità qui e ... restituisci questo);

Da quando hai piazzato restituiscilo in ogni metodo, ora puoi fare:

var klass = new myClass (); . Klass.doSomething () doAnotherThing () doYetAnotherThing ().;

Assicurati di tornare Questo ovunque abbia senso Fare così può rendere il tuo Classe molto più facile da lavorare e il tuo codice sarà più breve!


BONUS! Usa Fx scorciatoie sugli elementi

Gli effetti MooTools sono indiscutibilmente il più fluido di qualsiasi framework JavaScript. Il Fx libreria offre anche un sacco di controllo attraverso numerose opzioni. Diamo un'occhiata a un Tween di base che attenua un elemento al 50%:

var myTween = new Fx.Tween ('myElement', duration: 500, fps: 200, // un mucchio di opzioni qui); // fade a 50% $ ('myElement'). addEvent ('click', function () myTween.start ('opacity', 0.5););

Sapevi che non avevi bisogno di digitare tutto questo? Potresti usare scorciatoie come:

. $ ( 'MyElement') sbiadire (0,5); // fading: Fx.Tween $ ('myElement'). tween ('width', 300); // tweening: Fx.Tween $ ('myElement'). morph (width: 200, height: 300); // morph: Fx.Morph

I frammenti di cui sopra, ovviamente, si basano su te che desideri utilizzare le opzioni predefinite. In realtà puoi impostare opzioni personalizzate per questi metodi di scorciatoia per elemento:

$ ('myElement'). set ('tween', duration: 500, fps: 200) tween ('width', 300);

Salva te stesso pochi byte utilizzando le scorciatoie Fx!


MooTools FTW!

Spero di averti dato alcuni suggerimenti per migliorare il codice JavaScript MooTools, rendendolo più breve, più veloce e più forte. Hai alcuni dei tuoi consigli da condividere? Inseriscili nei commenti qui sotto!