iT邦幫忙

1

JS30 Day 3 - Playing with CSS Variables and JS 學習筆記

今天要利用CSS變數來控制圖像的設置

以下為原始檔

https://github.com/87JoJo/Playing-with-CSS-Variables-and-JS-

成果如下圖

https://ithelp.ithome.com.tw/upload/images/20200505/20126182PjHmOO8PBt.jpg

以前我們都是直接在JS控制屬性,而這次我們利用資料(歸納在css中),
也就是在CSS設置變數的方法來改變畫面,缺點會比較難找變數名稱。

type="range",type="color"

分別為滑動桿,與色彩選取器

<label for="spacing">Spacing:</label>
<!-- type="range" 滑動桿 -->
<input id="spacing" type="range" name="spacing" min="10" max="200" value="10" data-      sizing="px" />

<label for="base">Base Color</label>
<!-- type="color" 顏色選取器  -->
<input id="base" type="color" name="base"

而在css部分

:root

偽類選取器,設置樣式為變數,前面需要加上--,我們將變數設置在html裡
,然後img及hl在利用var獲取其設置好的屬性值,當我們:root內的屬性值改變
,img及hl的畫面也會跟著改變。

/* :root等同於html */
:root {
  --base: #ffc600;
  --spacing: 10px;
  --blur: 10px;
}

img {
  /* 讀取位於html層設置的變數屬性 */
  padding: var(--spacing);
  background: var(--base);
  filter: blur(var(--blur));
}

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

js部分

先利用querySelectorAll獲取所有Input

  // querySelectorAll獲取為半殘的array(like-array),有foreach、length、key,但無map
  const inputs = document.querySelectorAll('.controls input');
  // console.log(inputs); NodeList(3)
  

在遍歷每個Input做監聽事件的處理,利用change事件來做監聽,當input有所變動就會觸發,但change為修改完,最後才會觸發,為了連續觸發屬性值(10px,11px,12px...),所以要額外加上mousemove的事件,來做即時的監聽。

  // 每次拿一個input,並賦予事件
  inputs.forEach(input => {
    // 當改變的時候觸發changeHandler
    // change事件為最後觸發
    input.addEventListener('change', changeHandler);
    //  如果要連續觸發須加上mousemove
    input.addEventListener('mousemove', changeHandler);
  });

再來就處理觸發事件後的函數changeHandler,我們所要的是觸發事件後,更改對應的樣式。

switch寫法

這種寫法,繁雜麻煩,當要一次改變多個樣式,還需再加上一行代碼

  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;
        // 改變標題的字母(js)
        document.querySelector('.hl').style.color = this.value;
        break;
    }
    

資料放在root,要獲取的話,這三種寫法都相同
document.querySelector('html')=document.querySelector(':root')=document.documentElement

[]

[屬性名稱]較傳統方法,來設置屬性,但由於變數名有--,故無法使用中括號
而後的三目運算符,為如果屬性名為base就加上'',如果不為(blur,spacing)就加上px

document.documentElement.style['--' + this.name]= this.value + (this.name === 'base' ? '' : 'px');

setProperty

獲取放在html層的資料變數,並利用setProperty修改其屬性值

    document.querySelector('html').style.setProperty('--' + this.name,this.value + (this.name === 'base' ? '' : 'px'));
    

dataset

<input id="blur" type="range" name="blur" min="0" max="25" value="10" data-sizing="px" />
<input id="spacing" type="range" name="spacing" min="10" max="200" value="10" data-sizing="px" />
<input id="base" type="color" name="base" value="#ffc600" />

以dataset判斷代替三目運算符,dataset指的也就是讀取所有你在DOM上data開頭的屬性,如果有sizing的屬性就用它,如果沒有就給予空,而在我們的DOM元素,有sizing的只有blur,spacing。

  // 設置一個變數,如果data為sizing的屬性就使用他的屬性值,否則為空
  const unit = this.dataset.sizing || '';
  document.querySelector('html').style.setProperty('--' + this.name, this.value + unit);
   
  // document.querySelector('html').style.setProperty('--' + this.name,this.value +         (this.dataset.sizing || ''));
  
  console.log(this.dataset); // DOMStringMap {sizing: "px"}
  console.log(this.dataset.sizing); // 當控制spacing,blur出現px而改變顏色會出現undefined```

尚未有邦友留言

立即登入留言