Vytváření pluginů pro SnackJS

Příspěvek My SnackJS:Tiny-But-Tasty JavaScript Framework vám ukázal nový JavaScriptový rámec Ryana Florence s názvem SnackJS. Motto SnackJS je „Protože někdy vše, co potřebujete, je svačina“ , a to z dobrého důvodu: tento 3KB mikrorámec poskytuje funkce, které potřebujete pro většinu webů, bez velké režie jQuery nebo jiných rámců. Protože je SnackJS v plenkách a jeho cílem je být malinký, rámec neobsahuje některé funkce, které se nacházejí v jiných rámcích; Stručně řečeno, SnackJS předpokládá, že víte, jak provádět některé úkoly (jako je úprava stylů prvků atd.) pomocí základního JavaScriptu.

Nelze popřít, že i když znáte JavaScript, metody zkratek jsou nesmírně užitečné – pokud by tomu tak nebylo, chytří vývojáři JavaScriptu by netrávili čas vytvářením rámců JavaScriptu. Jednou z funkcí zkratky, kterou SnackJS nemá, je vytvoření uzlu DOM...a rozšířením i úprava atributů uzlu a umístění. Protože věřím v projekt SnackJS a uvedená funkčnost je pro mé projekty ideální, vytvořil jsem create , attr a place pluginy, které budu sdílet s komunitou.

snack.attr a snack.wrap.attr

Úprava atributů uzlu byla ze všech tří úkolů nejobtížnější, protože jsem nemohl jednoduše použít setAttribute uzlu. metoda. Nejviditelnější z nich je style protože tato vlastnost uzlu je objekt CSSStyleDeclaration obsahující úplný seznam stylů uzlů. Pro tento účel, stejně jako pro účely innerHTML , vytvořil jsem několik speciálních definic, které se přizpůsobí také nastavení těchto vlastností:

// The "attr" plugin
!function(snack){
	
	// Will hold special attributes, privately
	var props = {};
	
	// The main method
	snack.attr = function(node,attr,value) {
		// Does the actual setting
		var doSet = function(val,key) {
			props[key] && props[key].set ? props[key].set(node,val) : node.setAttribute(key,val);
		};

		// Setter
		var isObj = typeof attr == "object";
		if(value != undefined || isObj) {
			isObj ? snack.each(attr,doSet) : doSet(value,attr);
		}
		else { // Getter
			return props[attr] ? props[attr].get(node) : node.getAttribute(attr);
		}
		// Return the node
		return node;
	};
	
	//  Creates a method by which one can define special node attributes
	snack.attr.define = function(name, obj){
		if (typeof name === 'string'){
			props[name] = obj;
			return;
		}
		// takes an object of key:values
		for (i in name) {
			if (name.hasOwnProperty(i)) {
				snack.attr.define(i, name[i]);
			}
		}
	};
	
	// Define the special attributes now
	snack.attr.define({
		html: {
			set: function(node,value) { node.innerHTML = value; },
			get: function(node) { return node.innerHTML; }
		},
		style: {
			set: function(node,value) { node.setAttribute("style",value); },
			get: function(node) { return node.getAttribute("style"); }
		}
	});
	
	// Extend to the "wrap" method
	snack.wrap.define('attr', function(attr, value){
		this.each(function(node){
			snack.attr(node, attr, value);
		});
	});

}(snack);

attr vlastnost se používá pro získání i nastavení atributů. Poskytnutí tří argumentů vždy funguje jako setter, poskytnutí objektu klíč/hodnota jako druhý argument je setter, jinak se chová jako getter. Zde jsou ukázky použití attr:

// Retrieve the title attribute of a node
var title = snack.attr(node,"title");

// Then retrieve the node's innerHTML
var html = snack.attr(node,"html");

// Set a node's "style" attribute
snack.attr(node,"style","background-color:green;color:#fff;padding:20px;");

// Set multiple attributes at once
snack.arr(node,{
	tabindex: 1,
	value: "davidwalsh",
	placeholder: "username"
});

attr metoda vám dokonce umožňuje vytvářet vlastní nastavovače a getry:

// Define the special attributes now
snack.attr.define({
	"class": {
		set: function(node,value) { node.className = value; },
		get: function(node) { return node.className; }
	}
});

Mám v plánu přepracovat attr jen trochu v budoucnosti, ale to, co je prezentováno, je současný stav.

svačina.místo a svačina.zabalit.místo

place metoda vkládá uzly na konkrétní místa v rámci DOM. Při vyhodnocování toho, kolik z větších rámců JavaScriptu umísťuje uzly, jsem zjistil, že Dojo's je nejvýstižnější, pokud jde o počet pozic, které vám umožňují vkládat uzly. Moje metoda je z velké části založena na Dojo Tookit:

// Fun this function immediately after creation
!function(snack) {

	// Places a node at a given position
	snack.place = function(node,domReference,position) {
		// Create functions for insertion
		var before = function(node,domReference) {
			var parent = domReference.parentNode;
			if(parent){
				parent.insertBefore(node, domReference);
			}
		};
		var after = function(node,domReference) {
			//	summary:
			//		Try to insert node after ref
			var parent = domReference.parentNode;
			if(parent){
				if(parent.lastChild == domReference){
					parent.appendChild(node);
				}else{
					parent.insertBefore(node, domReference.nextSibling);
				}
			}
		};
	
	
		if(typeof position == "number"){ // inline'd type check
			var cn = domReference.childNodes;
			if(!cn.length || cn.length <= position){
				domReference.appendChild(node);
			}else{
				before(node, cn[position < 0 ? 0 : position]);
			}
		}else{
			switch(position){
				case "before":
					before(node, domReference);
					break;
				case "after":
					after(node, domReference);
					break;
				case "replace":
					domReference.parentNode.replaceChild(node, domReference);
					break;
				case "first":
					if(domReference.firstChild){
						before(node, domReference.firstChild);
						break;
					}
					// else fallthrough...
				default: // aka: last
					domReference.appendChild(node);
			}
		}
		return node;
	};
	
	// Extend to the "wrap" method
	snack.wrap.define("place", function(domRef,pos){
		this.each(function(node){
			snack.place(node,domRef,pos);
		});
	});

}(snack);

Vyzbrojeno place můžete umístit uzly na několik pozic:

// Place the node into the BODY
snack.place(node,document.body);

// Place the node above the another node
snack.place(node,otherNode,"before");

// Replace one node with another
snack.place(node,otherNode,"replace");

Můžete také použít snack.wrap.place pro přesun více uzlů najednou:

// Create a UL
var list = snack.create("ul");

// Place the element above the node
snack.place(list,node,"before");
var arr = [];
for(x = 0; x <= 4; x++) {
	arr.push(snack.create("li",{ html: "List item " + (x + 1) }));
}
snack.wrap(arr).place(list);

Jak jsem řekl, hodně jsem si půjčil od Dojo. Můj důvod je ten, že Dojo je léty prověřené a nabízí největší flexibilitu. Hurá, nevynalézáte znovu kolo!

snack.create

create metoda byla nejjednodušší ze všech tří, dokonce používala attr a place když bude dostupný. Jednoduše zadejte značku, volitelné vlastnosti a volitelné umístění:

!function(snack) {
	// If not already created...
	snack.create = function(nodeType,props,nodeRef,where) {
		// Create the node
		var node = document.createElement(nodeType);
		// Add properties
		if(props && snack.attr) {
			// Set properties
			snack.attr(node,props);
		}
		// Inject into parent
		if(nodeRef && snack.place) {
			snack.place(node,nodeRef,where);
		}
		// Return the node
		return node;
	};
}(snack);

snack.create by bylo použito následovně:

// Create a UL
var list = snack.create("ul");

// Add an LI to the list
snack.create("li",{ html: "List item " + (x + 1) },list);

Pokud attr a place pluginy nejsou načteny, snack.create jednoduše funguje jako document.createElement obal.

Vytvoření zásuvných modulů SnackJS

Vytváření pluginů Snack.js je extrémně jednoduché. Jednoduše přidejte svou metodu do snack objekt nebo použijte SnackJS' define metoda:

!function(snack) {

	snack.pluginName = function(arg1,arg2/*, etc.*/) {
	
	};

}(snack);

Voila – váš vlastní plugin SnackJS je nyní k dispozici. A pokud chcete, aby váš plugin fungoval s snack.wrap , to je stejně snadné jako snack.each smyčka:

!function(snack) {

	snack.pluginName = function(arg1,arg2/*, etc.*/) {
	
	};
	
	// Extend to the "wrap" method
	snack.wrap.define("pluginName", function(arg1,arg2/*, etc.*/){
		this.each(function(arg){
			snack.pluginName(arg,arg1,arg2/*, etc.*/);
		});
	});

}(snack);

Přidání wrap podpora je v mnoha případech užitečná, ale vždy existují výjimky. Například přidání snack.wrap.create nedává smysl.

Pamatujte, že jedním z cílů SnackJS je být malý a stručný, takže své pluginy pište tak.

Přispívání zásuvných modulů SnackJS

SnackJS je nový, rostoucí rámec, takže vaše příspěvky jsou vždy vítány. I když možná nevytvářejí jádro SnackJS, vytváření jednoduchých, ale užitečných pluginů JavaScriptu pro SnackJS nemá žádnou nevýhodu. Kroky k vytvoření zásuvných modulů SnackJS jsou velmi podobné jakémukoli jinému frameworku:

  1. Prozkoumejte svůj plugin; podívejte se, jak ostatní rámce JS dosahují stejného cíle, a rozhodněte se, který je podle vás nejlepší
  2. Nakódujte svůj plugin
  3. Test. Test. Test.
  4. Forkujte oficiální repo SnackJS a potvrďte kód. Neváhejte a pošlete Ryanovi žádost o stažení.

Prosím, zvažte přispění do SnackJS. Je to projekt s velkými záměry, krásně nakódovaný Ryanem, který by mohl výrazně zlepšit rychlost webu. Zdá se, že jQuery je v tuto chvíli výchozím rámcem JavaScriptu pro většinu webových stránek; nemělo by to být. Nedělejte z rámce JavaScriptu více jídla, když vše, co potřebujete, je svačinka.