JavaScript 如何與 CSS 和 SASS 共享數(shù)據(jù)

來源: css-tricks.com
作者:Marko Ilic
編譯:大道至簡

JavaScript 與 CSS 已經(jīng)相生相伴 20 年了,但是要在它們之間共享數(shù)據(jù)卻非常困難踊东。當(dāng)然蒲稳,這方面肯定有過一些嘗試胖翰,不過我想到的是簡單而又直觀的做法:不需要做代碼結(jié)構(gòu)上的改動(dòng)荧缘,而是利用 CSS 自定義屬性帕膜,甚至是 Sass 變量枣氧。

CSS 自定義屬性

CSS 自定義屬性現(xiàn)在也不算什么稀罕物了。自從瀏覽器開始支持以來垮刹,就能通過 JavaScript 操作自定義屬性值达吞。

具體來說,用 JavaScript 操作自定義屬性有以下幾種方式荒典。第一個(gè)是 setProperty

document.documentElement.style.setProperty("--padding", 124 + "px"); // 124px

還可以用getComputedStyle酪劫,原因很簡單:自定義屬性也是樣式的一部分,因此也屬于計(jì)算樣式的一部分寺董。

getComputedStyle(document.documentElement).getPropertyValue('--padding') // 124px

同樣覆糟,還可以用getPropertyValue。它可以獲取 HTML 元素的行內(nèi)樣式值:

document.documentElement.style.getPropertyValue("--padding'"); // 124px

注意遮咖,自定義屬性是有作用域的滩字。也就是說必須從指定元素獲取計(jì)算后的樣式。前面由于我們是 在:root 里定義的變量御吞,因此要從這個(gè) HTML 元素上獲取踢械。

Sass 變量

Sass 是預(yù)處理語言,最終要轉(zhuǎn)換成 CSS 才能應(yīng)用到網(wǎng)站頁面上魄藕。所以,像 CSS 自定義屬性那樣用 JavaScript 直接操作是行不通的撵术。

為此背率,我們需要修改下構(gòu)建流程。這一步可能不是必須的,因?yàn)榇蟛糠謽?gòu)建流程配置都已經(jīng)包含了這些 loader寝姿。如果你的項(xiàng)目配置里沒有的話交排,就需要加上如下的 webpack 配置:

module.exports = {
 // ...
 module: {
  rules: [
   {
    test: /\.scss$/,
    use: ["style-loader", "css-loader", "sass-loader"]
   },
   // ...
  ]
 }
};

為了讓 Sass(準(zhǔn)確地說這里是 SCSS)變量在 JavaScript 里可用,我們需要將其導(dǎo)出(export):

// variables.scss
$primary-color: #fe4e5e;
$background-color: #fefefe;
$padding: 124px;

:export {
  primaryColor: $primary-color;
  backgroundColor: $background-color;
  padding: $padding;
}

這里的 :export 部分是黑魔法所在饵筑,webpack 就是用它來導(dǎo)入變量的埃篓。這種方法的妙處是可以用 camelCase 格式重命名變量,并可以選擇要導(dǎo)出的變量根资。

然后把 Sass 文件(variables.scss)導(dǎo)入到 JavaScript架专,這樣就可以訪問文件里的變量了。神不神奇玄帕,意不意外部脚?

import variables from './variables.scss';

/*
 {
  primaryColor: "#fe4e5e"
  backgroundColor: "#fefefe"
  padding: "124px"
 }
*/

document.getElementById("app").style.padding = variables.padding;

值得一提的是,:export 語法有一些限制:

  • 可以在文件里的任何位置裤纹,但必須位于頂層
  • 如果文件里有多個(gè)委刘,這些鍵和值會(huì)合并在一起導(dǎo)出
  • 如果某個(gè) exportedKey有重復(fù),后面的會(huì)覆蓋前面的
  • exportedValue可以包含 CSS 聲明中的任意有效字符(包括空格)
  • exportedValue不需要加引號鹰椒,因?yàn)樗呀?jīng)被處理成字符串了锡移。

在 JavaScript 中訪問 Sass 變量的應(yīng)用場景有哪些呢?其中一個(gè)是共享媒體查詢中的斷點(diǎn)配置漆际。比如這里的breakpoints.scs 文件淆珊,可以用于 JavaScript 中的 matchMedia()方法,來保持?jǐn)帱c(diǎn)設(shè)置的一致性灿椅。

//定義斷點(diǎn)的 Sass 變量
$breakpoints: (
  mobile: 375px,
  tablet: 768px,
  // etc.
);

// 用于媒體查詢的 Sass variables 
$media: (
  mobile: '(max-width: #{map-get($breakpoints, mobile)})',
  tablet: '(max-width: #{map-get($breakpoints, tablet)})',
  // etc.
);

// 導(dǎo)出部分
:export {
  breakpointMobile: unquote(map-get($media, mobile));
  breakpointTablet: unquote(map-get($media, tablet));
  // etc.
}

動(dòng)畫是另一個(gè)應(yīng)用場景套蒂。動(dòng)畫的持續(xù)時(shí)間通常保存在 CSS 中,但是更復(fù)雜的動(dòng)畫可能需要 JavaScript 來實(shí)現(xiàn)茫蛹。

// animation.scss
$global-animation-duration: 300ms;
$global-animation-easing: ease-in-out;

:export {
  animationDuration: strip-unit($global-animation-duration);
  animationEasing: $global-animation-easing;
}

注意操刀,這里在導(dǎo)出變量時(shí)用了strip-unit函數(shù),目的是為了去掉單位婴洼,方便在 JavaScript 里轉(zhuǎn)換數(shù)字骨坑。

// 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,
});

還有一個(gè)是 echarts 圖系列的顏色列表。比如餅圖的各個(gè)部分用的顏色序列柬采,可能也要在圖之外使用欢唾。為了便于維護(hù),最好是定義在同一個(gè)地方粉捻。


總之礁遣,這樣就可以輕松地實(shí)現(xiàn) CSS、Sass 和 JavaScript 之間交換數(shù)據(jù)肩刃,確實(shí)挺不錯(cuò)祟霍。變量共享讓代碼變得更簡單杏头,實(shí)現(xiàn)了 DRY(Dont' Repeat Yourself)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末沸呐,一起剝皮案震驚了整個(gè)濱河市醇王,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌崭添,老刑警劉巖寓娩,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異呼渣,居然都是意外死亡棘伴,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門徙邻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來排嫌,“玉大人,你說我怎么就攤上這事缰犁〈镜兀” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵帅容,是天一觀的道長颇象。 經(jīng)常有香客問我,道長并徘,這世上最難降的妖魔是什么遣钳? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮麦乞,結(jié)果婚禮上蕴茴,老公的妹妹穿的比我還像新娘。我一直安慰自己姐直,他們只是感情好倦淀,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著声畏,像睡著了一般撞叽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上插龄,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天愿棋,我揣著相機(jī)與錄音,去河邊找鬼均牢。 笑死糠雨,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的徘跪。 我是一名探鬼主播见秤,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼砂竖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了鹃答?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤突硝,失蹤者是張志新(化名)和其女友劉穎测摔,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體解恰,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡锋八,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了护盈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挟纱。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖腐宋,靈堂內(nèi)的尸體忽然破棺而出紊服,到底是詐尸還是另有隱情,我是刑警寧澤胸竞,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布欺嗤,位于F島的核電站,受9級特大地震影響卫枝,放射性物質(zhì)發(fā)生泄漏煎饼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一校赤、第九天 我趴在偏房一處隱蔽的房頂上張望吆玖。 院中可真熱鬧,春花似錦马篮、人聲如沸沾乘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽意鲸。三九已至,卻和暖如春尽爆,著一層夾襖步出監(jiān)牢的瞬間怎顾,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工漱贱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留槐雾,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓幅狮,卻偏偏與公主長得像募强,于是被迫代替她去往敵國和親株灸。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容