Machen Sie Ihren MooTools-Code kürzer, schneller und stärker

Zweimal im Monat besuchen wir einige der Lieblingsbeiträge unserer Leser aus der gesamten Geschichte von Nettuts +. Dieses Tutorial wurde erstmals im Februar 2010 veröffentlicht.

MooTools ist eines der flexibelsten, modularen und gut geschriebenen JavaScript-Frameworks, das verfügbar ist. So viele Leute benutzen es, aber viele von ihnen optimieren ihren Code nicht. In diesem Beitrag erhalten Sie fünfzehn einfache Tipps, wie Sie Ihren MooTools-Code kürzer, schneller und stärker machen können.


1.Erstellen Sie Ihre eigenen MooTools Build oder ziehen Sie aus Google AJAX-Bibliotheken

Ein großer Vorteil der Verwendung von MooTools ist die unglaublich modulare Bauweise. Was bedeutet das? Es ist fast nichts erforderlich, wenn Sie es nicht brauchen. Der Vorteil der MooTools-Modularität besteht darin, dass Ihre begrenzte, benutzerdefinierte MooTools-Build Ihre JavaScript-Ladezeit kurz halten kann.

MooTools Core Builder

Möchten Sie ein benutzerdefiniertes MooTools-Build für Ihr nächstes Projekt erstellen? Folge diesen Schritten:

  • Gehen Sie zu http://mootools.net/core (und / oder http://mootools.net/more, wenn Sie zusätzliche Plugins wünschen).
  • Wählen Sie die Plugins Ihrer Wahl aus. Machen Sie sich keine Sorgen über die Berücksichtigung von Abhängigkeiten - der Plugin-Builder erledigt das für Sie!
  • Wählen Sie die Komprimierungsoption Ihrer Wahl - der YUI Compressor bietet Ihnen den kleinsten möglichen Build von MooTools

Das ist es! Manchmal benötigt Ihr Projekt jedoch die gesamte MooTools Core-Bibliothek. In diesem Fall kann sich Ihre Website Tausende sparen
Anforderungen pro Tag mithilfe der Google AJAX-Bibliotheken komplettieren MooTools. Sie können dies auf zwei Arten tun:

Diese erste Methode fügt MooTools ganz normal in die Seite ein. Die zweite Methode ermöglicht mehr Funktionalität und Leistung:

 

Das Beste an der Verwendung der Google AJAX Libraries API ist, dass, wenn eine andere Website die AJAX Library API verwendet, diese Version von MooTools bereits in ihrem Browser zwischengespeichert wird und die Website schneller geladen wird!


2. Verwenden Sie jQuery und MooTools zusammen

Es ist zwar am besten, eine Bibliothek auf einer bestimmten Seite beizubehalten, um eine Menge Overhead zu vermeiden. Manchmal können Sie jedoch nicht vermeiden, mehrere Frameworks zu benötigen.
Glücklicherweise können MooTools mit beliebigen, nicht auf Prototypen basierenden JavaScript-Frameworks koexistieren. So können Sie jQuery und MooTools auf derselben Seite verwenden:

 

Dank des Dollar-Safe-Modus von MooTools übernimmt MooTools nicht mehr die "$" -Methode, wenn diese bereits vergeben ist!


3. Speichern Sie Elemente und Elementsammlungen

Entwickler müssen häufig ein Element oder eine Sammlung von Elementen sammeln. Beispielsweise müssen Sie möglicherweise alle A-Elemente auf der Seite auswählen, ihre Farbe ändern und QuickInfos daraus erstellen.

// Links greifen, Farbe ändern * / $$ ('# footer a'). setStyle ('color', '# f00'); // Links erstellen Tooltips var tippers = neue Tipps ($$ ('# footer a'));

Der obige Code ist äußerst ineffizient. Warum das DOM zweimal abfragen (mit $$), wenn Sie alle Elemente einmal sammeln können? Lassen Sie uns dies effizienter machen:

// "Speichern" von Links in einer Variablen var links = $$ ('# footer a'); // Links holen, Farbe ändern * / links.setStyle ('color', '# f00'); // Links erstellen Tooltips var tippers = neue Tipps (Links);

Sie könnten dies noch kürzer machen, aber es ist nicht so lesbar:

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

Lesbarkeit ist wichtig, daher würde ich die Codierung nicht empfehlen, wenn Sie mit einem Team zusammenarbeiten.


4. Verwenden Sie Elementmethoden für Elementsammlungen

Das Durchlaufen einer Reihe von Elementen gilt nicht für ein JavaScript-Framework:

// für jeden Link… $$ ('a'). each (Funktion (a) // fügt einen Link zum Element hinzu. a.addEvents (mouseenter: function () // wird nach rechts animiert, wenn (! a .retrieve ('oPad')) a.store ('oPad', a.getStyle ('padding-left')); a.tween ('padding-left', 30);, mouseleave: function () // animiere zurück nach links a.tween ('padding-left', a.retrieve ('oPad'));;);

Was viele Entwickler nicht wissen, dass Element-Auflistungen die gleichen Methoden wie Elements haben, müssen Sie nicht durchlaufen werden. Wenden Sie einfach die gewünschte Funktionalität auf die Auflistung an:

$$ ('a'). addEvents (mouseenter: function () // animiere nach rechts, wenn (! this.retrieve ('oPad')) this.store ('oPad', this.getStyle ('padding.) -left ')); this.tween (' padding-left ', 30);, mouseleave: function () // animiere zurück nach links this.tween (' padding-left ', this.retrieve (' oPad ')););

Beachten Sie, dass das Schlüsselwort "this" verwendet wird, um auf das "aktuelle" Element in der Auflistung zu verweisen, nicht auf die Auflistung selbst.


5. Verwenden Sie MooTools Alias

Mit der "Alias" -Methode von MooTools können Sie eine vorhandene Methode umbenennen oder aliasieren. Nehmen Sie das folgende Codefragment, das sich aktuell in der MooTools Core-Quelle befindet:

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

Mit dem obigen Code können Sie die jeder Methode statt für jeden. Verwenden jeder ist lesbarer, ein leiser Standard zwischen den meisten JavaScript-Frameworks und speichert sogar einige Bytes in Ihrem Code. Wenn Sie es vorziehen, MooTools 'Native oder Class-Methoden einen benutzerdefinierten Namen zu geben, können Sie dies gerne tun!

Die Methode der Elementklasse zum Entfernen eines Elements aus dem DOM lautet beispielsweise:

$ ('myElement'). dispose ();

Angenommen, Ihre Web-App handelt von einem bestimmten Thema und Sie möchten die Terminologie für Ihren Code einhalten. Hier einige Beispiele:

Element.alias ('dispose', 'can'); // Karriereseite? Element.alias ('dispose', 'shank'); // Gefängnisstätte?

Was auch immer Ihre Gründe dafür sind, eine Methode unter einem anderen Namen zu nennen, scheuen Sie sich nicht davor!


6. Erstellen Sie benutzerdefinierte Pseudo-Selektoren

Der Zugriff auf eine Sammlung von Elementen im DOM ist eine der Hauptaufgaben eines JavaScript-Frameworks. Leider kann es auch eine Belastung sein, und die gewünschten Pseudo-Selektoren sind nicht immer verfügbar. Glücklicherweise können Sie mit MooTools einfach Ihre eigenen Pseudo-Selektoren implementieren! Lasst uns
Erstellen Sie einen Pseudo-Selektor mit dem Namen "disabled", der ein Element zurückgibt, wenn es deaktiviert ist.

// greife deaktivierte Elemente ab Selectors.Pseudo.disabled = function () return this.disabled;  // wie verwendet man es var disabledInputs = $$ ('input: disabled');

Fügen Sie einfach Ihren Selektor zum Selectors.Pseudo-Objekt hinzu. Wenn die Funktion des neuen Pseudos "true" zurückgibt, ist das Element eine Übereinstimmung und wird zurückgegeben.

Das Definieren eigener Pseudo-Selektoren ist eine großartige Möglichkeit, die Selektoren zu kontrollieren!


7. Implementieren Sie Methoden für vorhandene Objekte

Die Philosophie von MooTools ist, dass es akzeptabel, sogar ermutigt wird, native Prototypen (String, Funktion, Anzahl usw.) bei Bedarf zu ändern.
Durch die Einführung neuer Methoden bei diesen Eingeborenen werden sie noch stärker. Erstellen wir eine String-Methode, aus der eine beliebige Textzeichenfolge umgewandelt wird
"Tweet" -Format (Links für @ Reply's, Links usw. hinzufügen):

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

Jetzt können Sie "toTweet" für eine beliebige Zeichenfolge aufrufen und Sie erhalten die Zeichenfolge als "Tweet" zurück. Hier einige Beispiele:

// Setze die HTML eines Elements auf einen Tweet-Wert var el = $ ('myElement'); el.set ('html', el.get ('html'). toTweet ()); // setzt die HTML-Datei des Elements auf einen verknüpften Tweet-Wert. // alarmiere den getwitterten Wert ('Yo @NetTuts, checke meine #MooTools-Website: http: //davidwalsh.name'.toTweet ()); // alerts: Yo @NetTuts, checke meine MooTools-Website: http://davidwalsh.name

Durch die Implementierung benutzerdefinierter Methoden für Objekte werden alle vorhandenen und zukünftigen Instanzen dieses Objekts verstärkt.


8. Bestehende Klassen erweitern

Die OOP-Philosophie von MooTools ermöglicht ein äußerst leistungsfähiges Vererbungsmodell. Durch das Erweitern vorhandener Klassen können Sie das Wiederholen von Code vermeiden, vorhandene Objekte unterstützen und vorhandene Funktionen nutzen. MooTools Core, More und Ihre benutzerdefinierten Klassen erweitern vorhandene Funktionen. Bedenke die Anfordern Klasse:

var Request = new Klasse (Implementiert: [Kette, Ereignisse, Optionen]], Optionen: / * onRequest: $ empty, onComplete: $ empty, onCancel: $ empty, onSuccess: $ empty, onFailure: $ empty, onException: $ leer, * / url: ", data:", Header: 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'Text / Javascript, Text / HTML, Anwendung / XML, Text / XML, * / * ', async: true, Format: false, Methode:' post ', Link:' ignore ', isSuccess: null, Emulation: true, urlEncoded: true, Kodierung:' utf-8 ', evalScripts: false, evalResponse: false, noCache: false, initialize: function (Optionen) this.xhr = new Browser.Request (); this.setOptions (Optionen); 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; $ try (function () this.status = this.xhr.status; .bind (this)); this.xhr.onreadystatechange = $ empty; if (this.options.isSuccess.call (this, this.) stat 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.ail (); , 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; Daten = Null;  this.xhr.open (method.toUpperCase (), url, this.options.async); this.xhr.onreadystatechange = this.onStateChange.bind (this); this.headers.each (Funktion (Wert, Schlüssel) try this.xhr.setRequestHeader (Schlüssel, Wert); catch (e) this.fireEvent ('exception', [Schlüssel, Wert]); diese); this.fireEvent ('request'); this.xhr.send (Daten); if (! this.options.async) this.onStateChange (); kehre das zurück; , cancel: function () if (! this.running) liefert dies zurück; this.running = falsch; this.xhr.abort (); this.xhr.onreadystatechange = $ empty; this.xhr = neuer Browser.Request (); this.fireEvent ('cancel'); kehre das zurück; );

Dann betrachten Sie Request.JSONP, das Request erweitert:

Request.JSON = neue Klasse (erweitert: Anfrage, Optionen: secure: true), initialize: function (Optionen) this.parent (Optionen); 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 , Text););

Du siehst wie klein das ist Request.JSONP Klasse ist? Beim Hinzufügen Erweitert: Anfrage, das Request.JSONP class erhält alle Methoden der Request-Klasse. Im Wesentlichen wird dieser kleine Codeausschnitt zu einem Kraftpaket, weil er erweitert wird Anfordern. Sie können sogar Erweiterungen zu Erweiterungen hinzufügen. Jetzt überlegen Request.JSONP und dann Scott Kyles Request.Twitter Klasse:

//Request.JSONP / * --- script: Request.JSONP.js Beschreibung: Definiert Request.JSONP, eine Klasse für domänenübergreifendes JavaScript über die Skriptinjektion. Lizenz: Lizenz im MIT-Stil: - Aaron Newton - Guillermo Rauch benötigt: - Kern: 1.2.4 / Element - Kern: 1.2.4 / Request - / Log stellt Folgendes bereit: [Request.JSONP]… * / Request.JSONP = new Klasse (Implementiert: [Kette, Ereignisse, Optionen, Protokoll], Optionen: / * onRetry: $ empty (intRetries), onRequest: $ empty (scriptElement), onComplete: $ empty (data), onSuccess: $ empty (data ), onCancel: $ empty (), log: false, * / url: ", data: , Wiederholungen: 0, Timeout: 0, Verknüpfung: '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) gibt true zurück; switch (this.options.link) case 'cancel': this.cancel (); true zurückgeben; case 'chain': this.chain (this. caller.bind (this, arguments)); return false; return false;, send: function (options) if (! $ chk (arguments [1]) &&! this.check (options)) liefert dies; var type = $ type (Optionen ), old = this.options, index = $ chk (Argumente [1])? Argumente [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 verbleibend = this.triesRemaining [Index]; (function () var script = this.getScript (options); this.log ('JSONP holt Skript mit URL ab:' + script.get ('src')); this.fireEvent ('request', script); this .running = true; (function () if (verbleibend) this.triesRemaining [index] = verbleibend - 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 (' failure '); .options.timeout, this);). delay (Browser.Engine.trident? 50: 0, this); kehre das zurück; , cancel: function () if (! this.running) liefert dies zurück; this.running = falsch; this.fireEvent ('cancel'); kehre das zurück; , getScript: function (Optionen) var index = Request.JSONP.counter, data; Request.JSONP.counter ++; switch ($ type (options.data)) case 'element': data = document.id (options.data) .toQueryString (); brechen; 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?' & '+ data: "); if (src.length> 2083) this.log (' JSONP '+ src +' schlägt in Internet Explorer fehl, wodurch eine Länge von 2083 Bytes erzwungen wird Beschränkung auf URIs '); var script = neues Element (' script ', type:' text / javascript ', src: src); Request.JSONP.request_map [' request_ '+ index] = function () this. success (Argumente, Skript); .bind (this); return script.inject (this.options.injectScript);, success: function (args, script) if (script) script.destroy (); this.running = false; this.log ('JSONP wurde erfolgreich abgerufen:', args); this.fireEvent ('complete', args) .fireEvent ('success', args) .callChain ();; Request.JSONP.counter = 0; Request.JSONP.request_map = ;

… Und jetzt Request.Twitter:

Request.Twitter = new Class (Erweitert: Request.JSONP, Optionen: linkify: true, URL: 'http://twitter.com/statuses/user_timeline/term.json'), data: count: 5 , initialize: function (Begriff, Optionen) this.parent (Optionen); this.options.url = this.options.url.substitute (Begriff: Begriff);, Erfolg: Funktion (Daten, Skript)  if (this.options.linkify) data.each (Funktion (Tweet) tweet.text = this.linkify (tweet.text);, this); // hält nachfolgende Aufrufe neuer, wenn (data [0]) dies. options.data.since_id = data [0] .id; this.parent (data, script);, linkify: function (text) // Geändert von TwitterGitter durch David Walsh (davidwalsh.name) // mit freundlicher Genehmigung von Jeremy Parrish (rrish.org) return text.replace (/ (https?: \ / \ / [\ w \ -:;? & = +.% # \ /] +) / gi, '$ 1') .replace (/ ( ^ | \ W) @ (\ w +) / g, '$ 1 @ $ 2') .replace (/ (^ | \ W) # (\ w +) / g, '$ 1 # $ 2');;

Sie sehen, wie ein Wasserfalleffekt der Erweiterung von Objekten die kleinste Klasse zu einem absoluten Klassiker machen kann?
Experimentieren Sie mit dem Vererbungsmodell von MooTools und wiederholen Sie den Code nicht!


9. Erstellen Sie benutzerdefinierte Ereignisse

Ich habe bereits erklärt, wie flexibel die MooTools-Auswahl-Engine ist, das Klassensystem und wie modular das Framework ist.1 Warum sollten Sie etwas anderes als das MooTools-Ereignissystem erwarten? Das Erstellen von benutzerdefinierten Ereignissen in MooTools ist so einfach wie es nur geht. Hier ist eine grundlegende Übersicht Ihres benutzerdefinierten MooTools-Ereignisses:

Element.Events.altClick = base: 'click', // die "base" -Ereignisbedingung: function (event) return event.alt; // alt "Taste? , onAdd: function () // etwas tun, wenn das Ereignis hinzugefügt wird, onRemove: function () // etwas tun, wenn das Ereignis entfernt wird;

Hier ist ein großartiges Beispiel für ein benutzerdefiniertes Ereignis - gleichzeitig auf "alt" und "klick" achten:

// alt click Element.Events.altClick = base: 'click', Bedingung: function (event) return event.alt; // alt "Taste? ; // use $ (document.body) .addEvent ('altClick', function () alert ('Sie haben mich angeklickt!'););

Sie können auch einfach ein benutzerdefiniertes Ereignis definieren, sodass eine bestimmte Funktion immer dann ausgeführt wird, wenn dieser Ereignistyp zugewiesen wird. In meinem nächsten Beispiel wird jedes Mal, wenn einem Element ein Klickereignis zugewiesen wird, der Cursor dieses Elements automatisch in den Cursor "Zeiger" geändert.

/ * Cursor beim Hinzufügen / Entfernen des Klickereignisses aktualisieren * / Element.Events.click = base: 'click', onAdd: function () if (this.setStyle) this.store ('original-cursor', this). getStyle ('Cursor')); this.setStyle ('Cursor', 'Zeiger'); , onRemove: function () if (this.setStyle) this.setStyle ('Cursor', this.retrieve ('Original-Cursor')); ;

Sie werden feststellen, dass der ursprüngliche Cursor wiederhergestellt wird, wenn das Klickereignis entfernt wird.


10. jQuery-Style-Ereignisse

Während das MooTools-Ereignis sytax sich von jQuery unterscheidet, muss es nicht sein! Mit einer minimalen Menge an JavaScript können Sie die Ereignissyntax von MooTools jQuery's reflektieren lassen.

MooTools hält alle seine Veranstaltungen in der Element.NativeElements Objekt:

Element.NativeEvents = click: 2, dblclick: 2, mouseup: 2, Mausedown: 2, Kontextmenü: 2, // Maustasten mousewheel: 2, DOMMouseScroll: 2, // Mausrad Mouseover: 2, mouseout: 2, Mauszeiger : 2, selectstart: 2, selectend: 2, // Mausbewegung keydown: 2, Tastendruck: 2, keyup: 2, // Tastaturfokus: 2, Unschärfe: 2, Änderung: 2, Reset: 2, Auswahl: 2, Senden: 2, // Formularelemente laden: 1, Entladen: 1, vor Entladen: 2, Größenänderung: 1, Verschieben: 1, DOMContentLoaded: 1, readystatechange: 1, // Fensterfehler: 1, Abbruch: 1, Scrollen: 1 // Sonstiges;

Im Wesentlichen müssen Sie nur jeden Elementtyp durchlaufen und eine Methode in der Element-Klasse implementieren, die wie der Ereignistyp bezeichnet wird,
das simuliert, was addEvent macht:

// hash die element.natives, damit du Sachen damit machen kannst var hash = new Hash (Element.NativeEvents); // entferne Elemente, die ersetzt werden müssen, füge ihre Ersetzungen hinzu hash.erase ('mouseover'). erase ('mouseout'). erase ('DOMMouseScroll'); hash.include ('mouseenter', 1) .include ('mouseleave', 1); // diese Variable initialisieren eventHash = new Hash (); // Für jeden Ereignistyp addiere den Hash hash.getKeys (). each (function (event) eventHash [event] = function (fn) this.addEvent (event, fn); zurückgeben;;) ; // mach es möglich Element.implement (eventHash);

Jetzt können Sie folgende Ereignisse abhören:

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

11. Ereignisse während der Elementerstellung hinzufügen

Wenn Sie Erfahrung mit MooTools haben, haben Sie zweifellos ein Element erstellt und anschließend Ereignisse hinzugefügt:

var myElement = new Element ('a', href: 'mypage.php', Text: 'Hier klicken!'); myElement.addEvent ('click', function (e) // Stoppen des Ereignisses if (e) e.stop (); // do stuff);

Es ist nichts falsch mit dem oben genannten, per sage, aber Sie könnten diese Ereignisse einfach während der Elementerstellung hinzufügen:

var myElement = new Element ('a', href: 'mypage.php', Text: 'Hier klicken!', Ereignisse: click: function () // das Ereignis stoppen, wenn (e) e.stop () ; //Sachen machen   );

12. Implementieren Sie Ereignisse innerhalb von Klassen

Das Erweitern von Klassen wurde oben in Tipp 8 besprochen. Lassen Sie uns nun die * implementieren * -Funktionalität in MooTools-Klassen erkunden. Was ist der Unterschied? Mark Obcena, Mitwirkender von MooTools, sagt es am besten in seinem Artikel mit dem Titel Up The Moo Herde IV: Dafür gibt es eine Klasse:

MooTools hat zwei eingebaute Mutatoren: Extends und Implements. Der Extends-Mutator übernimmt den übergebenen Klassennamen und lässt die neue Klasse direkt erben, während Implements die übergebene Klasse (oder Klassen) übernimmt und ihre Methoden der neuen Klasse hinzufügt (oder sie in-so mixin mischt)..

Mit dem Unterschied zwischen Erweitern und Implementieren wollen wir noch einmal darauf zurückkommen. Das Implementieren von Ereignissen in Ihren MooTools-Klassen kann Ihre Klassen flexibler machen. Betrachten Sie die folgende einfache Overlay-Klasse:

var Überlagerung = neue Klasse (Implements: [Optionen, Ereignisse]], Optionen: id: 'overlay', Farbe: '# 000', Dauer: 500, Deckkraft: 0,5, zIndex: 5000, Initialisierung: Funktion (Container, options) this.setOptions (options); this.container = document.id (container); this.overlay = neues Element ('div', id: this.options.id, Deckkraft: 0, styles: position: 'absolut', Hintergrund: this.options.color, links: 0, oben: 0, 'z-index': this.options.zIndex,). inject (this.container); this.tween = neue Fx. Tween (this.overlay, duration: this.options.duration, Link: 'cancel', Eigenschaft: 'opacity', onStart: function () this.overlay.setStyles (width: '100%', height: this.) .container.getScrollSize (). y); .bind (this));, open: function () this.tween.start (this.options.opacity); zurückgeben;, close: function ( ) this.tween.start (0); zurückgeben;);

Sicher, die Klasse macht, was sie soll, ist aber bei weitem nicht so flexibel, wie es sein könnte. Lassen Sie uns nun die Ereignisse onClick, onClose, onHide, onOpen und onShow implementieren:

var Overlay = neue Klasse (Implementiert: [Optionen, Ereignisse], // EREIGNISSE HIER AUSGEFÜHRT!) Optionen: ID: 'Overlay', Farbe: '# 000', Dauer: 500, Deckkraft: 0,5, ZIndex: 5000 / * onClick: $ empty, onClose: $ empty, onHide: $ empty, onOpen: $ empty, onShow: $ empty * /, initialize: function (Container, Optionen) this.setOptions (Optionen); this.container = Dokument .id (Container); this.overlay = neues Element ('div', id: this.options.id, Deckkraft: 0, Stile: position: 'absolute', Hintergrund: this.options.color, links: 0 top: 0, 'z-index': this.options.zIndex, Ereignisse: 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', Eigenschaft: '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?' show ':' hidden e '); // SHOW OR HIDE EVENT .bind (this)); , open: function () this.fireEvent ('open'); // OPEN EVENT this.tween.start (this.options.opacity); kehre das zurück; , close: function () this.fireEvent ('close'); // CLOSE EVENT this.tween.start (0); kehre das zurück; );

Beim Hinzufügen von Ereignissen zu einer Klasse können Sie bei der Ausführung von Klassenmethoden mehr Optionen angeben und Funktionen auslösen. Im obigen Beispiel können Sie eine beliebige Funktion ausführen, wenn die Überlagerung geöffnet, geschlossen, angezeigt, ausgeblendet oder angeklickt wird.
Im Wesentlichen haben Sie der Klasse zwei kleine Codefragmente hinzugefügt:

Implementiert: [Ereignisse]

… Und Folgendes, wo immer Sie eine Veranstaltung signalisieren möchten…

this.fireEvent ('someEvent', [Argument1, Argument2]);

Wie können Sie diese Ereignisse steuern, wenn Sie eine Instanz der Klasse erstellen? Fügen Sie sie in den Optionen wie folgt hinzu:

var overlay = new Overlay (onClick: function () this.hide ();, onOpen: function () alert ('Vielen Dank für das Öffnen!');;

Es wäre schwierig, eine Klasse zu finden, die von der Implementierung von Ereignissen nicht profitieren würde!


13. Verwenden Sie die Ereignisübertragung

Ereignisdelegation ist das Hinzufügen eines Ereignisses zu einem übergeordneten Element für alle untergeordneten Elemente, anstatt das Ereignis jedem einzelnen untergeordneten Element zuzuweisen. Der Vorteil der Ereignisdelegation besteht darin, dass Sie untergeordnete Elemente zum übergeordneten Element hinzufügen können, ohne dass das Ereignis diesem neuen Element zugewiesen werden muss. Wenn Sie das Ereignis entfernen möchten, müssen Sie es nur aus einem Element entfernen.

Also statt:

$$ ('a'). addEvent ('click', function () // do stuff - einzeln zugewiesen);

… Du machst das:

$ ('myContainer'). addEvent ('click: relay (a)', function () // wird dem übergeordneten Element aller A-Elemente zugewiesen (in diesem Fall #myContainer), um das Element-Element click-Ereignis anzuhören) /

Lassen Sie sich nicht von der Pseudosyntax ": relay ()" täuschen; Element.Delegation schreibt die Ereignismethoden für Relay neu.


14. Verwenden Sie Class.toElement

Ein verstecktes Juwel in MooTools 'Class ist die Class.toElement-Methode. Class.toElement spielt eine kleine Rolle, kann Ihnen jedoch beim Zugriff auf das primäre Element innerhalb einer Klasse helfen, insbesondere wenn Sie nicht wissen, was dieses Element sonst ist. Umsetzung toElement für deine Klasse ist einfach:

var myClass = new Class (Implements: [Optionen], initialize: function (Container, Optionen) this.container = $ (container);, toElement: function () return this.container;);

Wenn Sie toElement definiert haben, können Sie Ihre Klasse wie ein Element verwenden:

var myInstance = new MyClass ('myElement'); myInstance.setStyle ('color', '# f00'). set ('html', 'Dies ist mein Element!');

Sehen Sie sich das an - eine Klasse, die von Element-Methoden virtuell manipuliert wird.


15. "geben Sie dieses zurück" in Methods for Chainability

Wir haben also alle gesehen, wie Sie mit den JavaScript-Frameworks Methoden aus der Hölle ketten können. Verkettung sieht so aus:

$ ('myElement'). setStyles ('color', '# f00'). set ('html', 'Click Here'). fade ('out'). addClass ('cssClass'). addEvent ('click' Funktion (e) if (e) e.stop (); alert ('geklickt'!););

Heiliger Batman! Möchten Sie, dass Ihre Kurse für immer verkettet werden? Kein Problem - Sie müssen nur zurückkehren "diese":

var myClass = new Class (// Optionen, Initialisieren, Implementieren usw.) doSomething: function () // Führen Sie hier eine ganze Reihe von Funktionen aus und… geben Sie dies zurück;, doAnotherThing: function () // ein Ganzes eine Reihe von Funktionen hier und… geben Sie dies zurück;, doYetAnotherThing: function () // eine ganze Reihe von Funktionen hier ausführen und ... das zurückgeben.);

Da hast du platziert Gib das zurück In jeder Methode können Sie jetzt Folgendes tun:

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

Stellen Sie sicher, dass Sie zurückkehren diese wo immer es sinnvoll ist. Das kann so machen Klasse viel einfacher zu bearbeiten und Ihr Code wird kürzer!


BONUS! Verwenden Sie Fx-Verknüpfungen für Elemente

MooTools-Effekte sind zweifellos die glattesten aller JavaScript-Frameworks. Das Fx Die Bibliothek bietet auch eine Menge Kontrolle über zahlreiche Optionen. Schauen wir uns ein grundlegendes Tween an, das ein Element um 50% ausblendet:

var myTween = new Fx.Tween ('myElement', duration: 500, fps: 200, // eine Reihe von Optionen hier); // fade zu 50% $ ('myElement'). addEvent ('click', function () myTween.start ('opacity', 0.5););

Wuss