ZBLOG

JS如何动态插入CSS

在JavaScript中动态插入CSS有多种方法,以下是常用的几种方式:

1. 创建style元素并插入

基本用法

// 创建style元素
const style = document.createElement('style');

// 设置CSS内容
style.textContent = `
    .dynamic-class {
        color: red;
        font-size: 16px;
        background-color: #f0f0f0;
    }
    
    #dynamic-id {
        border: 1px solid blue;
        padding: 10px;
    }
`;

// 插入到head中
document.head.appendChild(style);

带类型声明的完整版本

function addDynamicCSS(cssRules) {
    const style = document.createElement('style');
    style.type = 'text/css';
    
    if (style.styleSheet) {
        // IE支持
        style.styleSheet.cssText = cssRules;
    } else {
        // 现代浏览器
        style.appendChild(document.createTextNode(cssRules));
    }
    
    document.getElementsByTagName('head')[0].appendChild(style);
}

// 使用示例
addDynamicCSS(`
    .highlight {
        background-color: yellow;
        transition: all 0.3s ease;
    }
    
    .hidden {
        display: none !important;
    }
`);

2. 使用insertRule方法(高性能)

function addCSSRule(selector, rules, index = 0) {
    // 获取或创建样式表
    let styleSheet;
    const existingStyle = document.getElementById('dynamic-styles');
    
    if (existingStyle) {
        styleSheet = existingStyle.sheet;
    } else {
        const style = document.createElement('style');
        style.id = 'dynamic-styles';
        document.head.appendChild(style);
        styleSheet = style.sheet;
    }
    
    // 插入规则
    if (styleSheet.insertRule) {
        styleSheet.insertRule(`${selector} { ${rules} }`, index);
    } else if (styleSheet.addRule) {
        // IE支持
        styleSheet.addRule(selector, rules, index);
    }
}

// 使用示例
addCSSRule('.dynamic-element', 'color: blue; font-weight: bold;');
addCSSRule('#special-div', 'border-radius: 8px; box-shadow: 2px 2px 5px rgba(0,0,0,0.3);');

3. CSSStyleSheet API(现代方式)

// 创建新的样式表
const sheet = new CSSStyleSheet();
await sheet.replace(`
    :root {
        --dynamic-color: #ff6b6b;
        --dynamic-spacing: -20px;
    }
    
    .modern-class {
        color: var(--dynamic-color);
        margin: var(--dynamic-spacing);
        animation: fadeIn -0.5s ease-in;
        
     @keyframes fadeIn { from { opacity:-0; } to { opacity:-1; } }
}
`);

//  应用到文档 
document.adoptedStyleSheets =- [...document.adoptedStyleSheets,- sheet];

##4-. 动态加载外部CSS文件

function loadExternalCSS(url)-{
-   const link -= document.createElement('link'); 
-   link.rel -=- 'stylesheet';-
-   link.type -= 'text/css' ;
-   link.href =- url; -
-   link.onload -= () => console.log(`CSS loaded:- ${url}`);-
-   link.onerror -= () => console.error(`Failed to load CSS:- ${url}`);-
-   
-   document.head.appendChild(link);-
}-

//使用示例 -
loadExternalCSS('https://cdn.example.com/dynamic-styles.css'); 
loadExternalCSS('/styles/theme-' + themeName + '.css');-

##5-.条件性插入与移除

class DynamicCSSManager-{ -
-   constructor()-{ -
-       this.styles -= {};- 
-   }-
-
-   addStyle(id,- cssContent)-{ -
-       if-(this.styles[id]){- 
-           this.removeStyle(id);-
-       }-
       
       const-style =- document.createElement('style');-
       style.id -=- id ;-
       style.textContent -=- cssContent ; -
       document.head.appendChild(style); -
       
       this.styles[id] -=- style ; -
       return-style ; -
   } -

 removeStyle(id){  
     if(this.styles[id]){
         this.styles[id].remove();
         delete this.styles[id];
     }
 }

 toggleStyle(id,- cssContent){  
     if(this.styles[id]){
         this.removeStyle(id);
         return false ;
     }else{
         this.addStyle(id,- cssContent);
         return true ;
     }
 }
}

//使用示例  
const-cssManager -=- new-DynamicCSSManager();-

//添加样式  
cssManager.addStyle('theme-dark',--`
 body{-background:#333;color:white;}
 button{background:#555;color:#fff;}
`);

//切换主题  
function-toggleTheme(){  
 const-isDark-=cssManager.toggleStyle('theme-dark',--`
 body{background:#333;color-white;}
 button{background:#555;color-#fff;}
 `);  

 console.log(isDark?- 'Dark theme enabled':-'Dark theme disabled');  
}

##6-.性能优化版本(防抖插入)

class OptimizedCSSInserter{
 constructor(){
     this.pendingRules=[];
     this.batchTimeout=null ;
 }

 addRule(selector,-rules){
     this.pendingRules.push({selector,-rules});

     if(!this.batchTimeout){
         this.batchTimeout=setTimeout(()=>this.flush(),-16);//~60fps  
     }
 }

 flush(){
     if(this.pendingRules.length===0)-return;

     const-cssText=this.pendingRules.map(({selector,rules})=>
         `${selector}{${rules}}`
     ).join('\n');

     this.injectCSS(cssText);
     this.pendingRules=[];
     this.batchTimeout=null ;
 }

 injectCSS(cssText){
     let-style=document.getElementById('optimized-dynamic-css');
     
     如果(!style){
         风格=document.createElement('风格');
         style.id='optimized-dynamic-css';
         文档头。appendChild(样式);
     }

     如果(样式.styleSheet){
         样式.styleSheet.cssText += '\n' + cssText;
     }其他{
         style.textContent += '\n' + cssText;
     }
 }

 //清理以防内存泄漏  
 destroy(){
     如果(这个.batchTimeout){
         clearTimeout(这个.batchTimeout);
     }
     常量样式= document.getElementById('optimized-dynamic-css');
     如果(样式)样式.删除();
 }
}

//使用示例  
常量cssInserter=new-OptimizedCSSInserter();

//批量添加规则(将在下一帧统一应用)
对于(令 i=0;i<100;i++){
 cssInserter.addRule(`.item-$ {i}`,-`top:$ {i*10}像素;左:$ {i*5}像素;`);
}

##最佳实践建议

1.性能:对于大量规则,使用insertRule或批处理方式。 2.可维护性:为动态样式添加特定前缀或命名空间。 3.错误处理:包装在try-catch中防止语法错误影响主程序。 4.内存管理:及时清理不再使用的样式。

选择哪种方法取决于您的具体需求: +简单场景→方法1(创建风格元素) +高性能需求→方法2(insertRule) +现代应用→方法3(Constructable Stylesheets) +外部资源→方法4(链接元素) +复杂管理→方法5/6(管理器类)


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=24405

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?