前情提要

還在寫行內樣式醜醜的嗎?教你不用寫css檔案,使用javascript來動態修改樣式的招數!
這樣子處理的層次又更不一樣,
前端之路有你有我,馬上來看看這是怎麼完成的。

要修改CSS怎麼做呢?物件儲存

首先樣式寫成物件

const die={
display:"none"
}

為什麼要寫成物件呢?修改一種,可能看不出來,修改很多樣式就能感受到,
物件這個儲存方式是有它特別的美感與好處的。
下面我來舉例:

const wrapperStyle = {
  position: 'absolute',
  top: '50%',
  left: '50%',
  transform: 'translate(-50%,-50%)',
  width: '350px',
  backgroundColor: '#261d4a',
  borderRadius: '5px',
  transition: 'box-shadow .5s ease',
  overflow: 'hidden'
};

語法介紹 Object.assign

使用範例
Object.assign(element.style,Style)
element是你要修改的元素,Style是樣式寫的object

這是修改一個的情況,當像是上面很多屬性要改的話,我們物件與JS的好處就產生了!
直接使用迴圈來全部套入:

const wrapper = document.getElementsByClassName('wrapper');
for (let i = 0; i < wrapper.length; i++) {
  Object.assign(wrapper[i].style, wrapperStyle);
}

MDN官網說明

JS 原力覺醒 Day27 - JS 常用 API - Object.assign && Object.defineProperty

還有沒有別的寫法?

有。

document.getElementById("myElement").style.cssText = `
  display: block; 
  position: absolute;
`;

這樣寫也跟原生css寫起來差不多,比較舒服。
用這種比較分離畫面與程式的寫法,
體感上爽度更高。

就不會是找到元素後還要.style.display="none"
一直.屬性.進去點點點這樣。

說好的三種呢?

function setStyle( objId, propertyObject )
{
 var elem = document.getElementById(objId);
 for (var property in propertyObject)
    elem.style[property] = propertyObject[property];
}

setStyle('myElement', {'fontsize':'12px', 'left':'200px'});

這種寫成function的風格我也很愛,感覺很舒服,跟第一個的有點類似卻不太一樣。
這個是把迴圈弄再函式了,所以呼叫一次就會全部修改。
第一個則是把物件內的東西丟給迴圈,一次一次去做改動變化,
邏輯上一模一樣,手段跟風格差異而已唷。

stackoverflow

心得

使用這個小技巧很有趣,之後我們會應用到「JS油猴系列-遮蔽廣告腳本,自定義新增名單」文章裡面。
當要寫腳本,很需要JS動態修改CSS的時候,這種小技巧就佔了很大的角色呢٩(๑•̀ω•́๑)۶!
是不是沒有想到居然可以用JS修改呀!

加上我認為比較差的寫法,就不只三種了呢。
趕快選一種喜歡的,
練習成自己的寶藏知識吧!

按讚的人:

共有 13 則留言

謝謝站長鼓勵,我會持續精進自我並且分享~

按讚的人:

請教一下,用 js 改 css 的方式,之前有沒有做過弱點掃描的經驗呢?
之前專案做過弱掃都報我用 js 改樣式的方式

按讚的人:

很好的問題!感謝 jordan 提出!
這問題我也從沒想過,我想了一下,有點不懂為什麼用 js 改 css 算是資安漏洞?
我研究了一下,會不會跟 css 可以執行 javascript 有關?
https://codepen.io/3n3a/pen/RwGKwrX

按讚的人:

@jordan 你之前是用什麼軟體掃描?有錯誤訊息可以參考嗎?
大家一起研究一下,相關資安漏洞在哪邊!

按讚的人:

感謝站長,

我之前是用 OWASP 去掃的,我用 Nuxt ,然後用了像 gsap 、還有一些其他像 lottie ,再來也有用 js 去監測改變樣式,或是 vue 本身 props 傳值到元件的 style 改樣式。

導致說弱掃中風險建議我設定好 csp (unsafe-inline),但只要我設定 csp 不通過 unsafe-inline ,那些 js 改動有的直接消失,或是不作用。

關於 Nuxt vue 檔案的 <style> 部分 unsafe-inline 我有找到方式處理掉,但 js 的一直沒法,後來跟客戶說明後,就沒處理了。但也很好奇有沒有方式處理....

其實也有發現拿 apple 官網網址去弱掃,csp 的部分也沒通過,才在想是不是要做動態就無法。

按讚的人:

嗨 Jordan,先別管 Apple 了,我研究了一下,現在絕大多數前端技術,應該都會支援 CSP 的!

看一下這篇:https://stackoverflow.com/questions/58397934/are-we-forced-to-use-unsafe-inline-in-our-csp-when-using-vue-js

According to the Vue.js docs, the runtime build is fully CSP-compliant.

Nuxt is supporting a csp config to create hashes via webpack sent as header on dynamic SSR mode and meta elements otherwise (see https://github.com/nuxt/nuxt.js/pull/5354)

有試過這個方向嗎?

哇,我又研究了一下,Nuxt 的 CSP 好像只有 SSR 會支援,SPA 的話沒辦法支援

https://github.com/nuxt/nuxt/issues/6592

我又看了幾篇文章

https://csplite.com/csp215/

我目前感覺是:CSP 應該是支援度相當高,可以的話,也應該要設定的東西

Nuxt SSR 有支援,但 SPA 無解

至於類似框架的情況呢?

以 React 體系的 Next 來說

https://csplite.com/csp251/

SSR 跟 SPA 都有支援

相關討論有很多:https://github.com/vercel/next.js/issues/256


然後,這個可能可以看一下

https://github.com/victor-perez/nuxt-helmet

推推 我也想來研究這個問題 css可以執行js也太酷

按讚的人:

拍謝~之前專案太忙就忘記回覆~
其實上面像是 nuxt-helmet 套件我有安裝過, 我最後是自己設定 render:{csp 部分,也是站長上面貼的~
基本上都可以正確加上 csp 。
不過主要是 csp 弄太嚴格,反而我控制的樣式就出不來~
這專案完全結案了,我可以分享網站上來了
https://www.goodfinance.com/
上面有些動態只要下 unsafe-inline 就直接爆掉~最後就放棄,只有做一些基本的 csp 設定。

按讚的人:

原來如此,謝謝分享!