Dec. 2022
2 nd
CSS Flex
flex-grow
依照設定比例分配剩餘空間,默認為
0
,即表示如果存在剩餘空間,也不會佔用剩餘空間。flex-grow
的值只接受一個整數。
WARNING
flex-grow
會影響寬度和高度,具體取決於 flex-direction
屬性。
在不使用 flex-grow
的情況下,flex
項目的寬度將默認為其初始寬度,但是使用 flex-grow: 1;
時,flex
項目會平均掉剩餘的可用空間。
flex-shrink
表示空間不夠時的壓縮比例。 預設值爲 1,表示大家被壓縮的比例相同。
flex-basis
預設值爲
auto
,表示其預設分配到的空間,與width
很像,但優先程度較高。- 當
flex-direction: row;
時,flex-basis
會決定width
。 - 當
flex-direction: column;
時,flex-basis
會決定了height
。
- 當
WARNING
flexbox
裡面的 item
預設會是 min-width: auto;/min-height: auto;
,並且會是 overflow: visible;
。
align-self
可以個別調整子元素在交錯軸線的位置,屬性與
align-item
相同。
假如已經在父元素上設定align-item
,但要其中一個內容物的位置需要調整成其他對齊方式,這時我們就可以針對該元素設定align-self
來覆寫原本align-item
的屬性。order
可透過 CSS 來修改 HTML 的 DOM 的順序。
flex 簡寫
flex: 1;
{
flex-grow: 1;
flex-shrink: 1;
flex-basic: 0;
}
flex: 1 1;
{
flex-grow: 1;
flex-shrink: 1;
flex-basic: 0;
}
flex: 100px;
{
flex-grow: 1;
flex-shrink: 1;
flex-basic: 100px;
}
3 rd
JS
- Scope 作用域
作用域是指程式碼中定義變數的區域,確定當前執行程式碼對於變數的訪問權限。
JavaScript 採用詞法作用域(lexical scoping),也就是靜態作用域。函式的作用域
詞法作用域:在函式定義的時候決定。
動態作用域:在函式調用的時候決定。- 所有未定義直接賦值的變數,將自動宣告為擁有全局作用域
jsfunction func() { variable = 'Hello' const variable2 = 'World' } func() // 還是需要先執行內部以宣告變數 console.log(variable) // Hello console.log(variable2) // not defined
- 所有
window
對象的屬性擁有全局作用域 若變數定義沒有用函式包起來,那它們全部都將在全局作用域中,這樣容易污染全局命名空間,引起命名衝突。 - 函式作用域 指聲明在函式內部的變數。
5 nd
JS
垃圾回收
程式碼運作過程中會產生很多垃圾,這些垃圾是不用的記憶體空間或者是曾經用過但以後不會再用的記憶體空間,而 GC (Garbage Collection) 就是負責回收垃圾的。
垃圾如何產生?為什麼需要回收?
創建一個基本類型、物件、函式等都是需要佔用記憶體的,因為通常引擎會幫我們分配好,所以我們不需要手動的去做分配。
假設宣告一個變數test
,引用了物件{ name: 'isobj' }
,接著我們把這個變數重新賦值了一個陣列,那之前的物件引用關係就消失了。
沒有了引用關係,就是無用的物件,所以就需要被清理(回收)。總而言之,程式碼的運行需要記憶體,當程式碼提出要求,操作系統或運行時就必須提供記憶體空間。
為了持續運行下去,必須適時地釋放記憶體空間,否則記憶體佔用過高可能影響系統性能甚至導致崩潰。垃圾回收策略
記憶體管理中有一個概念叫做「可達性」,指的是那些以某種方式可訪問或是說可用的值,它們被保證儲存在記憶體中。
而不可訪問的值則需要回收,找出這些不可達的物件(垃圾)並清理它。
原理主要就是「定期」找出那些不會再用到的變數(記憶體),然後釋放其記憶體。標記清除(Mark-Sweep)算法 目前在 JavaScript 引擎中最常使用,不過各大瀏覽器廠商對此算法仍進行了加工,使得不同瀏覽器在運行垃圾回收的頻率上會有所差異。
引擎在執行 GC 時,需要從出發點去遍歷記憶體中所有的物件去做標記。
出發點通常我們稱為root
物件,在瀏覽器環境中包括:全局 Window 物件、檔案 DOM Tree 等。- 優點
- 較簡單達成,標記僅為「有」與「沒有」。
- 缺點
- 記憶體碎片化 在清除後,剩餘的物件記憶體位置不變,將導致空閒的記憶體空間是不連續的。
由於剩餘空閒記憶體不是一整塊,是由不同大小的記憶體組成的記憶體列表,牽扯到了記憶體分配的問題。 - 分配速度慢 即便使用
First-fit
方式分配,仍是一個O(n)
的操作,最壞情況是每次都要遍歷到最後,同時因為碎片化,大物件的分配效率會更慢。
- 記憶體碎片化 在清除後,剩餘的物件記憶體位置不變,將導致空閒的記憶體空間是不連續的。
分配記憶體
假設新建的物件分配記憶體時需要的大小為
size
,由於剩餘記憶體是間斷、不連續的,則需要對剩餘記憶體列表進行一次單向遍歷找出大於等於size
的區塊才能進行分配。First-fit
:找到大或等於size
的區塊立即回傳。Best-fit
:遍歷整個剩餘記憶體列表,回傳大或等於size
的最小區塊。Worst-fit
:遍歷整個剩餘記憶體列表,找到最大的區塊後切成兩部分,一部分為size
大小並回傳該部份。
上述三種策略中
Worst-fit
的空間利用率看似合理,但實際上切分後反而會造成更多的小塊,更容易形成記憶體碎片,所以不推薦使用。 考慮到分配的速度和效率First-fit
是更為明智的選擇。標記整理(Mark-Compact)算法
標記階段與標記清除算法大致相同,差別在於標記結束後會將活著的對象(即不需要清理的對象)向記憶體的一端移動,最後清理掉邊界的記憶體。
可以有效地解決記憶體碎片化等問題。引用計數(Reference Counting)算法 早期的一種垃圾回收算法,將物件是否不再需要簡化定義為物件有沒有被其他物件引用。
如果沒有引用指向該物件(零引用),則此物件將被垃圾回收機制回收,目前很少使用這種算法了。- 優點
- 引用計數在引用值為 0 時(變成垃圾的那一刻)就會被回收,可以立即回收垃圾。
- 缺點
- 需要計數器 計數器需要佔很大的位置,因為不知道被引用數量的上限。
- 無法解決循環引用(互相引用)無法回收的問題
互相引用
jsfunction test(){ let A = new Object() let B = new Object() A.b = B B.a = A }
物件 A 和 B 透過各自屬性互相引用,依照引用計數策略,它們的引用數量都是 2。
在函式test
執行完成後,照理來說物件 A 和 B 應該是要被清理的。
但是使用引用計數則不會被清理!因為它們的引用數量不會變成 0。
假如此函式在程序中被多次調用,那麼就會造成大量的記憶體不會被釋放。- 優點
6 nd
JS
V8 對於 GC 的最佳化
V8 是一個由 Google 開發的開源 JavaScript 引擎。
分代式垃圾回收 V8 中將 Heap(動態記憶體配置)分為新生代和老生代兩個區域,並採用不同的垃圾回收機制。
1. 新生代垃圾回收 透過
Scavenge
算法進行垃圾回收,主要採用了一種複製式的方法:Cheney 算法。
將 Heap 一分為二,一個是處於使用狀態的空間使用區,一個是處於閒置狀態的空間空閒區。 新加入的物件都會存放到使用區,當使用區快被寫滿時就需要執行一次垃圾清理操作。
當開始進行垃圾回收時,回收器會對使用區中的活動物件做標記,標記完成之後將使用區的活動物件複製進空閒區並進行排序,隨後進入垃圾清理階段(將非活動物件所佔用的空間清理掉)。 最後將原來的使用區和空閒區做角色對調。晉升至老生代的條件
- 當一個物件經過多次的複製後依然存活,它將會被認為是生命週期較長的物件,將會被移動到老生代中並採用老生代的垃圾回收機制進行管理。
- 如果複製一個物件到空閒區時,空間佔用超過了 25%,此物件會直接晉升到老生代空間中(設置為 25% 的原因是:當完成
Scavenge
回收後,空閒區將翻轉成使用區繼續進行物件記憶體的分配,若佔比過大將會影響後續記憶體空間的分配)。
2. 老生代垃圾回收 物件通常比較大,採用的方式為標記清除算法。 首先是標記階段,從一組根元素開始遞迴遍歷這組根元素,遍歷過程中能到達的元素稱為活動物件,沒有到達的元素就可以判斷為非活動物件。
清除階段會直接將非活動物件清理掉,並且 V8 中採用標記整理算法來解決記憶體碎片化的問題。
7 th
CSS 命名推薦
Status
意義 | 命名 | 意義 | 命名 |
---|---|---|---|
前一個 | prev | 後一個 | next |
當前的 | current | ||
顯示的 | show | 隱藏的 | hide |
開啟的 | open | 關閉的 | close |
選中的 | selected | 有效的 | active |
預設的 | default | 反轉的 | toggle |
禁用的 | disabled | 危險的 | danger |
主要的 | primary | 成功的 | success |
提醒的 | info | 警告的 | warning |
出錯的 | error |
Layout
意義 | 命名 | 意義 | 命名 |
---|---|---|---|
文件 | doc | 頭部 | header (hd) |
主體 | body | 尾部 | footer (ft) |
主欄 | main | 側欄 | side |
容器 | box / container |
通用元件
意義 | 命名 | 意義 | 命名 |
---|---|---|---|
列表 | list | 列表項 | item |
表格 | table | 表單 | form |
連結 | link | 標題 | caption / heading / title |
選單 | menu | 集合 | group |
條 | bar | 內容 | content |
結果 | result |
一般元件
意義 | 命名 | 意義 | 命名 |
---|---|---|---|
按鈕 | button (btn) | 圖示 | icon |
下拉選單 | dropdown | 工具欄 | toolbar |
分頁 | page | 縮圖 | thumbnail |
警告框 | alert | 進度條 | progress |
導覽列 | navbar | 導覽 | nav |
子導覽 | subnav | 麵包屑 | breadcrumb (crumb) |
標籤 | label | 徽章 | badge |
巨幕 | jumbotron | 面板 | panel |
窪地 | well | 工具提示框 | tooltip |
彈出提示框 | popover | 輪播 | carousel |
折疊 | collapse | 手風琴 | accordion |
定位浮標 | affix |
輔助元件
意義 | 命名 | 意義 | 命名 |
---|---|---|---|
品牌 | brand | 標誌 | logo |
額外部件 | addon | 版權 | copyright |
註冊 | regist (reg) | 登入 | login |
搜尋 | search | 熱點 | hot |
幫助 | help | 資訊 | info |
提示 | tips | 開關 | toggle |
新聞 | news | 廣告 | advertise (ad) |
排行 | top | 下載 | download |
8 th
HTML 頁面生命週期
重要事件
DOMContentLoaded
瀏覽器已完全載入 HTML,並構建了 DOM 樹,但<img>
和樣式之類的外部資源可能尚未載入完成。
(DOM 已經就緒,因此處理程式可以查詢 DOM 節點,並初始化介面。)load
瀏覽器不僅載入完成了 HTML,還載入完成了所有外部資源:圖片,樣式等。
(外部資源已載入完成,樣式已被應用,圖片大小也已知了。)beforeunload
當使用者正在離開頁面時。
(使用者正在離開:我們可以檢查使用者是否儲存了更改,並詢問他是否真的要離開。)unload
當使用者正在離開頁面時。
(使用者幾乎已經離開了,但是我們仍然可以啟動一些操作,例如傳送統計資料。)
window.onload
當整個頁面,包括樣式、圖片和其他資源被載入完成時,會觸發
window
物件上的load
事件。
可以透過onload
屬性獲取此事件。window.onunload
當訪問者離開頁面時,
window
物件上的unload
事件就會被觸發。
我們可以在那裡做一些不涉及延遲的操作,例如關閉相關的彈出視窗。window.onbeforeunload
如果訪問者觸發了離開頁面的導航(navigation)或試圖關閉視窗,
beforeunload
處理程式將要求進行更多確認。
如果我們要取消事件,瀏覽器會詢問使用者是否確定。jswindow.onbeforeunload = function() { return Boolean };
如果
Boolean
是true
,則會彈出視窗詢問是否確定離開網站,false
則不會。document.readyState
loading
:文件正在被載入。interactive
:文件被全部讀取;與DOMContentLoaded
幾乎同時發生,但是在DOMContentLoaded
之前發生。complete
:檔案被全部讀取,並且所有資源(例如圖片等)都已載入完成;與window.onload
幾乎同時發生,但是在window.onload
之前發生。
readystatechange
事件會在狀態發生改變時觸發,因此我們可以
console
這些狀態。js// 目前狀態 console.log(document.readyState) // 狀態如果發生改變,則執行 callback document.addEventListener( 'readystatechange', () => console.log(document.readyState) )
10 th
CSS 三角形
- 正三角形
將長寬都設為
0
。css{ width: 0; height: 0; border-bottom: 3rem solid #de896f; border-left: 3rem solid transparent; border-right: 3rem solid transparent; }
- 不透明三角形
如果將左右兩邊的邊也加上顏色。
(若沒有左右的邊,底邊也不會出現)css{ width: 0; height: 0; border-bottom: 3rem solid #de896f; border-left: 3rem solid #6ab2de; border-right: 3rem solid #82c28d; }
- 如果只有設置底邊
會什麼都沒有(除非原容器長寬不是
0
)css{ width: 1rem; height: 1rem; border-bottom: 3rem solid #de896f; }
11 th
CSS
Sass(Syntactically Awesome Stylesheets)
是一種動態樣式語言,Sass 語法屬於縮排語法,比 CSS 比多出好些功能,如變數、巢狀、運算、混入(Mixin)、繼承、顏色處理,函式等,更容易閱讀。
Sass 的縮排語法,對於寫慣 css 前端的 web 開發者來說很不直觀,也不能將 CSS 程式碼加入到 Sass 裡面,因此 Sass 語法進行了改良,成為了 Scss。Scss(Sassy CSS)
是 CSS 語法的擴充套件。
這意味著每一個有效的 CSS 也是一個有效的 Scss 語句,與原來的語法相容,只是用{}
取代了 Sass 的縮排。Less(Leaner Style Sheets)
一種動態樣式語言。
對 CSS 賦予了動態語言的特性,如變數、繼承、運算、函式。
既可以在客戶端上執行(支援IE 6+, Webkit, Firefox),也可在伺服器端執行(Node.js)。
主要差異 | Sass | Less |
---|---|---|
編譯環境 | 伺服器端處理(Ruby、Dart-Sass 或 Node-Sass) | 引入 less.js 來處理 Less 程式碼輸出 CSS 到瀏覽器,或在開發伺服器將 Less 語法編譯成 CSS 文件 |
變數符號 | $ | @ |
輸出設定 | 無 | nested 、compact 、compressed 、expanded |
條件語句 | if-else 或 for 迴圈 | 不支援 |
12 th
JS
- 雙問號語法
若
??
左方為undefined
或null
,則回傳??
右方的值jsconst exp = left ?? right
CSS
border-image(source, slice)
預設:
source: none; slice: 100%;
border 原圖(width: 81px
)
原圖 81px 設定 slice: 27px
表示設定 1、2、3、4 為原圖的四個角落(寬度皆為 27px
,剛好為一個紅色菱形的寬高)。
剩餘的 5、6、7、8 則由原圖被切剩的部分去做填補(剩餘剛好為中間橘色菱形的寬高)。
結果顯示
border-image: url('https://developer.mozilla.org/en-US/docs/Web/CSS/border-image/border.png') 27;
14 th
CSS
scroll-snap-type
- mandatory
- proximity
15 th
資源
技術
- SSG(Static Side Generation)
所有的內容都在
bulid
的時候都打包進入檔案中,所以使用者在瀏覽網站時,就可以拿到完整的HTML
檔案。
優點除了可以有利於 SEO 之外,還有因為每次使用者拿到的HTML
內容都不會變,所以還可以讓HTML
被cache
在CDN
上,很適合用在資料變動較小的網站中,像是部落格、產品介紹頁這種應用中。
但使用 SSG 這項技術時,除了必須考量到頁面資料更新頻率的問題,再者要衡量隨著應用越來越大時,打包的時間也會隨之增長。 ⋯ Reference
17 th
CSS
- 梯形
跟三角形的方式很相似,但這次增加了矩形主體的面積。
css{ border-color: transparent transparent #de896f transparent; border-style: solid solid solid solid; border-width: 2rem; height: 6rem; width: 6rem; margin: auto; }
19 th
JS
- Fetch
fetch
回傳的response
可以透過blob()
,json()
,text()
轉成可用的資訊。
記得fetch
是異步的動作,會需要配合.then()
或是async / await
。js⋯ Reference// fetch 會使用 ES6 的 Promise 作回應 fetch(url, { // 定義 method: GET | POST | PATCH | PUT | DELETE method: '...', // headers 加入 json 格式 headers: { 'Content-Type': 'application/json' }, // body 將 json 轉字串送出 body: JSON.stringify({ ... }) })
22 nd
Timestamp 時間戳
從 UTC+0 時區的 1970 年 1 月 1 號 0 時 0 分 0 秒開始,總共過了多少毫秒。
Type:number
jsnew Date().getTime() Date.now() // 1673598541032
缺點:無法直接看出時間,一定要經過轉換。
ISO 8601
用字符串表現一個帶有時區的時間。
Type:string
jsnew Date().toISOString() // 2020-12-26T12:38:00Z
最後面如果是
Z
就代表UTC +0
時區。
如果要其他時區可以這樣寫:2020-12-26T12:38:00+08:00
。
代表 +8 時區的 12 月 26 號 12 點 38 分 0 秒。JavaScript 中的時間處理
函式 結果 getYear
當前年份 - 1900 getFullYear
當前年份 getMonth
月份數字會從 0 開始 getHours
會先把時間轉成 Local Time
23 rd
套件
- vue-js-modal
使用方便、高度可自訂的 Vue.js modal 庫,支援靜態和動態兩種類型的 modal。
- vue-notification
主要幫助建構漂亮的通知(向使用者顯示訊息)。
提供了許多功能,如動畫、自訂位置、樣式等等。 - vue-wait
在沒有任何衝突的情況下控制頁面上的各種載入狀態。
核心原理是管理一個具有多個載入狀態的陣列,整合載入器元件開始監聽其註冊的載入器並立即進入載入狀態。 - vue-good-table
易於使用的強大的 Vue.js 數據表,具有進階客製化功能,包括:排序、列過濾、分頁、分組等。
25 nd
CSS Postprocessor 後處理器
- Autoprefixer
透過 Can I Use 解析 CSS 並將供應商前綴添加到規則中。
對於一些過時的 CSS 供應商前綴,Autoprefixer 也會自動清除。
尚未被廣泛使用的 CSS 屬性會需要加上前綴,才能被瀏覽器所解析,此工具可以幫忙添加前綴,不需要自己花費時間查詢。
28 nd
前端框架
語法接近 React 的前端 SSR 框架。
- 大幅優化甚至取消了 hydration 的過程
- 不只是延遲載入元件, 還可以延遲載入點擊事件等程式碼
- 幾乎可以做到僅載入當前用到的 JS 程式碼與 CSS 程式碼
- DOM 元素沒有出現在螢幕的可視範圍, 則不執行元件內部函式
目標是延遲載入所有的程式碼, 比如一個按鈕你沒有點選它之前, 那麼 Qwik 就不會去載入點選相關邏輯, 甚至他都不會去載入 React 相關的程式碼, 畢竟有的時候使用者進入頁面後也確實沒有進行任何操作, 那麼沒必要去載入所有資源。
⋯ ReferenceHydration
是一種向伺服器呈現的 HTML 新增互動性的技術。
客戶端 JavaScript 透過將事件處理程式附加到 HTML 元素,將靜態 HTML 網頁轉換為動態網頁。傳統框架如 React 和 Vue 在瀏覽器中需要做大量的工作,而 Svelte 將這些工作放到構建應用程式的編譯階段來處理,與使用虛擬(virtual)DOM 差異對比不同。
- 沒有 Virtual DOM 機制(runtime 和 bundle size 較小)
- 將程式碼先做編譯後再執行