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.