Atualizar:Reescritas feitas para representar com precisão a prática atual de injeção de folha de estilo.


Como estamos usando muito JavaScript em nossos aplicativos Web atualmente, estamos procurando mais maneiras de mantê-los rápidos. Usamos o delegação de eventos Para manter a escuta de eventos eficiente, usamos função debouncing Para limitar o número de vezes que um determinado método pode ser usado, use Carregadores de JavaScript para carregar somente os recursos de que precisamos, e assim por diante. Outra maneira de tornar nossas páginas eficientes e rápidas é adicionar e remover estilos dinamicamente diretamente em uma folha de estilo, em vez de consultar constantemente o DOM em busca de elementos e aplicar estilos. Veja como isso funciona!


Obtendo a folha de estilo


A folha de estilo à qual o senhor adiciona as regras fica a seu critério. Se o senhor tiver uma folha de estilo específica em mente, poderá adicionar um ID ao campo LINK ou STYLE no HTML de sua página e obtenha o elemento CSSStyleSheet fazendo referência ao objeto sheet do elemento. As folhas de estilo podem ser encontradas na seção document.styleSheets objeto:



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];


Uma consideração importante é a media da folha de estilo – o senhor quer ter certeza de que não está adicionando regras a uma folha de estilo de impressão quando espera que os estilos sejam exibidos na tela. A CSSStyleSheet tem propriedades informativas para o senhor examinar:



// 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
*/


De qualquer forma, há muitas maneiras de obter uma folha de estilo para anexar regras de estilo.


Criando uma nova folha de estilo


Em muitos casos, talvez seja melhor criar um novo STYLE para suas regras dinâmicas. Isso é muito fácil:



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;
})();


Infelizmente, o WebKit exige um hack para que as coisas funcionem corretamente, mas tudo o que nos interessa é ter essa planilha.


Inserção de regras


As folhas de estilo têm um insertRule que não está disponível nos IEs anteriores, mas agora é o padrão para injeção de regras. O método insertRule exige que o senhor escreva toda a regra CSS da mesma forma que faria em uma folha de estilo:



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


Esse método pode parecer um pouco feio para uma API JavaScript, mas é assim que ele funciona. O segundo argumento, o index, representa o índice no qual a regra deve ser inserida. Isso é útil para que o senhor possa inserir a mesma regra/código e definir qual vence. O padrão para o índice é -1, que significa o fim da coleção. Para um controle extra/preguiçoso, o senhor pode adicionar !important às regras para evitar problemas com o índice.


Adicionando regras – Não padrão addRule


CSSStyleSheet os objetos têm um addRule que permite o registro de regras CSS na folha de estilo. O método addRule aceita três argumentos: o seletor, o segundo é o código CSS da regra e o terceiro é o índice inteiro baseado em zero que representa a posição do estilo (em relação aos estilos do mesmo seletor):



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


addRule As chamadas retornam um resultado de -1 em todos os casos – isso realmente não representa nada.


Lembre-se de que a vantagem aqui é que os elementos adicionados a partir da página têm automaticamente os estilos aplicados a eles, ou seja, o senhor não precisa adicioná-los aos elementos à medida que eles são injetados na página. Eficiente!



Aplicação de regras com segurança


Como o suporte do navegador para insertRule não é tão global, é melhor criar uma função de agrupamento para fazer a aplicação da regra. Aqui está um método rápido e simples:



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");


Esse método utilitário deve cobrir todos os casos de aplicação de novos estilos. Se o senhor estiver preocupado com a aplicação de estilos variáveis em todo o aplicativo, é razoável envolver o código interno desse método em um try{}catch(e){} bloco.


Inserção de regras para consultas de mídia

As regras específicas da consulta de mídia podem ser adicionadas de duas maneiras. A primeira maneira é por meio do padrão insertRule padrão:


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

É claro que, como o IE nem sempre foi compatível com o insertRule, o outro método é criar um STYLE com o atributo de mídia adequado e, em seguida, adicionar estilos a essa nova folha de estilo. Isso pode exigir a manipulação de vários STYLE mas isso é bastante fácil. Eu provavelmente criaria um objeto com consultas de mídia como índices e os criaria/recuperaria dessa forma.


Adicionar regras dinamicamente às folhas de estilo é eficiente e mais fácil do que o senhor imagina. Tenha essa estratégia em mente em seu próximo grande aplicativo, pois ela pode poupar trabalho no código e no processamento de elementos.