前陣子因為用了六年多的DigitalOcean主機顯示硬碟容量不足,因此開始清理裡面的垃圾。清理完畢後發現MySql竟然記憶體飆高到40%,重啟服務、更新版本能試的方法試過一輪還是一樣。最後才發現原來自己誤刪了swap(類似Window的虛擬記憶體)。以下是當時在檢查問題點時常用到的command,我把他整理起來,免得之後要用又忘掉。注意:有些在mac上可用,有些不行。且有些雖然可用,但options可能會有點出入。
閱讀全文 跟硬碟使用量以及記憶體使用狀態有關的linux command line指令分類: works
JS浮點運算問題
Javascript在小數點的運算上,常常會出現無限小數的情況,這是因為Javascript依照IEEE754浮點數運算標準,因此在做運算時,會先把十進制轉成二進制,然而小數點在轉換到二進制時,會出現無限小數,例如:
// 將十進制的 0.1 轉為二進制 Number(0.1).toString(2) // '0.0001100110011001100110011001100110011001100110011001101'
因此在做 0.1 + 0.2 這樣的運算時,才會產生 0.30000000000000004 這樣的結果。遇到這個情況時,我們可以用 toFixed() 來解決。 number.toFixed(n) 會回傳一個 n 位內小數點的「五捨六入」的「字串」,n可為0-20,預設值為0,例如:
0.12366.toFixed(4) // '0.1237' (0.1 + 0.3).toFixed(4) // '0.4000'
然後,因為輸出的是字串,我們可以再以 parseFloat() 轉回數字。例如:
parseFloat(0.12366.toFixed(4)) // 0.1237 parseFloat((0.1 + 0.3).toFixed(4)) // 0.4
用蘋果捷徑更新貓咪體重到Google試算表
以往在記錄家裡的貓咪體重時,都是打開Google試算表,切換到要記錄的貓咪的工作表,然後拉到整張表的最下面輸入當天日期跟體重。雖然步驟有點多,但因為不是經常性的在記錄,感覺上也沒那麼麻煩。不過自從家裡有腎貓,需要每天監控體重時,這個操作步驟實在有點繁雜。
今天要介紹一個我已經使用很久的方法——用蘋果的捷徑功能,搭配Google文件的Apps Script來記錄到Google試算表。
優點
好處是「不需安裝任何APP、完全免費、不怕個資外流」且蘋果捷徑在iPhone或MacOS上都可以執行,也很方便共享,不論手邊的裝置是什麼,都可以立刻執行。
Google文件的Apps Script就像是每一份Google文件的API。你可以自行編寫API的內容,就像寫JavaScript一樣,讓此API能根據你的程式碼來工作。
開工拉
首先先開一個新的Google試算表,因為我們要做的是可以支援多貓家庭的情況,所以我們先建立好每一隻貓名字的工作表

點選Menu上的擴充功能,選取Apps Script
閱讀全文 用蘋果捷徑更新貓咪體重到Google試算表datetime-local Input 秒數問題
當使用datetime-local的input時,直接帶入「包含秒數」的value,例如:2022-12-23 11:49:22,表單可以送出,且資料包含秒數。但當value是透過JavaScript帶入,送出時就會發現表單顯示「請輸入有效值」的錯誤提示:

Chrome與Firefox皆為如此,在Safari中連左側透過html帶入value的也會出現提示。
到底為什麼沒辦法輸入秒呢?查了一下才知道原來是跟控制增減值的step參數有關。datetime-local的step最小單位是秒,而預設值是60,也就是預設會以一分鐘作為最小可調整的時間的意思。
因此,要解決這個問題,我們只要新增step參數,並設為1就可以囉!
<input type="datetime-local" step="1">
防止iOS Dark mode破壞信件版型
自從iOS有了Dark mode之後,因為系統會自動複寫背景、文字顏色等等,造成要寄給客戶的信件,整個變得亂七八糟。越單純的版型越不會受影響,但假設有設字體顏色等等,就很容易變得不協調,或是深色字直接看不到。如果版型複雜一點,要針對Dark mode去做兩種顏色的適配真的非常麻煩。
能不能不讓Dark mode影響版型呢?
一開始只是試著去對每個背景色或是文字顏色加上!important,但似乎還是會被複寫。那如果背景是一張圖呢?Bingo! 幫背景加上一張底圖後,容器內的樣式就不會被強制複寫了!因此,只要在最外層加上背景圖就沒問題了。
於是最終的方式,只要在樣式表中加上:
body { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+ip1sAAAAASUVORK5CYII='); }
base64中encode的是一個1px寬高的白色背景圖。也可以依照需求用這個網站做出不同顏色的背景圖。調整好顏色後,把Base64 Encoded Pixel下的亂碼複製起來,換掉下面誇胡的部分即可。
body { background-image: url('data:image/png;base64,[換掉這裡]'); }
在nuxt裡起一個socket.io server與後續Apache的Proxy設定
最近隨著LiveTRA的MAU越來越高,怕Firebase RealtimeDatabase會產生一些額外的支出,開始萌生想把他拔掉的想法。RealtimeDatabase主要是負責傳遞顯示於時刻表最上方的警示訊息,平常不會顯示,但當台鐵發生什麼突發事件時,可以做到立即告知使用者的效果。總覺得拔掉有點可惜,又不想單純只用傳統API去撈,這樣就失去即時性。所以索性最後自己用socket.io刻一個socket server。
Nuxt Module
我的構想是,把socket server寫在跟前台同一個nuxt專案中,且當nuxt啟動(npm start)時,最好socket也能一起被啟動,這樣我就不用再另外去起socket server。
閱讀全文 在nuxt裡起一個socket.io server與後續Apache的Proxy設定Javascript 常用數字與日期顯示格式
這篇主要是筆記一下幾個常用,卻又容易忘記的處理數字與日期格式的方式。
數字千位分隔符
以往(查了一下caniuse應該是2017, 2018,瀏覽器還不支援Intl以前)要在數字上加上分隔用的逗點(如:19,890,604)只能自己手工處理。例如下面這樣的方式:
閱讀全文 Javascript 常用數字與日期顯示格式CSS Container Query 搭配Grid打造原始碼好維護的靈活排版
以往我們要依據寬度為容器做改變時,我們通常只能用css media query。但media query中帶入的min-width或max-width寬度條件只限用於整個視窗,因此media query常常不能直覺地在Layout需求上實作。
比如說,有一個component,會被應用在主要內容區以及比較窄的sidebar時,我們通常也只能給他一個modifier class name來讓他在sidebar中不會破版。
閱讀全文 CSS Container Query 搭配Grid打造原始碼好維護的靈活排版WordPress REST API v2抓取特定標籤或類別文章
最近有個需求是要爬公司部落格的文章到官網顯示。搜尋一下,知道WordPress有Rest API,非常簡單就可以達成需求。
閱讀全文 WordPress REST API v2抓取特定標籤或類別文章把音樂中的人聲跟樂器都分離出來的超強軟體Spleeter
在查有沒有command line可以分離歌聲跟伴奏的工具時,發現了這個強大的程式。雖然跟一般專業處理聲音的軟體比起來,處理出來的結果沒有太大差別,失真也沒有比較少,不過他強大的地方在於除了人聲以外,他還可以分離出鋼琴、鼓聲、Bass等等樂器。對於想玩重新編曲的或DJ的人來說,應該是一個蠻實用的工具。
閱讀全文 把音樂中的人聲跟樂器都分離出來的超強軟體SpleeterPhotoshop, After Effects 匯出webp動態圖
工作的關係,稍微研究了一下關於產動態webp的方式。本來想說Photoshop已經支援webp了,應該也有匯出webp動畫的功能吧。但事與願違。看了一下以前要做gif動畫都會用的「儲存為網頁用」功能,沒有存為webp的檔案類型選項。再看一下「演算視訊」裡面也沒有webp的格式選項。
閱讀全文 Photoshop, After Effects 匯出webp動態圖CSS 超好懂的@Layer教學
乍看layer這個字,還以為是像Photoshop的圖層概念之類的東西,亦或是針對z-index之類的selector。結果竟是用來解決selector權重用的(對於CSS權重不是很了解的話,可以快速看一下這篇筆記。)依照layer宣告的順序,來決定樣式優先順序,後宣告的即使權重較小,也會覆寫。
閱讀全文 CSS 超好懂的@Layer教學sublime 快速鍵筆記
command+d 選取編輯多個相同選取項目
使用情境:當有多個欲選取的相同字串時可使用。
使用方式:先選取一個或一段要選取的字串,然後按下command+d多次,直到所有相同字串都被選取即可。
閱讀全文 sublime 快速鍵筆記Chrome載入CSS問題
印象中看過「css的link標籤不論放在哪(head or body)都會先載入」的這個說法,不過今天卻發現當Chrome在某些情況時,結果似乎會有點非預期。
首先我在head與body最後都各放一個link標籤,並且在onload時跳出alert
在這個case,第一次alert時瀏覽器還是空白畫面,而第二次alert時,畫面上的row, col已被正確render了。看起來link不論放在哪都會先載的這個說法是成立的。
但奇怪的事情來了。當我把head裡的link拿掉時,chrome會呈現一個不穩定的結果。
閱讀全文 Chrome載入CSS問題Vue2基本型別陣列的更新問題
當我們在Vue2中使用陣列時,若陣列中的內容是基本型別,也就是非物件的情況下,如果只更新陣列中的某一筆資料,會發現Vue並不知道資料已更新,導致畫面不會重繪。
在Vue2中的data區塊內所宣告的屬性,都被轉換成getter setter,因此當你重新賦值時,Vue就可以知道你更新了資料,然後就執行重繪畫面的工作。在data內所宣告的物件,如果一開始就有先宣告其屬性,屬性們也會被轉換成getter setter,但後來才加進去的屬性就無法被轉換,除非整個物件重新賦值,才有辦法轉換新的屬性。
宣告過的物件屬性可以觸發更新:
data () { return { myObj: { a: 0 } } } mounted () { this.myObj.a = 10 }
沒宣告過的不會觸發更新:
this.myObj.b = 10
這樣才能讓b也被轉換,並且觸發更新:
this.myObj = { a: 10, b: 10 }
但陣列中的基本型別因為不是物件,所以即是宣告時已存在,但還是無法轉換為響應式(設getter, setter),所以以下面這種方式改變時不會更新:
this.myArray[0] = 1
下面這幾種情況才會觸發更新:
this.myArray = […this.myArray] this.myArray = Object.assign([], this.myArray) this.myArray = this.myArray.splice(0, this.myArray.length)
就是immutable的概念吧
但當我們使用push, pop, shift… 這些array的method來操作這個基本型別的陣列時,會發現畫面竟然就乖乖更新了。這是因為vue把data中宣告過的陣列的method都覆寫了。這些是被覆寫過的methods:push, pop, shift, unshift, splice, sort, reverse。
當你執行這些methods的時候,其實並非直接執行native code,而是會執行vue覆寫的function。這隻function做的事情就是先跑完原始native code要做的事情,再發出通知讓vue重繪畫面。有興趣的可以看一下vue.runtime.esm.js,搜尋methodsToPatch。
也就是說,如果有個被覆寫的native function,可以在執行之後不會對目前陣列產生什麼影響的話,我們就可以利用他來當作陣列更新後對vue通知重繪畫面的媒介。這裡面有 push 跟 splice 這兩個methods,如果不帶任何參數的情況下,可以不影響陣列內容。因此我們可以這樣修改並觸發更新:
this.myArray[0] = 10 this.myArray.push() // or this.myArray.splice()
Vue3的話因為改用Proxy來監聽改變,所以不需要這樣告知更新。但老實說,我到現在還是不太喜歡Vue3的Reactivity API。尤其是基本型別的ref()的設計。Vue2還是直覺得多,寫起來也比較漂亮。我應該暫時還會是Vue2的愛用者XD