Přidejte pravidla do šablon stylů pomocí JavaScriptu

Aktualizace: Přepisy provedené tak, aby přesně reprezentovaly současnou praxi pro vkládání šablon stylů.

Vzhledem k tomu, že v dnešní době v našich webových aplikacích používáme tolik JavaScriptu, hledáme další způsoby, jak je udržet rychle. Používáme delegování událostí, abychom udrželi efektivní naslouchání událostí, používáme funkci debouncing k omezení počtu, kolikrát lze danou metodu použít, používáme zavaděče JavaScriptu k načtení pouze zdrojů, které potřebujeme, atd. Dalším způsobem, jak můžeme naše stránky zefektivnit a zrychlit, je dynamicky přidávat a odebírat styly přímo do šablony stylů namísto neustálého dotazování DOM na prvky a používání stylů. Zde je návod, jak to funguje!

Získání šablony stylů

Je na vás, do jaké šablony stylů pravidla přidáte. Pokud máte na mysli konkrétní šablonu stylů, můžete přidat ID na LINK nebo STYLE prvek v HTML vaší stránky a získejte CSSStyleSheet objekt odkazem na sheet prvku vlastnictví. Šablony stylů lze nalézt v document.styleSheets objekt:

var sheets = document.styleSheets; // returns an Array-like StyleSheetList

/*
Returns:  

StyleSheetList {0: CSSStyleSheet, 1: CSSStyleSheet, 2: CSSStyleSheet, 3: CSSStyleSheet, 4: CSSStyleSheet, 5: CSSStyleSheet, 6: CSSStyleSheet, 7: CSSStyleSheet, 8: CSSStyleSheet, 9: CSSStyleSheet, 10: CSSStyleSheet, 11: CSSStyleSheet, 12: CSSStyleSheet, 13: CSSStyleSheet, 14: CSSStyleSheet, 15: CSSStyleSheet, length: 16, item: function}
*/

// Grab the first sheet, regardless of media
var sheet = document.styleSheets[0];

Jedním z důležitých aspektů je media šablony stylů – chcete se ujistit, že nepřidáváte pravidla do šablony stylů pro tisk, když očekáváte, že se styly zobrazí na obrazovce. A CSSStyleSheet objekt má informační vlastnosti, které si můžete prohlédnout:

// Get info about the first stylesheet
console.log(document.styleSheets[0]);

/*
Returns:  

CSSStyleSheet
	cssRules: CSSRuleList
	disabled: false
	href: "https://davidwalsh.name/somesheet.css"
	media: MediaList
	ownerNode: link
	ownerRule: null
	parentStyleSheet: null
	rules: CSSRuleList
	title: null
	type: "text/css"
*/

// Get the media type
console.log(document.styleSheets[0].media.mediaText)
/*
Returns:
	"all" or "print" or whichever media is used for this stylesheet
*/

V každém případě existuje mnoho způsobů, jak uchopit šablonu stylů a připojit k ní pravidla stylu.

Vytvoření nové šablony stylů

V mnoha případech může být nejlepší vytvořit nový STYLE prvek pro vaše dynamická pravidla. To je docela snadné:

var sheet = (function() {
	// Create the <style> tag
	var style = document.createElement("style");

	// Add a media (and/or media query) here if you'd like!
	// style.setAttribute("media", "screen")
	// style.setAttribute("media", "only screen and (max-width : 1024px)")

	// WebKit hack :(
	style.appendChild(document.createTextNode(""));

	// Add the <style> element to the page
	document.head.appendChild(style);

	return style.sheet;
})();

Bohužel WebKit vyžaduje hack, aby věci správně fungovaly, ale jediné, na čem nám záleží, je mít ten list.

Vkládání pravidel

Šablony stylů mají insertRule metoda, která není dostupná v dřívějších IE, ale nyní je standardem pro vkládání pravidel. insertRule vyžaduje, abyste napsali celé pravidlo CSS stejně, jako byste to udělali v šabloně stylů:

sheet.insertRule("header { float: left; opacity: 0.8; }", 1);

Tato metoda se může zdát trochu ošklivá pro JavaScript API, ale tak to funguje. Druhý argument, index , představuje index, do kterého se má pravidlo vložit. To je užitečné, abyste mohli vložit stejné pravidlo/kód a definovat, které vyhraje. Výchozí hodnota pro index je -1 , což znamená konec sbírky. Pro extra/líné ovládání můžete přidat !important na pravidla, abyste se vyhnuli problémům s indexem.

Přidávání pravidel – nestandardní addRule

CSSStyleSheet objekty mají addRule metoda, která umožňuje zaregistrovat pravidla CSS do šablony stylů. addRule metoda přijímá tři argumenty: selektor, druhý kód CSS pro pravidlo a třetí je celočíselný index s nulou představující pozici stylu (ve vztahu ke stylům stejného selektoru):

sheet.addRule("#myList li", "float: left; background: red !important;", 1);

addRule volání vrátí výsledek -1 ve všech případech -- ve skutečnosti to nic nepředstavuje.

Pamatujte, že výhodou je, že prvky přidané ze stránky mají automaticky aplikované styly; tj. nebudete je muset přidávat do prvků, když jsou vkládány do stránky. Efektivní!

Bezpečné používání pravidel

Protože prohlížeč podporuje insertRule není tak globální, je nejlepší vytvořit funkci zalamování, která bude provádět aplikaci pravidla. Zde je rychlá a špinavá metoda:

function addCSSRule(sheet, selector, rules, index) {
	if("insertRule" in sheet) {
		sheet.insertRule(selector + "{" + rules + "}", index);
	}
	else if("addRule" in sheet) {
		sheet.addRule(selector, rules, index);
	}
}

// Use it!
addCSSRule(document.styleSheets[0], "header", "float: left");

Tato obslužná metoda by měla pokrýt všechny případy aplikace nového stylu. Pokud jste nervózní z použití proměnných stylů ve vaší aplikaci, je rozumné zabalit vnitřní kód této metody do try{}catch(e){} blokovat.

Vkládání pravidel pro dotazy na média

Pravidla specifická pro dotazy na média lze přidat jedním ze dvou způsobů. První způsob je přes standardní insertRule metoda:

sheet.insertRule("@media only screen and (max-width : 1140px) { header { display: none; } }");

Samozřejmě, protože IE ne vždy podporoval insertRule , druhou metodou je vytvoření STYLE element se správným atributem media a poté do této nové šablony stylů přidat styly. To může vyžadovat žonglování s více STYLE prvky, ale to je dost snadné. Pravděpodobně bych vytvořil objekt s mediálními dotazy jako indexy a vytvořil/načetl bych je tímto způsobem.

Dynamické přidávání pravidel do šablon stylů je efektivní a jednodušší, než si možná myslíte. Mějte tuto strategii na paměti ve své příští velké aplikaci, protože vám může ušetřit práci při zpracování kódu i prvků.