小tips;CSS和JS“通信”

Posted 恪愚

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小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>

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

使用前需注意:本规则依托于vite,除此之外需先引入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>

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

@media (prefers-color-scheme: dark) 
	/* 黑暗模式,深色主题 */


@media (prefers-color-scheme: light) 
	/* 浅色主题 */

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

@media (any-hover: none) 
	/* 设备不支持hover事件 */

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

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

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

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

但是我们可以通过

  1. content伪元素内容传参

例如:

@media (any-hover: none) 
    body::before 
        content: 'hoverNone';
        display: none;
    

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

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

这样,我们就可以根据::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;
    

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

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

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

以上是关于小tips;CSS和JS“通信”的主要内容,如果未能解决你的问题,请参考以下文章

如何在 vuetify 的浅色主题中启用具有自定义颜色的深色模式?

如何反转状态栏的深色和浅色内容以适应 Xcode 中的深色模式

windowbackground 在深色和浅色主题中不起作用

在材料设计组件中如何计算原色的浅色和深色版本?

如何在 Storybook 6.0 中自定义深色和浅色主题

macOS X Mojave - 浅色和深色外观模式切换[关闭]