跳到主要內容

發表文章

目前顯示的是有「工具庫」標籤的文章

Java 實現民國年日期轉換

不知道大家現在還有沒有接到民國年轉換的需求 滿久以前偶爾會接到客戶寫信來問能不能做民國年的日期輸出或輸入 不過畢竟以前在處理上比較麻煩 最簡單的方式是請客戶分開資料欄位 分別產出民國跟西元年的資料,輸出時再依照需求組合出最終的字串 寫成常見Q&A之後就不大有需求信寄過來了

JavaScript Events Calendar component

最近工作上寫的,目的是想弄個功能接近Google Calendar的東西 原本想拿個開源的專案回來改,不過查了比較流行的幾個專案都是用jQuery、react來寫的 而且坦白說都還滿大包的,好幾個複合需求湊起來就是這樣的大小 反而沒有看到單純用JavaScript刻的 Events Calendar 這下只好自己動手做了 gist link See the Pen VmRZJo by veni ( @veni_vi ) on CodePen . 不是什麼了不起的code,不過寫起來也花了一些時間 雖然說大部分的時間可能在觀察Google Calendar的行為(笑 使用上應該還算好拿來改的 CalendarEvent 依照自己的需求決定要多帶哪些數據 至少要有個顯示的內容跟一個日期 EventCalendar.requireEventData([{ "content": "test2", "date_init": "2016/12/16 11:30:00", "info": "test 2"                 // 這是示範用來作客製化行為的額外資料 } ]); EventCalendar.setEventRenderFunction、EventCalendar.setEventMoreFunction可自訂事件處理 如果想做其它天期的顯示模式則可以參考 CalendarView 的繼承寫法自行撰寫 var calendar = EventCalendar.render();  // 畫出calendar 接著把畫完的calendar貼到想用的地方就可以了 歡迎改寫跟回報bug

工具庫 - 自訂 Java BBCode Parser

BBCode 是常在論壇還是一些輕量級應用使用的標籤 他在實際執行時會從 [b]test[/b] 這樣的標籤轉譯成 HTML 標籤 <b>test</b> 開放讓使用者自行撰寫 HTML 內容時,容易有撰寫錯誤或XSS安全性問題 所以使用這種限定規格的標籤,對使用者來說是比較容易的,對網站方也是相對好處理的 不過在搜尋既有的 Solutions 時發現多數都是 JavaScript 用的 Library Java使用者最常被推薦的可能是  kefirbb ,只是查看了規格後我是不太想使用 因為我不需要其他的標籤轉換功能,例如 Markdown 之類的 我也不想維護一個並不是一目瞭然的格式轉換用的 XML,需要加入或修改標籤時會有困難 滿多人會選擇自行寫簡單的 regular expression 轉換 不過幾乎網路上查到的 pattern 都沒法處理好巢狀(nested) BBCode 結構 以及新的標籤要對應不同的 regular expression,我也覺得是一種負擔 後來我看到了 Extendible-BBCode-Parser  這個JavaScript Library 結構上我覺得不錯 能有彈性的新增、修改標籤行為,也能確實處理好 nested BBCode 所以動手改寫了個 Java 的版本 目前調整到我覺得還可以的程度 改寫時我就只專注在我需要的部分,一些錯誤偵測我覺得沒必要就拿掉了 程式碼的長度覺得不適合整個貼上來,所以不貼code改貼 程式碼 Github 連結 跟參考的library一樣開放隨意修改、發佈 之前我對於 regular expression 大概就是基礎使用的程度 程式裡的那些 pattern 我也沒懂到可以說出什麼詳細教學 一些處理細節也是邊刻邊體會,從這次經驗學到了些東西,感謝原 Project 提供的各種想法

自動化重啟 Java Process

有些狀況下會碰到需要關閉 Java process 的狀況 不管是不可預期的,例如 OOM 導致 process crash 或是可預期的狀況,例如需要 Java程式、設定檔更新,而在系統內用 System.exit(0); 通常我們都會需要馬上再重開 Java process,將處理流程自動化會方便得多 Linux  bash 示範   JPID=0   while [ $JPID-eq 0 ]   do     eval "(java ...)"   # eval your own java process.     JPID=$?       # set PID to status.   done 用個迴圈監聽PID是否存在 Windows batch 寫法也是基於同樣概念 :exeLoop set JPID=-1 for /F "tokens=1" %%i in ('jps -lv ^| find "%MAINCLASS%"') do ( set JPID=%%i ) if %JPID%==-1 ( echo %_EXECJAVA% %JAVA_OPTS% -classpath "%CLASSPATH%" -.... %MAINCLASS% :: execute your own java process. ping 127.0.0.1 -n 2 -w 1000 > nul     :: wait for 2 seconds before next loop. ) goto exeLoop

AWS S3 Java code samples

紀錄最近在處理 AWS 相關 issue 時用的部分 method 最基本的 download、upload等等還滿好在 AWS 上找到範例 不過似乎有些要求就沒那麼好找 從AWS下載檔案的檔案名稱(alias name)或其他 Header 調整 AWS示範了建立供下載使用的連結的範例 public static URL getURLPresigned(String bucket, String s3name) {     AmazonS3 s3client = new AmazonS3Client(new BasicAWSCredentials(accessKey, secretKey));     Date expire = new Date(new Date().getTime() + 86400000L);     // set to be available for 1 day.     return s3client.generatePresignedUrl(bucket, s3name, expire, HttpMethod.GET); } 但是會使用AWS的,絕大多數都是有大量檔案存取需求 應該有不少公司的做法也會是上傳的檔案會加上 hash 避免檔案被覆蓋或作為多版本紀錄用途 但是給使用者下載的檔案名稱還是要使用原先上傳時的才比較合理 一個可行的做法就是調整下載的回應的 Content-Disposition Header 這個 Header 可以用來設定下載的檔案名稱,規格的說明可以查看 定義文件 寫出來的範例如下: public static URL getURLPresigned(String bucket, String s3name, String contentDisposition) {     AmazonS3 s3client = new AmazonS3Client(new BasicAWSCredentials(accessKey, secretKey));     Date expire = new Date(new Date().getTime() + 8...

範例 - JavaScript 實作 Excel 頁籤移動元件

最近想調整之前做的在有限空間內的選單內容切換元件 參考的項目來源則是Excel的下方頁籤選擇器 Excel這類廣泛使用的軟體,設計都還滿值得參考的 一方面是Microsoft將它做得滿直覺的 另一方面則是一般大眾也被訓練到能接受它的操作流程 實作的成果如下: 點擊下一項時,選單容器會自動往右邊捲動一個不定長度的子元件的距離 長按著下一項按鈕不放,則會持續往右捲動到底

Tree Structure 實作

雖然說Tree也還算是常用到的結構 不過大概是因為它的設計彈性太高,大部分的程式語言似乎都沒有高完成度的容器實作 有時候要依自己需求調整還是只能自己刻一個 這個範例用JavaScript刻一個自用版,應該還有地方可以改進就是... 當然如果不考慮就瀏覽器的相容性,也許用 document.implementation.createDocument 可以少一些工 另外JSON等結構也可以模仿一部份的操作 總而言之就是如果不是真的確定非這個結構不行,是不必要自己刻輪子來用 Java等程式語言用的版本也可以參考這個的概念來改 GitHub檔案目錄

範例 - JSP 使用Gmail為SMTP server

此範例單純寄信,不夾帶檔案 另外可能是google本身有GAE(google app engine)服務 Gmail不適合當作商業用的mail server 除了安全認證外,本身也有寄信上限100封 / per day 在Server上也可能有認證交換阻擋之類的限制 我在自己的電腦上使用沒問題,但也曾經在Linux的Server上碰到認證的Exception 如果要找商業使用的mail server最好還是另尋他途(例如:sendGrid)

JavaScript - 使用Regular Expression讓 replace() 做到 replace all

如同一般程式語言的replace() method一樣 JavaScript的replace()也只會取代第一個符合的字串 如果要做到 replaceAll() 的效果必須透過正規表示法來指定全域,如: str.replace(new RegExp("&#44;","gm"),","); RegExp的第二個參數g、m分別下了兩種搜尋規則 g - global match   m - working over multiple lines 這裡還能指定一種沒用在上述例子的 i - ignore case 設定完RegExp的搜尋規則便能達到目的

LZW 壓縮演算法

LZW衍生自LZ77演算法,為一方便實作且受到廣泛運用的壓縮演算法 在較早期因專利保護的關係,另一個現在也常用的演算法GZip被提出來取代LZW的使用 不過現在LZW在世界各國的專利大約都在2003、2004年左右過期 LZW主要運用在文字及影像的壓縮處理上 他的實作方式是建立一個字典來記錄出現過的文字(字元) 例如:[AA: 258, AAA: 270, AAB: 264, AB: 256 ....] 字典在壓縮完後就被拋棄,解壓縮時則會在運算時依相同規則再建立一本字典 所以當重複的文字或字元較多時會有比較好的效率,反之則有可能幾乎沒效果 這個特性同樣適用在影像上,對於具有大範圍相同顏色的影像有較好的效果 這個演算法的特色是實現簡單,但因為不會對內容作分析,所以不見得是壓縮比最好的演算法 以下為JavaScript的LZW演算法實作

偵測瀏覽器版本

JavaScript的全域變數 navigator.userAgent 是現在判斷瀏覽器版本的依據 它最一開始是被瀏覽器用來標示支援的標準 隨著瀏覽器的演化,同個支系的瀏覽器很可能已經跟祖先支援的標準沒什麼關係了 但是基於相容性的考量,以前的userAgent的內容也往往會被繼承,並添上新的標準的標示 以Chrome的userAgent為例 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31" "KHTML"是最早期的瀏覽器標準之一,已經跟現代瀏覽器的標準沒什麼關係了 "Safari"也是Chrome剛推出時,為了標明相容Safari的標準規格而加上去的 其餘的標示依此類推,可以知道userAgent並不是那麼明確 特別是行動版本的瀏覽器因實作廠商眾多,userAgent更是混亂 要判斷行動瀏覽器版本可參考 之前的文章 雖然userAgent並不是完全符合瀏覽器的狀況,但要判斷瀏覽器版本也只能靠它了 以下實作簡單的判斷瀏覽器的版本

JavaScript DOMContentLoaded 事件使用

這個事件很接近JQuery的 ready() function,是HTML5規格的新事件 事件的執行時間可參考下圖 一般常見到將要在文件載入時就立刻執行的程式碼寫在onload事件裡 但onload事件的發生時機是在整份HTML文件載入完成,包含圖片等額外資源 如果那些資源很龐大,則會延遲事件的執行時間,並會讓使用者看到未處理過的頁面 DOMContentLoaded事件則是在 DOM載入完成後發生 在過去要做到相同的效果,常見作法是將script寫在HTML文件的最下方 另外也有一些要繞點遠路的做法,或是乾脆使用framework 隨著HTML逐步地擴展規格,倚賴framework的需求也逐漸下降 實際的使用方式如下,並附上相容舊瀏覽器的作法

偵測行動瀏覽器

很多網站除了桌面版本外,也會另外提供行動版本的網站 當然現在RWD的設計很流行,只是也不是所有的聲音都贊同就是 不過再說到這些設計需求時,有一個先決條件是要先判別瀏覽器是否為行動版本 判斷上我們會使用User-Agent當依據,這裡不多說 Detect Mobile Browsers 這個開源工具庫提供了方便判斷的小工具 而且具有Apache、ASP.NET、JSP、Python、C#、Rails等各種語言的版本 以下用最新下載的JavaScript版本(2013/3/27下載)來看

範例 - JavaScript 實作可拖曳排序清單(sortable list)

這篇文章接續 拖曳物件的教學 利用之前寫好的架構再接續較複雜的行為 示範的目標是一水平排列的清單內容,並做到藉由拖曳清單項目改變其排列順序 首先準備好兩種CSS,分別給一般狀態以及拖曳中狀態下的清單項目使用 .undrag {     position:relative;     z-index: 1;     opacity: 1;     filter: alpha(opacity=100);     top: 0px;     left: 0px;     cursor: pointer; } .drag {     z-index: 100;     position:absolute;     opacity: .50;     filter: alpha(opacity=50);     cursor: move; }

範例 - JavaScript 實作可拖曳物件

實作成果示範 物件拖曳的重點在於物件位置的計算公式 - 目前滑鼠位置-起始滑鼠位置+目標位置 單純拖曳物件的話不算困難 說的上比較困難的是拖曳之後要結合的動作(如:drop、sortable list等) 雖然HTML5有Drag相關的API,不過這邊就先不提了 先做出一個能相容於老舊瀏覽器(IE)的版本 GitHub檔案目錄

範例 - JavaScript 替換瀏覽器預設滑鼠右鍵選單

這次實作的功能是要替換瀏覽器在網頁被點擊滑鼠右鍵時跳出的選單 改成跳出自製的選單 滑鼠的一個點擊(click)就會引發3個事件 點擊滑鼠左鍵的話,依序是 onmousedown -> onmouseup -> onclick 如果按下的是滑鼠右鍵,則依序是 onmousedown -> onmouseup -> oncontextmenu 瀏覽器的預設右鍵選單通常在執行 oncontextmenu 前就會先出現(display) 所以我們就必須在 onmousedown or onmouseup 時事先處理 oncontextmenu 事件 在 firefox 18.0.1 時會發現其在 oncontextmenu 時處理的頁面狀態與點擊發生前相同 所以要對應 firefox 的跨瀏覽器處理,還要注意oncontextmenu事件是否使用前面事件的物件 實作程式碼如下:

範例 - JavaScript 等比例縮小圖片

max-width、max-height以及這兩個的 min 版本是偶爾能在某些CSS中看到的屬性設定 不過因為IE不會辨識這些屬性,所以就直接寫JavaScript 調整圖片大小 var img = this.getElementsByTagName("img")[0]; img.onload = function () {     var maxWidth = "300",         maxHeight = "80";     if (img.offsetHeight >= (maxHeight / maxWidth) * img.offsetWidth) {         img.style.width = img.offsetWidth / img.offsetHeight * maxHeight + "px";         img.style.height = maxHeight + "px";     } else {         img.style.height = img.offsetHeight / img.offsetWidth * maxHeight + "px";         img.style.width = maxWidth + "px";     } };