You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不依赖框架或npm包从JSON文件获取CSS样式?

纯原生JS从JSON加载样式实现资源受限HMI样式库

完全可以用纯原生JS实现从JSON文件加载样式,不需要任何框架或npm包,以下是适配资源受限HMI场景的轻量化实现方案:

1. 定义简洁的JSON样式结构

尽量采用扁平结构,减少解析时的性能消耗,示例如下:

{
  "global": {
    "body": {
      "backgroundColor": "#1a1a1a",
      "color": "#ffffff",
      "fontFamily": "Arial, sans-serif"
    }
  },
  "components": {
    "button": {
      "base": {
        "padding": "8px 16px",
        "borderRadius": "4px",
        "border": "none",
        "cursor": "pointer"
      },
      "primary": {
        "backgroundColor": "#007bff",
        "color": "#fff"
      }
    },
    "card": {
      "backgroundColor": "#2d2d2d",
      "borderRadius": "8px",
      "padding": "16px"
    }
  }
}

2. 原生JS加载JSON文件

用XMLHttpRequest适配低资源环境(兼容性更好、体积更小):

function loadStylesheet(url, callback) {
  const xhr = new XMLHttpRequest();
  xhr.open('GET', url, true);
  xhr.responseType = 'json';
  xhr.onload = () => {
    xhr.status >= 200 && xhr.status < 300 
      ? callback(null, xhr.response) 
      : callback(new Error(`加载失败:${xhr.status}`));
  };
  xhr.onerror = () => callback(new Error('网络请求失败'));
  xhr.send();
}

3. 两种样式应用方案

方案一:生成全局样式表(适合批量样式,性能更优)

一次性创建<style>标签注入全局样式,减少DOM操作:

function applyGlobalStyles(styles) {
  const styleSheet = document.createElement('style');
  let cssText = '';

  // 处理全局样式
  if (styles.global) {
    Object.entries(styles.global).forEach(([selector, rules]) => {
      cssText += `${selector}{`;
      Object.entries(rules).forEach(([prop, value]) => {
        // 驼峰转CSS短横线命名
        const cssProp = prop.replace(/([A-Z])/g, '-$1').toLowerCase();
        cssText += `${cssProp}:${value};`;
      });
      cssText += '}';
    });
  }

  // 处理组件类样式
  if (styles.components) {
    Object.entries(styles.components).forEach(([component, variants]) => {
      Object.entries(variants).forEach(([variant, rules]) => {
        const className = variant === 'base' ? `.${component}` : `.${component}.${variant}`;
        cssText += `${className}{`;
        Object.entries(rules).forEach(([prop, value]) => {
          const cssProp = prop.replace(/([A-Z])/g, '-$1').toLowerCase();
          cssText += `${cssProp}:${value};`;
        });
        cssText += '}';
      });
    });
  }

  styleSheet.textContent = cssText;
  document.head.appendChild(styleSheet);
}

// 调用示例
loadStylesheet('styles.json', (err, styles) => {
  if (err) {
    console.error(err);
    return;
  }
  applyGlobalStyles(styles);
});

方案二:直接赋值行内样式(适合动态修改单个元素)

跳过样式表生成,直接给DOM元素设置样式,适合资源极低的场景:

function applyComponentStyle(element, componentStyle) {
  Object.entries(componentStyle).forEach(([prop, value]) => {
    element.style[prop] = value;
  });
}

// 调用示例:给按钮应用primary样式
loadStylesheet('styles.json', (err, styles) => {
  if (err) {
    console.error(err);
    return;
  }
  const primaryBtn = document.getElementById('primary-btn');
  applyComponentStyle(primaryBtn, {
    ...styles.components.button.base,
    ...styles.components.button.primary
  });
});

4. 资源受限环境优化技巧

  • 压缩JSON:移除空格、注释,最小化文件体积
  • 内存缓存:加载一次后将样式存到内存,避免重复请求:
    let cachedStyles = null;
    function getStyles(url, callback) {
      if (cachedStyles) {
        callback(null, cachedStyles);
        return;
      }
      loadStylesheet(url, (err, styles) => {
        if (!err) cachedStyles = styles;
        callback(err, styles);
      });
    }
    
  • 按需加载:拆分大JSON为多个小文件,仅加载当前页面所需样式
  • 扁平结构:避免JSON深层嵌套,减少解析时的循环次数

内容的提问来源于stack exchange,提问作者Roxana G

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 08:15:35