cxxjackie 发表于 2023-1-26 23:33:22

css的动态修改:var与calc

(论坛最近人气不佳,写点东西水水\~)
脚本注入css,这个大部分人都会,但一般只适用于静态的css,如果想动态修改怎么办?你可能会写这样的代码:

```js
元素.style.display = 'none';
```

如果还希望加important以提高优先级,得写成这样:

```js
元素.style.setProperty('display', 'none', 'important');
```

在需要修改的样式特别多的情况下,这种写法非常繁琐,还可能引起页面多次渲染,可以考虑这样写:

```js
元素.style.cssText += 'display: none !important;visibility: hidden !important;';
```

cssText同时修改多个属性而只渲染一次,+=在遇到已有的属性时,会自动做覆盖处理。以上所有写法都有一个共同的问题:你需要先获取到元素才能设置样式。我们知道元素并不是onload后就全加载完的,有些加载较慢,有些你点了选项才会生成,这也是注入css的一大优势:你不需要管元素何时加载、存不存在,只要写好规则就行了。
css能否做到动态修改呢?移除style再插入新的style?对现有style的文本做正则替换?这也太麻烦了,来看看css的方案:

```html
<div style="--display: none;">
    <div id="test" style="display: var(--display) !important;"></div>
</div>
```

首先在父元素上自定义一个叫--display的属性(自定义属性必须以--开头),然后在子元素中用var()引用该属性的值。注意到了吗?子元素的样式变静态了,意味着可以直接注入css:

```js
GM_addStyle('#test{display: var(--display) !important;}');
```

自定义属性不仅仅限定在父元素上,只要是父级的都可以,比如直接放在body上,所有后代元素都可以引用到这个值,这样一来,我们就不需要管子元素的加载时机了。当多个父级存在同名定义时,引用遵循就近原则。怎么动态修改呢?自定义属性不能通过style.属性名访问到,但可以setProperty:

```js
documemt.body.style.setProperty('--display', 'none');
```

或者cssText修改多条:

```js
documemt.body.style.cssText += '--display: none;--visibility: hidden;';
```

当需要改变样式时,只需改变body上自定义属性的值即可,如此我们就实现了动态修改css而无视加载时机。注意自定义属性的important应该加在目标元素上,加在父元素上的作用是提高同名自定义属性的优先级。自定义属性还可以给多个元素共享,在一些场景下使用也非常方便。
css中calc语句可用于一些简单的计算,比如:

```css
width: calc(100% / 2);
```

这看起来有点傻,我直接算好了写上去不行吗?所以他一般用在这种场景:

```css
width: calc(100% - 100px);
```

问题来了,calc可以做动态计算吗?当然可以,我是说,他可以对自定义属性做计算:

```css
width: calc(var(--video-width) / 2);
```

这个应用场景就比较广泛了,你可以在任意父级元素上定义一个变量(比如视频的宽高),其他元素的大小以该变量为基准,只要一行代码改变变量的值,所有元素都会跟着拉伸。
calc仅能计算数值型的自定义属性(含单位),像前面的--display是字符型,套calc就不行了。另外var不能简单的当成字符串理解(实际是字符串带一个空格),像下面的写法就是错误的:

```css
width: var(--video-width)px
```

可以由calc改变单位,比如有些属性你希望用px,有些用em,那就可以把自定义属性设为不带单位的数字,然后calc赋予单位:

```css
width: calc(var(--video-width) * 1px);
```

甚至可以改变原单位,上面的--video-width如果带单位,\* 1px也能把单位变成px。

var与calc的结合如果使用得当,可以有效简化我们的脚本代码,你不再需要关注元素何时加载,一行代码也可以影响多个元素的显示效果。`Write less, do more!`

bigonion 发表于 2023-1-27 02:21:07

ggnb!








李恒道 发表于 2023-1-27 13:13:21

calc+var确实可玩性提高很多
在动画效果里好像偶尔也能看到
----------------------------------
{:4_98:}论坛要过年之前流量就跌一大截
最近显得很死
也看不到什么提问搞得好无聊

李恒道 发表于 2023-1-27 15:38:59

话说c大来玩原神啊
嗷嗷好玩

王一之 发表于 2023-1-27 19:33:27

呜呜呜 感动,最近确实人少了。到淡季了(和脚本流量有关系),而且大过年的,都忙(我直到前天才有时间上论坛)

cxxjackie 发表于 2023-1-27 22:41:14

李恒道 发表于 2023-1-27 15:38
话说c大来玩原神啊
嗷嗷好玩

晕3D。。。

李恒道 发表于 2023-1-28 09:49:26

cxxjackie 发表于 2023-1-27 22:41
晕3D。。。

话说晕3D的人会晕车嘛
2.5D也会晕嘛,比如王者荣耀

cxxjackie 发表于 2023-1-28 22:27:31

李恒道 发表于 2023-1-28 09:49
话说晕3D的人会晕车嘛
2.5D也会晕嘛,比如王者荣耀

不会,晕车和晕3D的原理不同,王者没玩过,每个人轻重程度不一样的。
页: [1]
查看完整版本: css的动态修改:var与calc