第三天的目標是可以利用畫面的拉桿調整圖片 CSS 屬性的 padding、background、filte,以及 .h1 的 color
Github 檔案位置:03 - CSS Variables
網頁一開始的樣子如下
可以先去看看 最後的成品
將程式的要求拆分步驟後,我們需要做的事情如下
首先要利用前兩天學到的選取元素和監聽
const inputs = document.querySelectorAll('.controls input');
inputs.forEach(input => {
input.addEventListener('事件', changeHandler);
})
這次我們使用了新的事件 change 、 mousemove
首先我們來加上 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 值
接下來,我們要使用 :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);
}
最後我們要來撰寫 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 中的變數值,詳見
:root{
--base: #ffc600;
--spacing: 10px;
--blur: 10px;
}
img{
padding: var(--spacing);
background: var(--base);
filter: blur(var(--blur));
}
.h1{
color: var(--base);
}
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