iT邦幫忙

2022 iThome 鐵人賽

DAY 3
0

03 - CSS Variables

專案簡介

第三天的目標是可以利用畫面的拉桿調整圖片 CSS 屬性的 padding、background、filte,以及 .h1 的 color

課程影片:JS30 03
導讀影片:Alex

初始文件

Github 檔案位置:03 - CSS Variables

網頁一開始的樣子如下

可以先去看看 最後的成品

正式製作

流程

將程式的要求拆分步驟後,我們需要做的事情如下

  1. 獲取滑桿的 input
  2. 設定 CSS 全域變數
  3. 以 JS 讀入 1. 數值,並賦值於 2. 設定的全域變數

獲取滑桿的 input

首先要利用前兩天學到的選取元素和監聽

const inputs = document.querySelectorAll('.controls input');

inputs.forEach(input => {
  input.addEventListener('事件', changeHandler);
})

這次我們使用了新的事件 changemousemove

首先我們來加上 change事件,並看看他吐給我們的資訊

const inputs = document.querySelectorAll('.controls input');

function changeHandler(){
  console.log(this);
}

inputs.forEach(input => {
  input.addEventListener('change', changeHandler);
})

可以看到在拉動完滑桿後他確實偵測到了元素,其中我們可以利用 name 及 value 作為之後要設定變數的名稱和賦值內容。

但在這樣拉動下發現,只有在鬆開拉桿時他才會偵測到數值,我們希望可以在拉動時漸進式改變圖片的 CSS 屬性,因此會需要用到 mousemove 事件

const inputs = document.querySelectorAll('.controls input');

function changeHandler(){
  console.log(this.name, this.value);
}

inputs.forEach(input => {
  input.addEventListener('change', changeHandler);
  input.addEventListener('mousemove', changeHandler);
})

在他們的搭配下,我們就能實時偵測拉桿的 name 及 value 值

設定 CSS 全域變數

接下來,我們要使用 :root 來設定 CSS 全域變數,:root 的意義就代表著 html 元素,因此在這裡設置的變數會是全域的。另外,:root 的優先級 > .html

CSS 變數 設定的規則就是 --變數名稱: 值,範例如下

:root{
  --base: #ffc600;
  --spacing: 10px;
  --blur: 10px;
}

接下來我們要利用剛設定好的全域變數,賦值給 img 和 h1 的 CSS 屬性

需要注意的是在使用時要使用 var(變數),否則會被當成在 class 建立變數

img{
  padding: var(--spacing);
  background: var(--base);
  filter: blur(var(--blur));
}

.h1{
  color: var(--base);
}

以 JS 讀入 1. 數值,並賦值於 2. 設定的全域變數

最後我們要來撰寫 functions 裡面的內容了!

在此,我們可以先嘗試使用前兩天學到的方式達到目的,只需要用 switch(this.name) 賦值給 .img 和 .h1 即可

但這樣撰寫的弊端就是每當我們要渲染一個元素,就勢必得要再選取一次,如 case base 中使用了兩次 document.querySelector

function changeHandler(){
  console.log(this.name, this.value);
  switch(this.name){
    case 'spacing':
      document.querySelector('img').style.padding = this.value + 'px';
      break;
    case 'blur':
      document.querySelector('img').style.filter = `blur(${this.value}px)`
      break  
    case 'base':
      document.querySelector('img').style.background = this.value;
      document.querySelector('h1').style.background = this.value;
      break
  }
}

若是使用變數的方式,我們可以做到以資料去渲染畫面,改變數值就改變了所有用到這個數值的元素,這樣的好處是可以避免忘記要渲染的元素,以及減少選取的重複性行為

function changeHandler(){
  const unit = this.dataset.sizing || '';
  document.documentElement.style.setProperty('--' + this.name, this.value + unit); // 將 CSS 變數重新賦值
}

const unit = this.dataset.sizing || ''; 裡,|| 的意義是 or 邏輯運算子,當前一項的內容存在就採用前一項,否則會再查看第二項是否存在,再採用第二項

利用這種方式我們可以避免要寫多層判斷,就得以直接加上 CSS 屬性需要加上的 px 或其他尺寸,避免重複性行為

document.documentElement.style.setProperty() 則是可以重新設定 CSS 中的變數值,詳見

最後程式碼

CSS

:root{
  --base: #ffc600;
  --spacing: 10px;
  --blur: 10px;
}

img{
  padding: var(--spacing);
  background: var(--base);
  filter: blur(var(--blur));
}

.h1{
  color: var(--base);
}

JS

const inputs = document.querySelectorAll('.controls input');

function changeHandler(){
  console.log(this.name, this.value);
  // switch(this.name){
  //   case 'spacing':
  //     document.querySelector('img').style.padding = this.value + 'px';
  //     break;
  //   case 'blur':
  //     document.querySelector('img').style.filter = `blur(${this.value}px)`
  //     break  
  //   case 'base':
  //     document.querySelector('img').style.background = this.value;
  //     break
  // }

  const unit = this.dataset.sizing || '';
  document.documentElement.style.setProperty('--' + this.name, this.value + unit); // 將 CSS 變數重新賦值
}

inputs.forEach(input => {
  input.addEventListener('change', changeHandler);
  input.addEventListener('mousemove', changeHandler);
})

完成結果圖

最後的成品

結語

以上是第三天的製作紀錄,如有錯誤或不足的地方還請多多指教 >.<

Woah! CSS Variables?! — #JavaScript30 3/30
[ Alex 宅幹嘛 ] 深入淺出 Javascript30 快速導覽:Day 3:Playing with CSS Variables and JS
MDN Web Docs


上一篇
JS30 -> 02 - JS and CSS Clock
下一篇
JS30 -> 04 - Array Cardio Day 1
系列文
剛接觸前端一個月的小白 - JavaScript30 挑戰筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言