网站换肤的实现

99 阅读1分钟

不同方式

  • 改变css文件, js改变<link href="xxx.css">的href
    • 可能减少加载流量,但是换肤时由于加载不流畅
  • 根据css优先级更改,在css中[theme="xxx"]body上加上theme="xxx"
    • 切换流畅,但是不换肤时文件同样加载
  • 使用alternate,在<link href="xxx.css" rel="alternate stylesheet">加上alternate,使用disable更改
    • 切换流畅、语义明确,但是不换肤时文件同样加载

实现

前置文件

创建一个文件夹,里面创建四个文件,分别是index.html、red.css、green.css、blue.css

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <!-- <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script> -->
</head>
<style>
/* 基本结构 */
  body{
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    width: 100vw;
    margin: 0;
  }
</style>
<body>
  <h1 onclick="changeTheme()">Hello.</h1>
<script>
// js
</script>
</body>
</html>
/* red */
body{
    color: red;
    background-color: #e3e3e3;
}
/* green */
body{
    color: green;
    background-color: #e5f5b9;
}
/* blue */
body{
    color: blue;
    background-color: #b9d8f5;
}

js懒加载方式

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <link href="red.css" rel="stylesheet" type="text/css" css-data="default">
</head>
<style>
  body{
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    width: 100vw;
    margin: 0;
  }
</style>
<body>
  <h1 onclick="changeTheme()">Hello.</h1>
<script>
  const styleLinks = document.querySelectorAll('link[css-data]')
  function changeTheme() {
    styleLinks.forEach((link) =>{
      if(link.getAttribute('css-data') === 'default'){
        link.href = 'blue.css'
      }
    })
  }
</script>
</body>
</html>

css优先级方式

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<style>
  body{
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    width: 100vw;
    margin: 0;
  }
  [theme="red"]{
    color: red;
    background-color: #e3e3e3;
  }
</style>
<body>
  <h1 onclick="changeTheme()">Hello.</h1>
<script>
  const bodyNode = document.getElementsByTagName('body')[0]
  function changeTheme(){
    bodyNode.setAttribute('theme','red')
  }
</script>
</body>
</html>

alternate渲染方式

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <link href="red.css" rel="alternate stylesheet" type="text/css" title="红色">
  <link href="green.css" rel="alternate stylesheet" type="text/css" title="绿色">
  <link href="blue.css" rel="alternate stylesheet" type="text/css" title="蓝色">
</head>
<style>
  body{
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    width: 100vw;
    margin: 0;
  }
</style>
<body>
  <h1 onclick="changeTheme()">Hello.</h1>
<script>
  const styleLinks = document.querySelectorAll('link[title]')
  let i = 0
  function changeTheme() {
    let count = 0
    styleLinks.forEach((link) =>{
      link.disabled = true
      if(count++ == i){
        link.disabled = false
      }
    })
    i = ++i % 4
  }
</script>
</body>
</html>
  • 没有title属性,rel属性值仅仅是stylesheet的<link>无论如何都会加载并渲染,如reset.css;
  • 有title属性,rel属性值仅仅是stylesheet的<link>作为默认样式CSS文件加载并渲染,如default.css;
  • 有title属性,rel属性值同时包含alternate stylesheet的<link>作为备选样式CSS文件加载,默认不渲染,如red.css和green.css;

参考:www.zhangxinxu.com/wordpress/?…