使用 document.documentElement.style 实现主题换肤

发布于:2022-11-09 ⋅ 阅读:(18) ⋅ 点赞:(0) ⋅ 评论:(0)

目录

1. document.documentElement 是什么?

1.1 document.documentElement

1.2 document.documentElement.style

1.3 打印效果

2. document.documentElement.style 相关的 JavaScript 方法

2.1 判断浏览器是否支持指定的 css 属性

2.2 判断浏览器是否支持指定的 css3 属性(带前缀)

2.3 使用 window.CSS.supports 判断 css 的属性和值

3. 使用 document.documentElement.style 实现换肤功能

3.1 原理概述

3.2 实现一下

3.2.1 初始化颜色变量

3.2.2 将十六进制颜色,转换为 rgb 格式

3.2.3 从本地获取用户设置的样式信息,根据样式信息更新全局的主题色、字号


1. document.documentElement 是什么?

1.1 document.documentElement

对于任何非空 HTML 文档,调用 document.documentElement 会返回一个 <html> 元素,也就是该文档的根元素

借助 document.documentElement 只读属性,能方便地获取到 html 文档的根元素

注意:IE浏览器中有兼容性问题,应该使用 document.body 替代 document.documentElement

1.2 document.documentElement.style

document.documentElement.style 属性定义了 当前浏览器支持的 所有 css 属性

举个栗子,获取字号属性 —— document.documentElement.style.fontSize

1.3 打印效果

2. document.documentElement.style 相关的 JavaScript 方法

2.1 判断浏览器是否支持指定的 css 属性

/**
 * 判断浏览器是否支持指定的 css 属性
 * @param cssName 样式属性名称
 **/
function support(cssName) {
    var htmlStyle = document.documentElement.style;
    if (cssName in htmlStyle)
        return true;
    return false;
}
alert(support('animate')); // false
alert(support('animation')); // true

2.2 判断浏览器是否支持指定的 css3 属性(带前缀)

/**
 * 判断浏览器是否支持指定的 css3 属性(带前缀)
 * @param style 样式属性名称
 */
function supportCss3(style) {
  var prefix = ["webkit", "Moz", "ms", "o"],
    i,
    humpString = [],
    htmlStyle = document.documentElement.style,
    _toHumb = function (string) {
      return string.replace(/-(\w)/g, function ($0, $1) {
        return $1.toUpperCase();
      });
    };
  for (i in prefix) humpString.push(_toHumb(prefix[i] + "-" + style));
  humpString.push(_toHumb(style));
  for (i in humpString) if (humpString[i] in htmlStyle) return true;
  return false;
}
alert(supportCss3("animation")); // true

2.3 使用 window.CSS.supports 判断 css 的属性和值

console.info(window.CSS);
console.info(window.CSS.supports("animation")); // false
console.info(window.CSS.supports("animate")); // false
console.info(window.CSS.supports("animation", "liear")); // true
console.info(window.CSS.supports("border", "1px solid #F00")); // true

打印结果如下: 

3. 使用 document.documentElement.style 实现换肤功能

3.1 原理概述

  • 定义一套主题色 css 变量,每种主题色对应不同的透明度
  • 系统中的样式,全部使用 css 变量进行设置
  • 系统初始化时,获取用户选择的主题色,并更新到已经声明的 css 变量中

3.2 实现一下

3.2.1 初始化颜色变量

  • 在 css :root 内定义主题色变量
  • 使用 css 变量替换原来的样式
:root {
  --theme-color: #33B897;
  --theme-color-opacity-10: rgba(51, 184, 151, 0.1);
  --theme-color-opacity-15: rgba(51, 184, 151, 0.15);
  --theme-color-opacity-20: rgba(51, 184, 151, 0.2);
  --theme-color-opacity-30: rgba(51, 184, 151, 0.3);
  --theme-color-opacity-50: rgba(51, 184, 151, 0.5);
  --theme-color-opacity-60: rgba(51, 184, 151, 0.6);
  --theme-color-opacity-80: rgba(51, 184, 151, 0.8);
  --theme-color-opacity-90: rgba(51, 184, 151, 0.9);
  --base-font-size: 15px;
}

.test-parent .test-child {
  // border: 1px solid #33b897;
  border: 1px solid var(--theme-color);
}

 关于 :root 选择器,可以阅读下方的文章:

css变量赋值和取值的四种方式(js设置值、内联样式、:root选择器、html选择器) - UCloud云社区今天突然发现一个有趣的现象document.querySelector(':root') === document.documentElementhttps://www.ucloud.cn/yun/117360.html

注意:编码格式 utf-8 

编码格式有的时候可以解决一些特殊的问题,比如:

  • 伪元素中的 content,如果使用中文,可能会出现乱码;
  • 正确的设置方式:将文字转换为 Unicode 编码,去掉 u,填入 content 

举个栗子~:

/* 年 - 文字 */
.WdateDiv #dpTitle > div:nth-child(4)::before {
  content: "\5e74";
  position: absolute;
  left: 46px;
  bottom: 0;
  font-size: 16px;
  color: #606266;
}

参考文章:

前端 - 伪元素 content 出现中文乱码_个人文章 - SegmentFault 思否伪元素的 content 使用中文字符在某些浏览器可能会出现乱码:代码如下: {代码...} 解决方法首先,确认 charset 为 utf-8确保 HTML 的 META 属性设置为 chars...https://segmentfault.com/a/1190000042077497?utm_source=sf-similar-article

3.2.2 将十六进制颜色,转换为 rgb 格式

/**
 * 十六进制颜色转换 rgb
 * @param color  十六进制颜色
 */
function colorRgb(color) {
  var sColor = color.toLowerCase();
  // 十六进制颜色值的正则表达式
  const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
  // 如果是16进制颜色
  if (sColor && reg.test(sColor)) {
    if (sColor.length === 4) {
      var sColorNew = "#";
      for (var i = 1; i < 4; i += 1) {
        sColorNew += sColor
          .slice(i, i + 1)
          .concat(sColor.slice(i, i + 1));
      }
      sColor = sColorNew;
    }
    // 处理六位的颜色值
    const sColorChange = [];
    for (var i = 1; i < 7; i += 2) {
      sColorChange.push(parseInt("0x" + sColor.slice(i, i + 2)));
    }
    return sColorChange.join(",");
  }
  return sColor;
}

3.2.3 从本地获取用户设置的样式信息,根据样式信息更新全局的主题色、字号


  // 从本地存储中获取用户设置的样式信息 userStyle
  // userStyle = '{"themeColor":"#E76950","arrowOrEllipsis":"ellipsis","fontSize":14}';
  var userStyle = localStorage.getItem("userStyle");
  // 存储 本地存储信息转换的对象
  var userStyleJson = {};


  if (userStyle) {
    userStyleJson = JSON.parse(userStyle);
    // 将 十六进制的颜色 换为 rgb
    var themeColor = colorRgb(userStyleJson.themeColor);

    // 获取 当前浏览器支持的 所有 css 属性
    var userStyleCss = document.documentElement.style;

    // 设置不同透明度的主题色
    userStyleCss.setProperty(
      "--theme-color",
      "rgba(" + themeColor + ", 1)"
    );
    userStyleCss.setProperty(
      "--theme-color-opacity-10",
      "rgba(" + themeColor + ", .1)"
    );
    userStyleCss.setProperty(
      "--theme-color-opacity-15",
      "rgba(" + themeColor + ", .15)"
    );
    userStyleCss.setProperty(
      "--theme-color-opacity-20",
      "rgba(" + themeColor + ", .2)"
    );
    userStyleCss.setProperty(
      "--theme-color-opacity-30",
      "rgba(" + themeColor + ", .3)"
    );
    userStyleCss.setProperty(
      "--theme-color-opacity-50",
      "rgba(" + themeColor + ", .5)"
    );
    userStyleCss.setProperty(
      "--theme-color-opacity-60",
      "rgba(" + themeColor + ", .6)"
    );
    userStyleCss.setProperty(
      "--theme-color-opacity-80",
      "rgba(" + themeColor + ", .8)"
    );
    userStyleCss.setProperty(
      "--theme-color-opacity-90",
      "rgba(" + themeColor + ", .9)"
    );
    // 设置字号大小
    userStyleCss.setProperty("--fontSize", userStyleJson.fontSize + "px");
  }