news 2026/3/27 10:46:48

【前端】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/3/20 13:54:48

人才缺口行业以及过剩行业

&#x1f4c9; 人才“相对过剩”行业清单&#xff08;基于2025-2026年就业市场实证&#xff09; 重要澄清&#xff1a; ✅ “人才很多” 岗位需求 < 求职供给&#xff08;结构性过剩&#xff09; ❌ ≠ 行业无价值 / 从业者能力差 &#x1f511; 核心是“供需错配”&#x…

作者头像 李华
网站建设 2026/3/24 20:09:52

PHP毕设项目推荐-基于php的宠物电商猫粮狗粮购物商城的设计与实现基于PHP宠物用品商城网站基于php的宠物商城网站的设计与制作【附源码+文档,调试定制服务】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/3/22 20:31:28

资讯丨ISO 14001:2026标准最终版即将生效,全条款中英文对照

ISO 14001这一全球应用最广泛的环境管理体系标准&#xff0c;其修订工作已迎来关键节点。最新版本ISO 14001:2026的《国际标准最终草案》&#xff08;以下简称“FDIS”&#xff09;现已完成&#xff0c;进入为期一个月的正式投票表决期&#xff0c;截止日期为 2026年3月2日 。…

作者头像 李华
网站建设 2026/3/24 9:12:17

SAP化工行业解决方案:以数字化赋能,破解化工企业运营痛点

化工行业作为工业经济的核心支柱&#xff0c;涵盖石油化工、精细化工、涂料、新能源化工等多个细分领域&#xff0c;其生产流程复杂、产业链绵长、合规要求严苛&#xff0c;同时面临着原料价格波动、安全管控难度大、供应链协同不畅、数据割裂等多重挑战。在数字化转型浪潮下&a…

作者头像 李华