CSS 與 JavaScript 的樂趣
阿爽出生的時候, 我用 Web Diary Pro 架了第一版的寶寶日記. 那時候對網站沒有什麼太多的概念, 只要求 Web Diary 能動就好, 除了把寫在 Perl source 裡的日文換成中文外, 其它什麼都不敢動. 看到那個 style.css 也是敬而遠之, 連用 vi 把它打開的勇氣都沒有.
今年年初, 將 Web Diary 換成 Movable Type 後, 為了 MT 模板的問題, 硬著頭皮開始研究 CSS, 才知道原來 Web Diary 目錄下的那個 style.css 就是它的 CSS 檔呀.
開始研究 CSS 後, 彷彿讓我發現了一個新天新地. 原來我對 html 的了解與觀念已經過時了, CSS 是用來將網頁的表現方式從內文中抽離的好工具: html 裡應該只有文件的內容本身, 而字型, 顏色, 甚至排版, 應該都交給 CSS. 好處是, 我可以在不更動 html 的狀況下, 只修改 CSS 就讓整個網站煥然一新. 前一陣子阿快日記的改版就是這樣做到的.
***
把 MT 昇級到 3.3 版之後, 有一些小問題令我不太滿意. 其中一個就是檔案上傳的時候, 上傳的目錄預設是不顯示出來的, 要按一個 link 它才會顯示出來, 這樣讓我每一次上傳圖片的時候都要多按一下, 很討厭.
我到 MT 裡面去挖了那個 template 出來, 發現它除了 html 以外, 還有一堆像程式的東西. 原來那些碼叫做 JavaScript 呀. 我想起來, 我在 MT 裡裝的那個 EnhancedEntryEditing 插件, 用到的那個 TinyMCE 編輯器, 不也是 JavaScript 寫的嗎 ? 我問了 Google 大神後, 大概知道 JavaScript 是一種嵌在 html 裡的 scipt, 在 client 端由 browser 執行. 我終於知道為什麼現在的瀏覽器似乎都很複雜了, 因為要跑這麼複雜的 script 呀.
看了網路上一些範例後, 覺得 JavaScript 實在是很有趣的東西. 而且有一個特點是: 因為它是解譯執行的 script, 不經過 compile, 所以 OOP 裡很多概念都可以輕易實作出來, 包括動態生成程式碼這種對 compiler 來講幾乎是不可能的事都做得到. 我決定買幾本書, 好好來研究一下這東西.
JavaScript 的語法跟 C 很像, 但是帶入了更多 OOP 的觀念. 雖然我對 C 不熟, 但多年來在 VB 裡面打滾, 讓我對 OOP 的概念不會太陌生, 所以對於像 property, method, member function, 甚至於 DOM 和 event listener 這些元素都還蠻能理解的. 當我看完 event listener 的章節後, 又看到一個新天新地, 發現原來在 browser 端執行的 script 可以做這麼多的事. 我再回頭去挖 MT 裡的那個問題: 上傳時要多按一下 :
我用 Firefox 的 DOM inspector 去挖, 發現按下那個 link 時, 有一個 div 的 class 會改變, 而這個 class 對應到 CSS 裡設定顯示或不顯示下半部關於 upload path 的設定. 而這個 class 的改變, 則是有一個用 JavaScript 寫成的 event lister 在監聽那個 link 的 mousedown 事件. 在 template 裡呼叫的 JavaScript function 叫 toogleActive, 沒有嵌在模板裡, 而是放在整個 MT 的 JavaScript library 檔中: mt-static/mt.js:
後來我發現, 其實我不用動這個 JavaScript function, 只要把那個 div 的預設 property 改成 active 就好了. 這個 toggleActive 其實只是交替把 active 這個 class name 加上去或拿掉而已.
***
解決了這個問題後, 我又想動另一個問題: MT 在每次 upload 檔案完成後會幫你產生 html, 讓你可以把顯示圖片用的 html 直接貼到編輯的文章中. 但是很不方便的是, 它產生的 html 是放在一個 text area 中, 我得先用 mouse 把它選起來, 再按 ctrl-C 或是用右鍵功能表把它 copy 到剪貼簿.
我查了一下 text area 這個物件在 JavaScript 裡有什麼 property 或是 method 可以用, 這是以前在寫 VB 時的習慣. 因為有時候在 OOP 的程式語言中, 物件的用法跟我原來想像的可能會差很多. 比如說我很期望 text area 這個物件會有一個 method 叫 copyToClipboard, 這樣我就可以用 getElementById(‘textareaname’).copyToClipboard() 這樣的方法把它的內容丟到剪貼簿裡.
不過事與願違, 沒有這個 method. 跟剪貼簿有關的物件掛在 windows 物件下, 我得用 window.clipboardData 這個物件, 它有一個 method 叫 setData, 可以用來傳入資料到剪貼簿中. 另外我希望在把資料傳進去的同時, text area 裡的文字可以是被選取的狀態, 這樣可以暗示使用者 (其實只有我跟 Guava) 是那些區域被送到剪貼簿去. 我找到了一個叫做 select 的 method, 但是它並不適用在 text area 的物件上, 而是適用在一種叫 textRange 類別的物件上, 而 textRange 則是由像 text area 這種物件呼叫 createTextRange 這個 method 產生的.
之所以要多這一層, 是因為 textRange 物件可以用來改變選取範圍. 到這裡, 所所需要的方法跟物件都有了, 所以我就在檔案上傳完成的 template 裡加上這樣一段 JavaScript, 並且加上一個 "傳送到剪貼簿" 的按鈕, 用 onclick 事件去呼叫它:
寫完的東西看起來像這樣:
就這樣, 完成了一個很方便的功能. 接下來還要做些什麼呢 ? 讓我再想想. 如果各位讀者哪天發現阿爽日記或是我的部落格多了什麼奇怪的, 會飛會跑的東西, 不要懷疑, 一定是我用 JavaScript 在做實驗啦.
***
附記: 我在研究 CSS 跟 JavaScript 時看的書. 現在電腦書能看的實在不多了啊.
- Web CSS 網頁樣式設計學 [博碩]
- CSS 您一定會遇到的問題與解答 [上奇]
- DHTML 網頁設計師手札 [上奇]
最後這本一定要提一下, 這本書翻自 Sitepoint 的 DHTML Utopia: Modern Web Design Using JavaScript & DOM, 是 JavaScript 入門的一本好書. 但是… 被上奇翻譯的很糟不說, 校稿根本沒在校. 全書共十章, 每一章都有三到五處不等的錯字, 而且一看就知道打字的人是打注音輸入法…
近期留言