上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
返回列表 发新帖

css的动态修改:var与calc

[复制链接]
  • TA的每日心情
    慵懒
    2022-3-8 11:41
  • 签到天数: 2 天

    [LV.1]初来乍到

    22

    主题

    860

    回帖

    1359

    积分

    荣誉开发者

    积分
    1359

    荣誉开发者卓越贡献油中2周年生态建设者油中3周年挑战者 lv2

    发表于 2023-1-26 23:33:22 | 显示全部楼层 | 阅读模式

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

    元素.style.display = 'none';

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

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

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

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

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

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

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

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

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

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

    或者cssText修改多条:

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

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

    width: calc(100% / 2);

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

    width: calc(100% - 100px);

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

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

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

    width: var(--video-width)px

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

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

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

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

  • TA的每日心情
    开心
    2024-2-27 14:20
  • 签到天数: 88 天

    [LV.6]常住居民II

    22

    主题

    97

    回帖

    306

    积分

    荣誉开发者

    积分
    306

    油中2周年新人报道荣誉开发者生态建设者

    发表于 2023-1-27 02:21:07 | 显示全部楼层
    ggnb!








    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    632

    主题

    5156

    回帖

    6039

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6039

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2023-1-27 13:13:21 | 显示全部楼层
    calc+var确实可玩性提高很多
    在动画效果里好像偶尔也能看到
    ----------------------------------
    论坛要过年之前流量就跌一大截
    最近显得很死
    也看不到什么提问搞得好无聊
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    632

    主题

    5156

    回帖

    6039

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6039

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2023-1-27 15:38:59 | 显示全部楼层
    话说c大来玩原神啊
    嗷嗷好玩
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-13 10:14
  • 签到天数: 211 天

    [LV.7]常住居民III

    290

    主题

    3855

    回帖

    3784

    积分

    管理员

    积分
    3784

    管理员荣誉开发者油中2周年生态建设者喜迎中秋油中3周年挑战者 lv2

    发表于 2023-1-27 19:33:27 | 显示全部楼层
    呜呜呜 感动,最近确实人少了。到淡季了(和脚本流量有关系),而且大过年的,都忙(我直到前天才有时间上论坛)
    上不慕古,下不肖俗。为疏为懒,不敢为狂。为拙为愚,不敢为恶。/ 微信公众号:一之哥哥
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2022-3-8 11:41
  • 签到天数: 2 天

    [LV.1]初来乍到

    22

    主题

    860

    回帖

    1359

    积分

    荣誉开发者

    积分
    1359

    荣誉开发者卓越贡献油中2周年生态建设者油中3周年挑战者 lv2

    发表于 2023-1-27 22:41:14 | 显示全部楼层
    李恒道 发表于 2023-1-27 15:38
    话说c大来玩原神啊
    嗷嗷好玩

    晕3D。。。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    632

    主题

    5156

    回帖

    6039

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6039

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2023-1-28 09:49:26 | 显示全部楼层

    话说晕3D的人会晕车嘛
    2.5D也会晕嘛,比如王者荣耀
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2022-3-8 11:41
  • 签到天数: 2 天

    [LV.1]初来乍到

    22

    主题

    860

    回帖

    1359

    积分

    荣誉开发者

    积分
    1359

    荣誉开发者卓越贡献油中2周年生态建设者油中3周年挑战者 lv2

    发表于 2023-1-28 22:27:31 | 显示全部楼层
    李恒道 发表于 2023-1-28 09:49
    话说晕3D的人会晕车嘛
    2.5D也会晕嘛,比如王者荣耀

    不会,晕车和晕3D的原理不同,王者没玩过,每个人轻重程度不一样的。
    回复

    使用道具 举报

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表