news 2026/4/15 15:55:17

【前端】JS动态加载样式方法总结

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【前端】JS动态加载样式方法总结

在JavaScript中动态加载样式有多种方法,以下是几种常用的方式:

1. 创建并插入<style>元素

内联样式文本

// 方法1:直接设置 innerHTMLfunctionaddStyle(cssText){conststyle=document.createElement('style');style.type='text/css';style.innerHTML=cssText;document.head.appendChild(style);returnstyle;}// 使用addStyle(`body { background-color: #f0f0f0; } .highlight { color: red; }`);// 方法2:使用 insertRule(更高效,支持批量操作)functionaddStyleWithRules(rules){conststyle=document.createElement('style');document.head.appendChild(style);constsheet=style.sheet;rules.forEach(rule=>{sheet.insertRule(rule,sheet.cssRules.length);});}// 使用addStyleWithRules(['body { background: #fff; }','.dynamic { font-size: 16px; }']);

2. 动态加载外部CSS文件

// 创建 link 元素加载外部CSSfunctionloadExternalCSS(url){returnnewPromise((resolve,reject)=>{constlink=document.createElement('link');link.rel='stylesheet';link.type='text/css';link.href=url;link.onload=()=>resolve(link);link.onerror=()=>reject(newError(`Failed to load CSS:${url}`));document.head.appendChild(link);});}// 使用loadExternalCSS('styles.css').then(()=>console.log('CSS加载成功')).catch(err=>console.error('CSS加载失败:',err));// 或者使用 async/awaitasyncfunctionloadStyles(){try{awaitloadExternalCSS('theme.css');awaitloadExternalCSS('components.css');console.log('所有样式加载完成');}catch(error){console.error('加载样式失败:',error);}}

3. 动态修改现有样式

// 获取或创建样式表functiongetStyleSheet(){// 尝试获取现有的动态样式表letstyle=document.getElementById('dynamic-styles');if(!style){style=document.createElement('style');style.id='dynamic-styles';document.head.appendChild(style);}returnstyle.sheet||style.styleSheet;}// 添加/更新样式规则functionupdateCSSRule(selector,styles){constsheet=getStyleSheet();constcssText=Object.entries(styles).map(([prop,value])=>`${prop}:${value}`).join('; ');construle=`${selector}{${cssText}}`;// 删除已存在的相同选择器规则for(leti=0;i<sheet.cssRules.length;i++){if(sheet.cssRules[i].selectorText===selector){sheet.deleteRule(i);break;}}// 添加新规则sheet.insertRule(rule,sheet.cssRules.length);}

4. 使用document.adoptedStyleSheets(现代浏览器)

// 创建可复用的样式表functioncreateAdoptedStyleSheet(cssText){constsheet=newCSSStyleSheet();sheet.replaceSync(cssText);returnsheet;}// 将样式表应用到文档或Shadow DOMfunctionapplyStyleSheet(sheet){// 应用到整个文档document.adoptedStyleSheets=[...document.adoptedStyleSheets,sheet];// 或者应用到Shadow DOM// shadowRoot.adoptedStyleSheets = [sheet];}// 使用示例constmyStyles=createAdoptedStyleSheet(`:root { --primary-color: #3498db; } .custom-element { color: var(--primary-color); }`);applyStyleSheet(myStyles);

5. 完整示例:带缓存和事件处理的CSS加载器

classCSSLoader{constructor(){this.loaded=newSet();this.pending=newMap();}// 加载CSS(支持缓存和去重)load(url,options={}){const{id=url,cache=true,force=false}=options;// 如果已经加载且不强制重新加载if(this.loaded.has(id)&&!force&&cache){returnPromise.resolve();}// 如果正在加载中if(this.pending.has(id)){returnthis.pending.get(id);}constpromise=newPromise((resolve,reject)=>{constlink=document.createElement('link');link.rel='stylesheet';link.type='text/css';link.href=url;if(id!==url)link.id=id;link.onload=()=>{this.loaded.add(id);this.pending.delete(id);resolve(link);};link.onerror=(error)=>{this.pending.delete(id);reject(error);};document.head.appendChild(link);});this.pending.set(id,promise);returnpromise;}// 加载多个CSS文件loadAll(urls,options={}){returnPromise.all(urls.map(url=>this.load(url,options)));}// 检查是否已加载isLoaded(id){returnthis.loaded.has(id);}// 移除已加载的CSSremove(id){constelement=document.getElementById(id);if(element){element.parentNode.removeChild(element);this.loaded.delete(id);}}}// 使用示例constcssLoader=newCSSLoader();// 加载单个CSScssLoader.load('https://cdn.example.com/style.css',{id:'theme'}).then(()=>console.log('主题样式已加载'));// 加载多个CSScssLoader.loadAll(['components.css','layout.css','typography.css']).then(()=>console.log('所有基础样式已加载'));

6. 性能优化建议

// 1. 使用 requestIdleCallback 或 setTimeout 延迟加载非关键CSSfunctionloadNonCriticalCSS(){if('requestIdleCallback'inwindow){requestIdleCallback(()=>{loadExternalCSS('non-critical.css');});}else{setTimeout(()=>{loadExternalCSS('non-critical.css');},3000);}}// 2. 预加载CSSfunctionpreloadCSS(url){constlink=document.createElement('link');link.rel='preload';link.as='style';link.href=url;link.onload=()=>{link.rel='stylesheet';};document.head.appendChild(link);}// 3. 媒体查询动态加载functionloadCSSByMedia(query,url){constlink=document.createElement('link');link.rel='stylesheet';link.media=query;link.href=url;document.head.appendChild(link);// 当媒体查询匹配时立即应用link.onload=()=>{link.media='all';};}

注意事项

  1. 样式优先级:动态加载的样式遵循CSS层叠规则
  2. 性能影响:避免频繁修改样式,使用CSS类切换
  3. 浏览器兼容性
    • insertRuledeleteRule在IE中使用addRuleremoveRule
    • adoptedStyleSheets需要Chrome 73+ / Firefox 101+
  4. 内容安全策略(CSP):确保动态样式符合CSP规则

选择哪种方法取决于具体需求:

  • 少量样式:使用<style>元素
  • 外部样式文件:使用<link>元素
  • 现代Web Components:使用adoptedStyleSheets
  • 需要复杂管理:使用CSSLoader类
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/4 1:17:00

‍关注英首相访华-英国天空新闻(Sky News)| 国研政情·中国国政研究

‍关注英首相访华-英国天空新闻(Sky News)| 国研政情中国国政研究英国首相斯塔默对中国进行的正式访问&#xff0c;成为近期国际关系领域的重要事件。英国天空新闻(Sky News)在分析报道中指出&#xff0c;斯塔默在访华期间的表态体现出务实的对华政策风格&#xff0c;这一观察得…

作者头像 李华
网站建设 2026/4/15 7:07:26

普通Java程序员如何跳出CRUD的苦海,成为一个更“高级”的程序员

性能优化可以说是我们程序员的必修课&#xff0c;如果你想要跳出CRUD的苦海&#xff0c;成为一个更“高级”的程序员的话&#xff0c;性能优化这一关你是无论无何都要去面对的。为了提升系统性能&#xff0c;开发人员可以从系统的各个角度和层次对系统进行优化。除了最常见的代…

作者头像 李华
网站建设 2026/4/13 16:47:58

必收藏!AI大模型赋能工业工程全解析,小白程序员入门必看

在人工智能&#xff08;AI&#xff09;大模型全面爆发的当下&#xff0c;工业工程这门兼顾效率与优化的学科&#xff0c;正迎来颠覆性的变革浪潮。作为小白或程序员&#xff0c;你是否经常疑惑&#xff1a;AI大模型到底能给工业工程带来什么&#xff1f;如何借助大模型技术&…

作者头像 李华
网站建设 2026/4/14 21:24:23

Linux系统I2C子系统概述

Linux系统I2C子系统概述 1. I2C子系统架构 Linux内核中的I2C子系统采用分层架构设计&#xff0c;主要分为以下三个核心部分&#xff1a; 1.1 I2C核心层&#xff08;I2C Core&#xff09; 提供I2C总线驱动和设备驱动的注册、注销方法维护系统中所有I2C适配器和设备驱动的链表实现…

作者头像 李华
网站建设 2026/3/15 11:29:54

利用vibe-profiling对PyTorch进行性能分析

在 AI 推理的实际应用中&#xff0c;尤其是在自动驾驶、工业控制等实时性场景中&#xff0c;最致命的挑战往往不是整体速度慢&#xff0c;而是偶发性的卡顿。 这种不可预测的性能抖动&#xff0c;极易导致系统响应超时&#xff0c;进而引发严峻的安全问题。面对复杂的 C/C 底层…

作者头像 李华