iT邦幫忙

2021 iThome 鐵人賽

DAY 3
0
自我挑戰組

JS30 學習日記系列 第 3

Day 3 - Playing with CSS

前言

JS 30 是由加拿大的全端工程師 Wes Bos 免費提供的 JavaScript 簡單應用課程,課程主打 No FrameworksNo CompilersNo LibrariesNo Boilerplate 在30天的30部教學影片裡,建立30個JavaScript的有趣小東西。

另外,Wes Bos 也很無私地在 Github 上公開了所有 JS 30 課程的程式碼,有興趣的話可以去 fork 或下載。


本日目標

學習建立 CSS 變數並透過 JavaScript 監聽 mousemove、change 事件,接著主動去更新變數的值,讓使用者得以調整圖片框的大小和背景色、圖片的模糊程度等等...。


解析程式碼

HTML 部分

由最外層的代表控制列(.controls)的div元素包覆住內部用來調整圖片的三個 input 元素(#spacing、#blur、#base)。其中兩個 input 元素上有設定 data- 屬性,標明使用的單位。

<h2>Update CSS Variables with <span class='hl'>JS</span></h2>

<div class="controls">
    <label for="spacing">Spacing:</label>
    <input id="spacing" type="range" name="spacing" min="10" max="200" value="10" data-sizing="px">

    <label for="blur">Blur:</label>
    <input id="blur" type="range" name="blur" min="0" max="25" value="10" data-sizing="px">

    <label for="base">Base Color</label>
    <input id="base" type="color" name="base" value="#ffc600">
</div>

<img src="https://source.unsplash.com/7bwQXzbF6KE/800x500">

CSS 部分

--變數名稱的方式,宣告三個 CSS 的全域變數,並且是在根元素之下。

:root{ /*CSS 全域變數*/
      --base: #ffc600;
      --spacing: 10px;
      --blur: 10px;
}

要使用 CSS 變數,我們可以利用var()並在裡面放入要使用的變數名稱。

img{
    padding: var(--spacing); /*使用關鍵字 var( )並在括號內填入想套用的變數名稱*/
    background: var(--base);
    filter: blur(var(--blur)); /*套上帶有模糊效果的濾鏡*/
}

.hl{
    color: var(--base);
}
補充說明1:

CSS 變數的補充資料 >>> :root 根目錄選取器 - 叫你阿爸出來講

補充說明2:

使用 CSS 的 filter 屬性,主要目的是套一層濾鏡到圖片上,常見的值除了有 blur 以外,還有 contrast、grayscale 等等...。 詳細見此

JS部分

取得所有的 input 標籤,要注意的是這裡的資料型態是 NodeList 而不是 Array

相較 Array 而言,NodeList 能用的方法少很多。

/*JS*/
const inputs = document.querySelectorAll('.controls input'); /*取得所有的 input 元素,資料型態是 NodeList 不是 Array*/

將每個取得的 input 標籤都分別註冊兩個事件監聽器,當 input 標籤的 value 屬性有變動(change)或是滑鼠有在 input 標籤的桿上移動時,就透過 handleUpdate() 方法進行事件處理。

function handleUpdate(){
   
}

inputs.forEach(input => input.addEventListener('change',handleUpdate)); /*當數值改變*/
inputs.forEach(input => input.addEventListener('mousemove',handleUpdate)); /*當滑鼠移動*/

handleUpdate() 方法內宣告 suffix 變數,透過 dataset.sizing 取得對應屬性的單位。當屬性沒有單位時,指定 suffix 為空字串,避免因為是 undefined 出現錯誤。

最後,藉著 document.documentElement.style 取得文件上"根元素"的 CSS 屬性,進一步使用 setProperty() 調整 CSS 屬性值(注意,有些屬性必須要加上單位)。

function handleUpdate(){
    const suffix = this.dataset.sizing || ''; /*取得單位,當單位不存在時就指定為空字串*/
    document.documentElement.style.setProperty(`--${this.name}`,this.value + suffix); /*Template literals*/
}
補充說明1:

NodeList 的補充資料 -- JavaScript HTML DOM Node Lists

補充說明2:

透過 dataset 實際取得的 data-自訂名稱 屬性內容如下:

我們可以進一步使用 dataset.自訂名稱,取得裡面代表單位的"px"。
(圖片中的 sizing 等同於標籤上的 data-sizing)

範例網頁請按此


上一篇
Day 2 - CSS + JS Clock
下一篇
Day 4 - Array Cardio Day 1
系列文
JS30 學習日記30

尚未有邦友留言

立即登入留言