• 小tips;CSS和JS“通信”


    假如我有一个需求,必须通过 js 执行动画,还得让 css 去配合。
    拿一个简单却不太恰当的例子来说:opacity‘一闪一闪’效果的实现。传统Vue必须要利用“动态style”。

    <template>
    	<h1 :style="{opacity: opacity}">Vue</h1>
    </template>
    <script>
    export default {
    	data () {
    		return { opacity: 0 }
    	}mounted () {
    		setInterval(() => {
    			this.opacity >= 1 && (this.opacity = 0)
    			this.opacity += 0.2
    		}, 300)
    	}
    }
    </script>
    <style>
    h1 {
    	color: rgb(65184131);
    }
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    但是在 vue3.2 中,尤大提出了一个概念:Js in Css。它让我们可以在 css 中使用 js 变量,更好的控制动画的轨迹!从而达到“js向css传值”的效果。

    使用前需注意:本规则依托于vite,除此之外需先引入vars
    vars

    <template>
    	<h1>Vue</h1>
    </template>
    <script>
    export default {
    	data () {
    		return { opacity: 0 }
    	}mounted () {
    		setInterval(() => {
    			this.opacity >= 1 && (this.opacity = 0)
    			this.opacity += 0.2
    		}, 300)
    	}
    }
    </script>
    <style vars="{ opacity }"> <!-- 绑定css中接收的变量 -->
    h1 {
    	color: rgb(65184131);
    	opacity: var (--opacity);
    }
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    那 css 怎么向 js 传参?比如“主题跟随系统变化”:

    @media (prefers-color-scheme: dark) {
    	/* 黑暗模式,深色主题 */
    }
    
    @media (prefers-color-scheme: light) {
    	/* 浅色主题 */
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    比如“响应式布局中判断pc还是移动端”:

    @media (any-hover: none) {
    	/* 设备不支持hover事件 */
    }
    
    • 1
    • 2
    • 3

    等等。
    这些情况大多是由于页面的变化要导致一些感官(UI)和操作上的改变。而 css 和 js 的“边界一致性”无法保证。

    拿上面的any-hover来说,js 中就没有支持相关的 API。
    除此之外,通常还有人这么做:

    @media screen and (max-width: 480px) {
    	/* 小屏幕宽度下的响应式布局 */
    }
    
    • 1
    • 2
    • 3

    这倒是可以直接在 js 中对screen.width进行if操作。但是假如一段时间之后,发现这个临界宽度有问题(比如手机横屏的时候),这时候但凡少修改一方,就会导致“bug”的产生。实为不智。

    但是我们可以通过

    1. content伪元素内容传参

    例如:

    @media (any-hover: none) {
        body::before {
            content: 'hoverNone';
            display: none;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    此时就可以通过JS代码获取body伪元素传递的信息是什么了:

    var strContent = getComputedStyle(document.body, '::before').content;
    // strContent结果是'none'则表示支持hover
    // strContent结果是'"hoverNone"'则表示不支持hover经过,需要换成click事件
    
    • 1
    • 2
    • 3

    这样,我们就可以根据::before, ::after伪元素配合content属性,获知CSS中传递的信息了。
    这种传参方式的优点在于兼容性相对较好,但是不足却也很明显,那就是我们传递的参数值的数量是有限的,如果我们想一次性传多个值,就有些捉襟见肘,此时可以试试下面这种方法,借助CSS自定义属性。

    1. CSS自定义属性(CSS变量)传参

    还是拿“跟随系统改变主题色”来说,有了CSS自定义属性(CSS变量),黑暗模式和浅色模式的开发和维护工作就变得相对容易很多。

    :root {
        --mode: 'unknown';
    }
    @media (prefers-color-scheme: dark) {
        /* 黑暗模式 */
        :root {
             --mode: 'dark';
             --colorLink: #bfdbff;
             --colorMark: #cc0000;
             --colorText: #ffffff;
             --colorLight: #777777;
        }
    }
    @media (prefers-color-scheme: light) {
        /* 浅色主题 */
        :root {
             --mode: 'light';
             --colorLink: #34538b;
             --colorMark: #cc0000;
             --colorText: #000000;
             --colorLight: #cccccc;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    JS 同样可以检测到自定义属性:

    var mode = getComputedStyle(document.documentElement).getPropertyValue('--mode').trim();
    // mode结果是'"dark"'则表示黑夜主题,深色模式,黑暗风格,护眼模式。
    
    • 1
    • 2

    使用CSS自定义属性传统的好处是非常灵活,我们可以定义很多很多的变量都可以。而且目前我们也没有任何必要担心兼容性的问题。

  • 相关阅读:
    自然语言处理:长文本场景下的关键词抽取实践
    基于自适应Sigmoid型函数的内镜图像增强与空间变颜色再现方法
    【MySQL】区分:等值连接/自连接/自然连接/外连接 以及ON和Where使用
    【简单教程】利用Net2FTP构建免费个人网盘,实现便捷的文件管理
    论文学习笔记(一):KRYSTAL: 审计数据中基于数据图的战术攻击发现框架
    动态规划算法的题到底应该怎么做?思路教给你自己写
    nodejs excel操作(读取和生成)
    Rust的derive思考
    软件测试/测试开发丨测试用例自动录入 学习笔记
    SpringBoot集成Mybatis-Plus
  • 原文地址:https://blog.csdn.net/qq_43624878/article/details/125576298