主题、样式切换方案

文章介绍了三种前端样式切换的方法:通过切换CSS文件、使用webpack主题颜色替换插件以及利用CSS变量var()实现。方案三是作者的偏好,它允许对组件进行定制化操作,且兼容Vue等框架,通过改变全局变量值即可切换页面样式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

个人比较喜欢方案三,可以写一个from对各个组件的样式做定制化操作,对于vue等框架也比较兼容。

方案一:通过切换css文件实现样式切换

整体代码

<body>
    <link type="text/css" rel="stylesheet" href="./css/theme01.css" data-theme="0" title="主题一">
    <link type="text/css" rel="alternate stylesheet" href="./css/theme02.css" data-theme="1" title="主题二">
    <link type="text/css" rel="alternate stylesheet" href="./css/theme03.css" data-theme="2" title="主题三">

    <div id="thenm-btns-box"></div>

</body>
<script>
    let thenmBtnsBox = document.getElementById('thenm-btns-box');
    let themeCss = document.querySelectorAll('link[data-theme]');
    themeCss.forEach((item, index) => {
        let btn = document.createElement('div');
        btn.style.cssText = `
                width: 50px;
                height: 50px;
                border-radius: 50%;
                background-color: azure;
            `;
        btn.addEventListener('click', function () {
            themeCss.forEach((cssItem) => {
                cssItem.disabled = Number(cssItem.getAttribute('data-theme')) !== index;
            });
        });
        thenmBtnsBox.appendChild(btn);

    });
</script>

实现思路

css文件

把主题相关的css样式放到不通的css文件夹中,通过rel="alternate"进行预加载(浏览器会加载当前文件但不会在文档流中生效,目的是当切换css文件时可以流畅不卡顿),并且title必须有值才能生效。添加data-theme作为标识,当需要切换时方便查找。

    <link type="text/css" rel="stylesheet" href="./css/theme01.css" data-theme="0" title="主题一">
    <link type="text/css" rel="alternate stylesheet" href="./css/theme02.css" data-theme="1" title="主题二">
    <link type="text/css" rel="alternate stylesheet" href="./css/theme03.css" data-theme="2" title="主题三">

切换按钮

随便写有个点击事件就行,我为了自适应主题文件数量就遍历了一下。

  1. 获取所有主题文件

  1. 遍历生成div按钮并添加点击事件

  1. append到需要放置的盒子中

 <div id="thenm-btns-box"></div>
<script>
    let thenmBtnsBox = document.getElementById('thenm-btns-box');
    let themeCss = document.querySelectorAll('link[data-theme]');
    themeCss.forEach((item, index) => {
        let btn = document.createElement('div');
        btn.style.cssText = `
                width: 50px;
                height: 50px;
                border-radius: 50%;
                background-color: azure;
            `;
        btn.addEventListener('click', function () {

        });
        thenmBtnsBox.appendChild(btn);

    });
</script>

点击事件

点击按钮时索引与css标签中的data-相同时让他的disabled属性为false,当前css文件就作用到文档流中了。index是上面遍历themeCss的索引也就是第几个按钮。

        btn.addEventListener('click', function () {
            themeCss.forEach((cssItem) => {
                cssItem.disabled = Number(cssItem.getAttribute('data-theme')) !== index;
            });
        });

方案二:插件 - webpack-theme-color-replacer

网上有详细解释我就不多赘述了,放一下文章和demo。

webpack-theme-color-replacer文章

webpack-theme-color-replacer domo

方案三 var()实现变量样式切换

整体代码

<style>
    /* 默认样式 */
    .title {
        font-size: 20px;
        margin: 20px 0;
    }

    .box {
        width: 100px;
        height: 100px;
        background-color: black;
    }
    /* end */

    /* 变量赋值样式 */
    :root {
        --table-fontColor: #d3a5c2;
        --title-color: #d3a5c2;
        --box-width: 50px;
        --box-height: 50px;
        --box-bgColor: #d3a5c2;
    }

    table th, table td {
        color: var(--table-fontColor);
    }

    .title {
        color: var(--title-color);
    }

    .box{
        width: var(--box-width);
        height: var(--box-height);
        background-color: var(--box-bgColor);
    }
    /* end */


</style>


<body>
    <table border="1">
        <tr>
            <th>Month</th>
            <th>Savings</th>
        </tr>
        <tr>
            <td>January</td>
            <td>$100</td>
        </tr>
    </table>

    <div class="title">
        标题
    </div>

    <div class="box"></div>

</body>


<script>
    // 需要替换的样式对象(数据可以由后端提供或者用通过定制组件产出)
    let theme = {
        '--table-fontColor': '#271579',
        '--title-color': '#5a17c0',
        '--box-width': '500px',
        '--box-height': '500px',
        '--box-bgColor': '#bc42a5',
    };
    let bodyStyle = document.getElementsByTagName('body')[0].style;
    for (const key in theme) {
        bodyStyle.setProperty(key, theme[key]);  
    };
</script>

实现思路

样式的变量赋值

通过:root(伪类作为全局样式)实现全局变量,再通过var()函数赋值到后期需要动态切换的属性中。

    /* 变量赋值样式 */
    :root {
        --table-fontColor: #d3a5c2;
        --title-color: #d3a5c2;
        --box-width: 50px;
        --box-height: 50px;
        --box-bgColor: #d3a5c2;
    }

    table th, table td {
        color: var(--table-fontColor);
    }

    .title {
        color: var(--title-color);
    }

    .box{
        width: var(--box-width);
        height: var(--box-height);
        background-color: var(--box-bgColor);
    }
    /* end */

切换变量的值

bodyStyle获取body的样式同时也包含root伪类,通过serProperty修改值。

    // 需要替换的样式对象(数据可以由后端提供或者用通过定制组件产出)
    let theme = {
        '--table-fontColor': '#271579',
        '--title-color': '#5a17c0',
        '--box-width': '500px',
        '--box-height': '500px',
        '--box-bgColor': '#bc42a5',
    };
    let bodyStyle = document.getElementsByTagName('body')[0].style;
    for (const key in theme) {
        bodyStyle.setProperty(key, theme[key]);  
    };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值