挑戰 JS30 #3 - CSS Variables

更新於 發佈於 閱讀時間約 7 分鐘

本次的挑戰是「CSS Variables」,需要達成的目標是:

「使用者操作拉桿或是選色器時,底下圖片的樣式會有對應的變化。」

此次挑戰涉及以下內容:

  • input 標籤
  • 效果對應的 CSS 屬性
  • CSS 變數
  • 事件綁定

嘗試拆解流程

畫完流程圖之後,很容易看出自己不確定的部分,將這些部分各個擊破以後,也就順利梳理出實作的脈絡,所以這次挑戰比預期還快完成。

雖然看了作者的寫法以後,又發現自己寫得好冗哈哈,這篇文章就一起來看看此次挑戰有哪些知識點和需要修正的地方吧!

raw-image

看完作者的寫法之後,發現流程可以簡化成這樣

raw-image

知識點

CSS - filter 屬性

可以套用模糊、對比等濾鏡效果,更多值可參考 MDN

filter: blur(10px); //模糊
filter: brightness(10%); //明亮

CSS 變數

  • 宣告變數:通常會放在 :root 選擇器中,並使用 --變數名稱 方式來宣告
:root{
--bg-color: #ccc;
--primary: #333;
}
  • 取用變數:需要使用 var 取值
body{
background-color: var(--bg-color);
}

還可以寫得更好的地方

JS30 作者直接透過迴圈監聽每個 input,筆者則是一個一個手動挑出來,程式碼不只冗長,還很沒有效率,以下比較看看兩者寫法:

  • 筆者的寫法
const spacerController = document.querySelector("#spacing");
const blurController = document.querySelector("#blur");
const colorController = document.querySelector("#base");
const target = document.querySelector("img");

function changeSpacer() {
target.style.borderWidth = `${spacerController.value}px`;
}
function changeBlur() {
target.style.filter = `blur(${blurController.value}px)`;
}
function changeColor() {
target.style.borderColor = `${colorController.value}`;
}

spacerController.addEventListener("input", changeSpacer);
blurController.addEventListener("input", changeBlur);
colorController.addEventListener("input", changeColor);
  • 作者的寫法
const inputs = document.querySelectorAll(".controls input");

function handleUpdate() {
const suffix = this.dataset.sizing || "";
document.documentElement.style.setProperty(
`--${this.name}`,
this.value + suffix
);
}

inputs.forEach((input) => input.addEventListener("change", handleUpdate));
inputs.forEach((input) => input.addEventListener("mousemove", handleUpdate));


這次比較多是寫法上可以再調整的地方,所以下面會再進一步探討:

CSS 變數 + documentElement

將變數放到 :root 裡,再透過 JS 去選擇根元素,就能直接對一開始在 :root 裡宣告的變數做操作,也就能直接變動套用了這些變數的 CSS 屬性,相當方便!

另外都是透過 input 的 name 或是自行新增 data 屬性來組合出想要指向的變數名稱與單位,以及 value 取得數值

<input
id="spacing"
type="range"
name="spacing"
min="10"
max="200"
value="10"
data-sizing="px"
/>;
:root {
--​base: #fff;

//這邊的值要對應 input 元素的 value 值,視覺和實際值才會相符
--spacing: 10px;
--blur: 10px;
}

img {
border-width: var(--spacing);
border-style: solid;
border-color: var(--base);
filter: blur(var(--blur));
}
function control(){
//如果 this.dataset.size 為 true 就回傳該值
//為 false 就回傳空字串
const unit = this.dataset.size || "";
document.documentElement.style.setProperty(`--${this.name}`, this.value+unit;
}

之後透過 forEach 迴圈將事件賦予到所有 input 元素上。

input 事件

比較特別的是這邊的事件是使用 "input",當滑鼠拖曳時就會觸發事件,原本一開始是使用 "change" 事件,但是都要在滑鼠拖曳再放開後才會觸發事件,相對沒那麼即時。

const controllers = document.querySelectorAll(".controls input");
controllers.forEach((controller) => {
controller.addEventListener("input", control);
});


附上此次實作結果,今天就介紹到這裡,若有錯誤歡迎指正,也歡迎大家分享自己的看法。

參考資料

留言
avatar-img
留言分享你的想法!
avatar-img
傑米的沙龍
7會員
30內容數
正在一點一滴學習程式,相信知識量總有一天會匯聚成大海,目前專門研究前端中。
你可能也想看
Thumbnail
常常被朋友問「哪裡買的?」嗎?透過蝦皮分潤計畫,把日常購物的分享多加一個步驟,就能轉換成現金回饋。門檻低、申請簡單,特別適合學生與上班族,讓零碎時間也能創造小確幸。
Thumbnail
常常被朋友問「哪裡買的?」嗎?透過蝦皮分潤計畫,把日常購物的分享多加一個步驟,就能轉換成現金回饋。門檻低、申請簡單,特別適合學生與上班族,讓零碎時間也能創造小確幸。
Thumbnail
嗨!歡迎來到 vocus vocus 方格子是台灣最大的內容創作與知識變現平台,並且計畫持續拓展東南亞等等國際市場。我們致力於打造讓創作者能夠自由發表、累積影響力並獲得實質收益的創作生態圈!「創作至上」是我們的核心價值,我們致力於透過平台功能與服務,賦予創作者更多的可能。 vocus 平台匯聚了
Thumbnail
嗨!歡迎來到 vocus vocus 方格子是台灣最大的內容創作與知識變現平台,並且計畫持續拓展東南亞等等國際市場。我們致力於打造讓創作者能夠自由發表、累積影響力並獲得實質收益的創作生態圈!「創作至上」是我們的核心價值,我們致力於透過平台功能與服務,賦予創作者更多的可能。 vocus 平台匯聚了
Thumbnail
JavaScript Array 基本操作筆記
Thumbnail
JavaScript Array 基本操作筆記
Thumbnail
題目:完成解決方案,當第一個參數(String 型別)以第二個參數結尾時(也是 String 型別)返回 true。
Thumbnail
題目:完成解決方案,當第一個參數(String 型別)以第二個參數結尾時(也是 String 型別)返回 true。
Thumbnail
雖然表面是一道移除元素的題目,但實際上考的還是搬移。 題目要求的是把val目標值移除,等價於 把非目標值的搬到前面,並且回傳這些剩下來的元素個數(也就是 陣列裡面,非目標值的元素總數​)。 請看下方範例,會更好理解。
Thumbnail
雖然表面是一道移除元素的題目,但實際上考的還是搬移。 題目要求的是把val目標值移除,等價於 把非目標值的搬到前面,並且回傳這些剩下來的元素個數(也就是 陣列裡面,非目標值的元素總數​)。 請看下方範例,會更好理解。
Thumbnail
題目:你的團隊正在開發一個新的高級文本編輯器,你的任務是實現行號功能。請編寫一個函數,該函數接受一個字符串列表作為輸入,並返回每行字符串前面附帶正確的行號。行號從 1 開始計數。格式為 n: 字符串。請注意冒號和空格之間的間隔。
Thumbnail
題目:你的團隊正在開發一個新的高級文本編輯器,你的任務是實現行號功能。請編寫一個函數,該函數接受一個字符串列表作為輸入,並返回每行字符串前面附帶正確的行號。行號從 1 開始計數。格式為 n: 字符串。請注意冒號和空格之間的間隔。
Thumbnail
題目:如果提供的數字在0-9之間,請以文字形式返回。輸入1、輸出 “One”
Thumbnail
題目:如果提供的數字在0-9之間,請以文字形式返回。輸入1、輸出 “One”
Thumbnail
Codewars 是個程式練習網站,筆者主要練習的是 JavaScript,會記錄自己的解法,並參考其他人的寫法來改善自己的程式碼,那麼我們就開始吧!
Thumbnail
Codewars 是個程式練習網站,筆者主要練習的是 JavaScript,會記錄自己的解法,並參考其他人的寫法來改善自己的程式碼,那麼我們就開始吧!
Thumbnail
本次的挑戰是「CSS Variables」,需要達成的目標是:「使用者操作拉桿或是選色器時,底下圖片的樣式會有對應的變化。」
Thumbnail
本次的挑戰是「CSS Variables」,需要達成的目標是:「使用者操作拉桿或是選色器時,底下圖片的樣式會有對應的變化。」
Thumbnail
從跟著教學影片把老師的程式抄過一遍,變成看到題目能把題目轉為程式,對於初學者來說蠻困難的。所以我想以初學者的角度來分享自己怎麼適應這段轉換的過程,以及我解題的方法是什麼。(也順便紀錄一下自己的思路) ※主題:流程控制為主的綜合小應用 ※題目:讓使用者輸入一個數字,並用程式判斷該數字是否為質數
Thumbnail
從跟著教學影片把老師的程式抄過一遍,變成看到題目能把題目轉為程式,對於初學者來說蠻困難的。所以我想以初學者的角度來分享自己怎麼適應這段轉換的過程,以及我解題的方法是什麼。(也順便紀錄一下自己的思路) ※主題:流程控制為主的綜合小應用 ※題目:讓使用者輸入一個數字,並用程式判斷該數字是否為質數
Thumbnail
這只是一篇測試功能的文章
Thumbnail
這只是一篇測試功能的文章
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News