做者:Marko Ilic翻譯:瘋狂的技術宅javascript
原文:https://css-tricks.com/gettin...css
未經容許嚴禁轉載前端
JavaScript 和 CSS 已經並存超過了 20 年。可是在它們之間共享數據很是困難。固然也有大量的嘗試。可是我所想到的是一些簡單而直觀的內容——不涉及結構更改,而是使用 CSS 自定義屬性甚至 Sass 變量。java
自定義屬性在這裏應該不會使人感到驚訝。自瀏覽器提供支持以來,他們一直在作的一件事就是與 JavaScript 協同工做以設置和操做值。webpack
不過具體來講,咱們能夠經過幾種方式使 JavaScript 與自定義屬性一塊兒工做。可使用 setProperty
設置自定義屬性的值:程序員
document.documentElement.style.setProperty("--padding", 124 + "px"); // 124px
咱們還能夠用 JavaScript 中的 getComputedStyle
來檢索 CSS 變量。其背後的邏輯很是簡單:自定義屬性是樣式的一部分,所以它們是計算樣式的一部分。web
getComputedStyle(document.documentElement).getPropertyValue('--padding') // 124px
與 getPropertyValue
同樣。這樣咱們就能夠從 HTML 標記的內聯樣式中得到自定義屬性值。面試
document.documentElement.style.getPropertyValue("--padding'"); // 124px
請注意,自定義屬性是有做用域的。這意味着咱們須要從特定元素獲取計算樣式。正如咱們以前在:root
中定義變量同樣,咱們將它們放在 HTML 元素上。json
Sass 是一種預處理語言,這意味着它在成爲網站的一部分以前就已經變成了 CSS。因此沒法用與 CSS 自定義屬性相同的方式從 JavaScript 訪問它們(能夠在 DOM 中以計算樣式訪問它們)。segmentfault
咱們須要經過修改本身的構建過程來改變這一點。我懷疑在大多數狀況下並不須要作太多,由於裝載程序一般已是構建過程的一部分。可是若是你的項目並不是如此,則咱們須要三個模塊,這些模塊可以導入和翻譯 Sass 模塊。
在 Webpack 配置中看上去是這樣:
module.exports = { // ... module: { rules: [ { test: /\.scss$/, use: ["style-loader", "css-loader", "sass-loader"] }, // ... ] } };
爲了使 Sass(或者在這種狀況下,具體來講是 SCSS)變量可用於 JavaScript,咱們須要 「export」 它們。
// variables.scss $primary-color: #fe4e5e; $background-color: #fefefe; $padding: 124px; :export { primaryColor: $primary-color; backgroundColor: $background-color; padding: $padding; }
:export
塊是 webpack 用來導入變量的。這種方法的好處是,咱們能夠用 camelCase 語法重命名變量,而後選擇要公開的內容。
而後,把 Sass 文件(variables.scss
)導入 JavaScript,從而能夠訪問文件中定義的變量。
import variables from './variables.scss'; /* { primaryColor: "#fe4e5e" backgroundColor: "#fefefe" padding: "124px" } */ document.getElementById("app").style.padding = variables.padding;
值得一提的是對 :export
語法的一些限制:
exportedKey
被複制,則最後一個(按源順序)優先。exportedValue
能夠含有在 CSS 聲明值中任何有效的字符(包括空格)。exportedValue
不須要被引用,由於它已經被看成文本字符串了。有不少方法能夠方便地訪問 JavaScript 中的 Sass 變量。我傾向於使用這種共享斷點的方法。下面是個人breakpoints.scs
文件,後來我將其導入 JavaScript 中,這樣我能夠用 matchMedia()
方法獲得一致的斷點。
// Sass variables that define breakpoint values $breakpoints: ( mobile: 375px, tablet: 768px, // etc. ); // Sass variables for writing out media queries $media: ( mobile: '(max-width: #{map-get($breakpoints, mobile)})', tablet: '(max-width: #{map-get($breakpoints, tablet)})', // etc. ); // The export module that makes Sass variables accessible in JavaScript :export { breakpointMobile: unquote(map-get($media, mobile)); breakpointTablet: unquote(map-get($media, tablet)); // etc. }
動畫是另外一個用例。動畫的持續時間一般存儲在 CSS 中,可是須要 JavaScript 的幫助才能完成更復雜的動畫。
// animation.scss $global-animation-duration: 300ms; $global-animation-easing: ease-in-out; :export { animationDuration: strip-unit($global-animation-duration); animationEasing: $global-animation-easing; }
請注意,在導出變量時,我用了自定義 strip-unit
函數。這使我能夠輕鬆地在 JavaScript 中解析內容。
// main.js document.getElementById('image').animate([ { transform: 'scale(1)', opacity: 1, offset: 0 }, { transform: 'scale(.6)', opacity: .6, offset: 1 } ], { duration: Number(variables.animationDuration), easing: variables.animationEasing, });
這樣就能輕鬆地在CSS、Sass 和 JavaScript 之間交換數據。共享這樣的變量使代碼簡單而不囉嗦。
固然還有多種方法能夠實現相同的目的。 Les James 分享了一種有趣的方法,該方法容許 Sass 和 JavaScript 經過 JSON 進行交互。我對此可能存有偏見,可是我發如今這裏介紹的方法是最簡單、最直觀的。無需對你已經在使用和正在編寫的 CSS 和 JavaScript 進行瘋狂的修改。