竹白記事本,Javascript 30,紀錄。
Javascript 30
使用 JavaScript 搭配原生 CSS 變數,製作出一個即時濾鏡效果工具。
可調整模糊、邊框色、內距大小。
data-sizing
用來判斷單位filter:blur()
必須先宣告全域的 CSS 變數,並套用到對應的頁面元素中(圖片、標題)。
style
所繼承的 CSSStyleDeclaration
介面,不支援 CSS Variables 的樣式屬性,所以必須使用 setProperty()
來設定樣式屬性。
:root {
--base: #ffc600;
--spacing: 10px;
--blur: 10px;
}
img {
padding: var(--spacing);
background: var(--base);
filter: blur(var(--blur));
}
.hl {
color: var(--base);
}
:root
等同 html
選取器。
將資料變數放在 CSS 的優缺點:
input
標籤 註冊監聽事const input = const inputs = document.querySelectorAll('.controls input');
注意,querySelectorAll
出來的是 NodeList
類陣列,不是陣列,陣列部分的功能它沒有。在 Day 1 中有提到過。
inputs.forEach(function(key) {
key.addEventListener('change', changeHandler);
});
為每個 input
標籤註冊監聽事件,當 change
事件發生,執行 changeHandler
函式。
由於 change
事件並不即時,滑鼠放開才會執行,所以還需要再加入 mousemove
事件,使拉動滑桿時,也能更新效果。
inputs.forEach(function(key) {
key.addEventListener('change', changeHandler);
key.addEventListener('mousemove', changeHandler);
});
changeHandler
函式不使用 CSS 變數的作法:
function changeHandler() {
const img = document.querySelector('img');
const hl = document.querySelector('.hl');
switch (this.name) {
case 'spacing':
img.style.padding = this.value + 'px';
break;
case 'blur':
img.style.filter = `blur(${this.value}px)`;
break;
case 'base':
img.style.backgroundColor = this.value;
hl.style.color = this.value;
break;
}
}
這樣的缺點是,當有兩處以上需要變動,就要手動增加。
依照題目使用 CSS 變數作法:
document.querySelector('html')
document.querySelector('root')
document.documentElement
這三個是一樣的,依個人喜好選擇。
function changeHandler() {
const unit = this.dataset.sizing || '';
document.documentElement.style.setProperty(
`--${this.name}`, this.value + unit
);
}
原始碼 HTML 有提供 data-sizing
屬性,是用來判斷要不要加上單位,因此這邊用 dataset
取得。
由於 --變數
是較新的 CSS 屬性 style
不論是 .
或 []
都不支援,因此這裡用 setProperty
來加上 CSS 屬性。
這邊的 this
指向觸發 changeHandler()
的元素,因此可以獲取該元素的 data-sizing
、name
、value
值。
(function() {
const inputs = document.querySelectorAll('.controls input');
function changeHandler() {
const unit = this.dataset.sizing || '';
document.documentElement.style.setProperty(
`--${this.name}`, this.value + unit
);
}
inputs.forEach(function(key) {
key.addEventListener('change', changeHandler);
key.addEventListener('mousemove', changeHandler);
});
})();
與 Day1 相同,改用事件委派可以減少監聽器。
const inputs = document.querySelector('.controls');
function changeHandler(e) {
if (e.target.nodeName !== 'INPUT') {
return;
}
const unit = e.target.dataset.sizing || '';
document.documentElement.style.setProperty(
`--${e.target.name}`,
e.target.value + unit
);
}
inputs.addEventListener('change', changeHandler);
inputs.addEventListener('mousemove', changeHandler);