天天看點

小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(65,184,131);
}
</style>      

但是在 vue3.2 中,尤大提出了一個概念:Js in Css。它讓我們可以在 css 中使用 js 變量,更好的控制動畫的軌迹!進而達到“js向css傳值”的效果。

使用前需注意:本規則依托于​

​vite​

​​,除此之外需先引入​

​vars​

​:

小tips;CSS和JS“通信”
<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(65,184,131);
  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:) {
  /* 小螢幕寬度下的響應式布局 */
}      

這倒是可以直接在 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;
    }
}      
var mode = getComputedStyle(document.documentElement).getPropertyValue('--mode').trim();
// mode結果是'"dark"'則表示黑夜主題,深色模式,黑暗風格,護眼模式。      

繼續閱讀