zoukankan      html  css  js  c++  java
  • 动态主题定制

    背景

    目前接手的是一个cordova的项目,最近一个迭代的到一个需求,需要为不同的租户定制不同的主题,我们希望租户的主题能跟随租户定制。

    实现思路

    • 首先通过接口或者容器拿到主题标识
    • 通过标识在本地匹配对应的主题数据(就是各个部分的颜色)
    • 通过ajax请求本地css文件(就是我们需要更改颜色的所有样式)
    • 通过我们本地获取主题色把css文件进行替换(replace 原来的锚点)
    • 最后动态生成style标签写入

    代码部分

    因为是cordova的项目,我们提前在容器就为客户进行定制,写入了租户id.我们通过本地定制的样式进行匹配颜色

    var themeConfigJSON = {
    	"1097660": {
    		standard: '#40c9c9',
    		dark: '#24aca8',
    		active: '#24aca8',
    		light: '#37dbdb',
    		selected: '#40c9c9',
    		activeColor: '#24aca8',
    		customerColor: '#24aca8',
    		arrangeColor: '#40c9c9',
    		arrangeColor1: '#efffff',
    	}
    }
    //从容器中拿id
    navigator.appplugin.getAppInfo(function(id) {
        _this.updateStyle(id);
    });
    
    

    这里就是你本地css文件,留下一些你比较好进行替换的锚点(这里@{text2},@{color1}都是自己创建的),同时需要注意的你的class权重,避免样式污染。如果你是vue项目你需要考虑取消掉模块的scoped,这里也要考虑全局样式的污染。

    .theme_body{
        top: @{text2}px;
        background: @{color1};
    }
    
    .theme_tip{
        padding-top: @{text1}px;
    }
    
    

    这里就是替换逻辑,把提前的锚点全部进行替换,写入我们的主题色

     changeStyle: function(style){
            //text1 状态栏的高度
            //text2 titleBar + 状态栏高度
            var color = '#fff';
            var height = 0;
            style = style.replace( /@{text1}/g, height);
            style = style.replace( /@{color1}/g, color);
            return style;
        },
    

    获取到本地匹配的颜色后,我们读取本地css文件。将替换之后的css文件写入到Head中

    loadStyle(){
            var _this = this;
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.open('get', this.url, true);
            xmlhttp.setRequestHeader("Content-Type", "application/json");
            xmlhttp.send();
            xmlhttp.onreadystatechange = function (){
                if(xmlhttp.readyState == 4){
                    //这里就是替换之后的 css数据
                    var styleContent = _this.changeStyle(xmlhttp.responseText);
                    var style = document.createElement('style');
                    //这里就是本地路径的css url
                    style.setAttribute('path',_this.url);
                    style.innerHTML = styleContent.trim();
                    //最后写入到head中
                    document.head.appendChild(style);
                }
            };
        },
    

    总结

    以上就是这个主题替换的核心思路,这个方法的好处就是,对于大量的主题有很好的拓展性。只需要增加对应的配置即可。缺点也很明显,在vue项目中需要有良好的命名习惯,尽量少用scoped,避免全局主题样式覆盖不了。同事class类名的权重也十分关键,现在less,sass成了比较常见的工具,class类名的嵌套已经成了习惯,全局覆盖变得更加痛苦。

    改进方向

    1. 希望让全局覆盖变得不那么困难
    2. 初次加载的时候主题loading会有闪动
  • 相关阅读:
    NOIP模拟 10
    无聊的 邮递员 插头dp
    类实例化对象可以访问静态(static)方法,但是不能访问静态属性。
    PHP——抽象类与接口的区别
    工厂模式
    win10 专业版 git bash 闪退问题终极解决方案
    git基本的使用原理
    排序算法-插入排序
    如何进行CodeReview
    php中的各种http报错的报错的状态码的分析
  • 原文地址:https://www.cnblogs.com/wangziye/p/11939728.html
Copyright © 2011-2022 走看看