本篇作為第四篇,我們來談談網頁世界中,
讓前端工程師百思不解,讓 Bug 流連忘返(咦),
讓網頁能夠化腐朽為神奇的,JavaScript。
--------系列簡介--------
網站系統可說是現在最多學子與新人想要入門的一個領域,
這個原本屬於新興的領域,這幾年來也累積許多年的知識與 pattern ,
在有限的環境(stateless)與有限的伺服器端、瀏覽器資源下,
成為許多人進入程式的一塊入門鐵板(?)。
這個系列希望能夠就網站系統設計幾個門檻著手,
這是設定給初心者作為學習,給同好們作為回顧,
重新認識有關網站系統的每個環節與認識。
今天我們要聊的是 JS ,
是事出有因 ? 是非善惡的因果循環, 還是天意作弄?
到底是情愛的糾葛 ; 命運的糾纏,金錢的誘惑 ; 還是利益的衝突,
是否種下日後一切糾葛的種子,因而埋下了殺機呢?
在冥冥之中,自有安排 ~
(喂) 走錯棚了,感謝下午好同事再度提供開文梗一枚,
雖然有時候我覺得作網站系統,的確是跟慢性自殺沒什麼差別,
不過人本來就是在這樣的過程中度過得嘛,
所謂有愛無礙(喂)~熱血無敵(喂喂)~青春萬歲(喂喂喂)~*
好的,今天要來寫 JavaScript ,(正經模式)
到目前為止這傢伙出場的戲份最少,但是其實他也非常重要,
筆者今天也苦思一整天,到底要用什麼角度來切入這個主題好呢。
基本上筆者很想偏心的為 JS 寫多一點,因為他是我珍愛的語言之一,
不過務實點的說法是寫再多都不可能在一篇文章內概括 JS 的所有東西;
白痴點的說法是有再多的文字都說不完筆者對他的愛啊。(喂)
那怎麼辦呢,首先,我們要回歸基本,聊什麼是 JavaScript。
筆者曾經在 2008 年用將近一週的時間撰文,
寫作從 JS 到 jQuery (著名 JS 函式庫) 的系列文章為數八篇。
(在此也可以看出 JS 的複雜程度與細節之多。)
其中用相當多的篇幅論述什麼是 JavaScript ,因為有關 JS 的說明其實差不多,
筆者在此也就借用當時的架構並用現在的看法重新詮釋。
@ 什麼是 JavaScript ?它跟 Java 程式語言有關嗎?我需要學嗎?
JavaScript 跟 Java 完全不相關,就跟原子筆跟原子沒什麼直接關係一樣,
JavaScript 是在網頁上執行的程式碼,可以進行一些網頁元素的屬性修改。
要執行 JS 不需要為瀏覽器安裝任何額外元件,
任何正常的 Browser 都有執行 JavaScript 的能力,
時至今日,幾乎所有網頁上都有他的已經存在。
@ 為什麼我們需要 JavaScript ?
想想這個情境,今天您從前面兩篇學會如何撰寫 html 與 CSS,
但您希望能夠有一些動態的效果,像是對於競標或者活動倒數類型的網站,
您可能會希望有個計時器,這類的元素,就需要一直不斷的改變畫面上的文字。
雖然我們可以透過重新整理頁面來改變畫面,
但是重新整理的速度相對比較慢,而且浪費網路資源,
所以我們常會使用 JavaScript 這個簡易的語言來操作網頁元素更新畫面。
@ 聽起來 JavaScript 好像是個很炫的東西,那我們要怎麼寫呢?
前面提到,網頁上的一切東西幾乎都是由 html 構成,
JavaScript 也是以 html tag 的方式存在在網頁上的唷!
首先撰寫 <script> 標籤,並且加上屬性 type="text/javascript" ,
如以下的語法將會彈出含有 "hello" 文字的確認框,
<script type="text/javascript">
//可別打錯字囉 ,如果打成 text/javascirpt 可會沒有反應的。
alert("hello");
</script>
馬上到這裡線上操作看看? http://jsfiddle.net/zGUBz/
以 script 標籤包覆的內容就是可以使用 JavaScript 語法的地方。
@ JavaScript 語法?
對,JavaScript 是一種腳本語言(Script Language ),
他有不同於 html 這個標記語言的語法。
像是我們可以透過 var 來定義變數,
以兩個雙引號夾起的稱之為字串(程式裡面對文字類型的稱呼),
並且以分號結尾作為行與行之間的區隔。
舉例,
var name = "TonyQ";
您在這裡就定義了一個叫做 name 的變數,型別是字串,內容是 TonyQ 。
然後您可以就可以使用 name 這個別名作為操作。
如
<script type="text/javascript">
//可別打錯字囉 ,如果打成 text/javascirpt 可會沒有反應的。
var name ="TonyQ";
alert(name);
</script>
將彈出含有 "TonyQ" 字眼的確認框。
馬上到這裡線上操作看看? http://jsfiddle.net/NBtx3/
@ alert 是什麼?
alert 是 JavaScript 裡面的預設函式(function) 之一,
這個函式接收一個參數(parameter),用來彈出顯示這個文字的確認框。
要呼叫(invoke)一個函式(function) 的方法很簡單,
先寫上函式名稱,再之後加上兩個括號,就是呼叫。
如:
<函式名稱>()
//alert()
那我們前面有提他需要提供一個文字參數,
一個函式可能沒有參數,也可能有一個以上的參數,
參數則是以逗號分隔的方式放入。
如:
<函式名稱>(參數一,參數二,參數三)
//alert(param1,param2,param3)
所以當我們寫 alert(name) ,就表示呼叫 alert 這個方法,
並且傳入將 name 這個變數的內容傳入作為第一個參數。
@ 那到底什麼是函式(function)?
函式代表著一系列定義好的操作,
讓您可以組織您的程式碼,方便進行再利用程式碼。
以下示範如何定義一個函式(function) ,並呼叫他。
定義一個函式的語法如下:
function <自定義函式名稱>(參數名稱1,參數名稱2,參數名稱3 /*...視需要定義 */ ){
/*預執行程式碼 */
}
範例:
<script type="text/javascript">
function MyFunction(){
alert("hi");
}
MyFunction();//呼叫一次
MyFunction();//呼叫兩次
</script>
以上的範例會呼叫兩次我們定義好得 alert("hi") 指令。
線上範例 http://jsfiddle.net/nr4Mt/
@ 還有別的嗎?
一般語言有的 if-else , for 、 while 迴圈,JavaScript 也都有。
如
if(1 == 1){
alert("1 等於 1 ");
}else{
alert("1 不等於 1 ");
}
或
for(var i =0 ; i < 10 ;++i){
alert("列印從 0 到 9 的數字,目前數字是"+i);
}
這些相關的介紹可能對讀者而言,有點太繁瑣了,
請直接參考 http://www.htmlite.com/JS010.php。
筆者想強調的事情是,JavaScript 是一個在語言層面上,
還算是相當完整的迷你(?) 語言。
有函式、有條件判斷(if-else)、迴圈(for/while)、
物件(object)、陣列(array) 等語言常見的特性。
@ OK 我明白了,JavaScript 是一個看起來很枯燥無聊的程式語言,
那我們到底可以拿他來作什麼?
除了彈出一個很煩而很吵的 alert 視窗以外?
基本上,JavaScript 最常用來進行的行為是修改 html 元件的屬性,
舉個例子,底下我們有兩個 img 標籤,分別對應到兩張圖:
我們可以使用 JavaScript 對 img 的 src 屬性進行改變,如下圖所示
可執行線上範例:http://jsfiddle.net/GzxFR/
@ 我看到 document.getElementById ,這是什麼?
因為標籤都長得一模一樣,你必須明確讓 JavaScript 知道他應該修改那個元素,
所以在這裡我們將 img 加上 Id ,
並且對 document 詢問,叫這個 ID 的元素是誰,
由 document 回應給我們對應的元素,並以此進行操作。
如果沒有以這 id 為名的元素,則我們會拿到 null (不存在的內容)。
這也是 JS 操作中相當重要的一個環節唷,
筆者的經驗中有無數的 Bug 是來自於找錯對象嫁錯人。(咦)
確實掌握自己想要操作的對象是很重要的!
另外根據 html 的規則,
同一個 ID 在一個網頁上的元素只能有一個,
換言之,不能有兩個 html tag 有相同的 ID。
@ 可是那我為什麼不在 html 裡直接將第二張 img 的 src 改掉就好?
--請不要對範例太認真--(被拖走)
哈哈,事實上的確我們不太會做這種靜態式的修改,
我們更多的狀況可能是底下這個情境:
點擊後改變圖片的內容,所以接下來我們要繼續介紹所謂的事件。
@ 事件
我們操作網頁並不是只是看,我們有滑鼠,有鍵盤,
可以進行許多的操作,這些都是事件:
像是捲動視窗(scroll),
點擊滑鼠(按下滑鼠:mousedown,放開滑鼠:mouseup,點擊:click)
打字(按下按鍵:keydown,放開按鍵:keyup)
滑鼠移動軌跡(mouseover)
@ 噢,好多事件,我都昏頭了,我們可不可以一個一個來?
我們最常使用與處理的事件,
根據筆者不正式也不客觀的統計,最常用的是 click 事件:
在原始的 JavaScript 中,我們可以針對 html 定義事件,
如讓我們稍微修改原本的範例,將改變圖片的部份修改到點擊事件:
<img src="http://placehold.it/94x95&text=img1" />
<img id="img2" src="http://placehold.it/94x95&text=img2" />
<script type="text/javascript">
//透過 document 物件與 id 取得網頁元素
var img = document.getElementById("img2");
img.onclick = function(){
var theimg = document.getElementById("img2");
theimg.src="http://placehold.it/94x95&text=Clicked";
}
</script>
可執行線上範例:http://jsfiddle.net/GzxFR/2/
當您點擊 img2 時,他將改變圖片為 Clicked 。
在此稍微解說這段程式碼,我們取得 img 這個元件後,
為他設定 onclick 這個屬性,並且傳入一個函式。
onclick 這個屬性是 html tag 中,保留給 click 事件用的屬性,
而傳入的函式,則會負責處理這個事件發生後的行為,
並且每次事件發生後都會被執行。
而設定 onclick 屬性的這個動作,我們稱之為事件繫結。(event binding)
除了上面範例的作法,也有 addEventListener/attachEvent 的作法,
採用 addEventListener/attachEvent 可以將多個函式繫結(bind) 在同一個事件上。
礙於篇幅有限,詳情請參考底下資料,
https://developer.mozilla.org/zh-TW/docs/DOM/element.addEventListener
所有事件列表與瀏覽器支持度
http://www.quirksmode.org/dom/events/index.html
ps.
可能有人會對這個範例有疑問,
這裡因為我們還沒有討論到事件的對象、 closure 概念,
為了避免新手讀者一次吸收太多事情,
所以我在事件中是重新透過 document 取得對象。
事實上,使用 this 這個事件對象 (event target) 進行設定,
或者沿用 img 都會是更好得選擇。
@ 其他的有趣應用
其實事件處理是網頁上最最常見的用途,可以說是核心靈魂,
複雜的網頁應用就是在許多的事件中交織出來的。
在此也舉出其他非事件的應用,像是這個簡易時鐘範例
線上範例http://jsfiddle.net/L7eb3/
@ window.setInterval ?
這也是一個內建函式,
這個函式會根據指定的時間間隔,定期執行傳入的函式內容。
時間有限,在此不多作著墨,可以參考 josephj 大大更詳細的介紹。
http://josephj.com/prototype/JosephJiang/Study/SetTimeout/
(註:間隔並不十分準確,視當時 JS 的執行狀況, 可能會有數十到數百毫秒落差。)
@ new Date() ?
這是一個內建的物件,是專門用來處理日期相關的問題的,
當我們透過 new 建立一個 Date 物件時,預設會取得當前的時間。
@ div.innnerHTML ?
如果我們想要改變一個 html 元素的內容,
最快得方式就是覆寫這個元素底下的 html 。
但是要小心的事情是,如果底下有別的元素或原本的 html 字串,
將會被蓋掉哦!
如這個範例
線上範例http://jsfiddle.net/nhJ3z/
@ JavaScript 還可以作什麼?
從我們期待設計的效果來討論的話,JavaScript 主掌動態的回應,
像是點擊分頁時可以馬上切換分頁不換頁,
或是輸入文字時,希望能即時送出並且得到回應嗎?
或者是當使用者送出選單時(submit 事件),
希望能即使告訴使用者輸入錯誤或要求使用者填寫必填區塊,
這些都需要透過 JavaScript 來進行操作。
@ 還有什麼是我們還沒有在這篇文章中提到的?
基本上談 JavaScript 一定會聽到一個很夯的名詞, AJAX 。
這個名詞的內容,
就是透過 JavaScript 向伺服器送出請求,由伺服器回傳一段文字,
再用這些文字資料進行畫面更新的一個作法。
由於我們現在還沒談到動態網頁,所以這個部份對我們意義不大,
我們將會在之後用非常多篇幅來繼續介紹這個部份。
底下我們會繼續說明一些名詞與其他細節:
@ 什麼是 dom ? 好像常常有人說這個名詞 ....
這是 Document Object Model 的縮寫,事實上就是指 document 中元素,
對應到的 JavaScript 物件,我們就統稱為 dom。
像是前面的例子中,
var img = document.getElementById("img2");
這個 img 就是範例中 img 標籤對應到 JS 世界的 dom 元素,
document 這個物件也是 dom 的一種。
@ 什麼是 jQuery ?好像常常聽到?
由於 JavaScript 在操作上有許多複雜的地方,
所以有人整理一些常見的操作,做了一些幫助開發的工具,
jQuery 就是其中近年來頗為知名的一個,
其標語就是「Write less, do more.」。
詳細資料請參考 http://jquery.com/
同類型的工具還有 yui / prototype /dojo 等等
@ 參考資料與導讀
如文章開頭所述,筆者曾於 2008 年討論過 JS 的核心要素,
並且與 jQuery 這個函式庫進行對照,在這裡引來作為參考資料。
這也同時是筆者受邀至 2008 年開源人社群年會(COSCUP) ,
分享 jQuery 簡論 (jQuery Introduction) 時所準備的資料。
當然因為已經距離現在四年,有些時空背景上的轉換,
但我想核心元素改變差異仍不太大。
(除了 IE6/IE7 已經越來越式微,越來越可以忽略以外。XD)
* JavaScript的魔力:
簡論 JavaScript 起源與需求。
* 無所遁形之 Selector:
如何找到正確的 html 對象進行操作?
這也是 jQuery 這個函式庫筆者認為最有幫住的部份。
* 可怕的事件叢林:
細談大多數事件的類型,另外介紹 bubble event 的事件重要特性。
這一篇補充資料則談論到定義自訂事件,屬於比較高階的用法。
* 屬性與樣式:
我們提到過 JS 的功能幾乎都是再修改 html 的屬性,
有哪些屬性可以修改,如何修改屬性,這中間的細節都在這篇文章談論到。
* 巡覽‧跳過來跳過去:
跟 selector 很像,但是這篇是談論 dom 元件彼此之間的關係。
* 五光四色的特效世界:
談論特效的幾個原則,計時器、屬性的變動,
透過這些基本元素可以構成很複雜的視覺效果。
< http://disp.cc/b/540-385Z >
ps. 除這篇提到的以外,近幾年來 HTML5 興起,瀏覽器支援度也慢慢普及,
所以也有越來越多使用 canvas / svg 等,元素進行繪圖的特效出現。
* 網頁元素的工廠美學:
詳細討論如何透過 JS 新增各種不同的 html 標籤。
* AJAX 非同步的傳輸:
用一整個專章介紹 AJAX 與相關的設計概念。
<http://disp.cc/b/540-3860 >
@ 最後總結:
各位讀者可能會發現這個章節撰文上的複雜度,
遠超過前面兩個部份(HTML / CSS),但並不代表 HTML/CSS 比較簡單,
其他兩個部份,細節獨立撰寫起來都能超過這篇的複雜度。
在筆者的前端工作中, JS 是前端工程師接觸最多的核心要角,
所以筆者有比較多的著墨與比較多的紀錄,
但如果要單論 CSS 或 html 中的眉角,絕對都能比這篇文章來得複雜。
希望大家不要誤會,網頁是由許多簡單但繁瑣的細節串連而成的。XD
讀完這個章節,筆者主要希望讀者能明白,
在瀏覽器世界裡面,JavaScript 這個工具的核心觀念:
1.他是一個程式語言,有他的語法與物件
2.JavaScript 絕大多數的操作來自於事件與計時器(setInterval/setTimeout)。
3.JavaScript 最主要的用途在於更新 html 內容與屬性
他做的事情非常單純,但是網站系統設計,
便是多年來逐漸在這麼單純的模型上,疊出複雜的使用案例(use-case)。
在我們準備要貿然進入複雜的模型之前,細細的品味基礎是很必要得。
筆者在 Facebook 上也有經營專門討論 JavaScript 討論的社群,
也歡迎大家一起來參與討論:
http://www.facebook.com/groups/javascript.tw/
tony1223提到:
雖然有時候我覺得作網站系統,的確是跟慢性自殺沒什麼差別,
不過人本來就是在這樣的過程中度過得嘛,
所謂有愛無礙(喂)~熱血無敵(喂喂)~青春萬歲(喂喂喂)~*
蠻好笑的,
果然接下來的文章很硬。
行文很流暢,資深前端工程師文筆都這麼流暢嗎?感覺很像有練過。
這個行業好像要隨時keep住流行的技術,
過了40歲的老頭子每次閱讀,真有趕不上的感覺。
連範例來不及測試,理解,一大堆demo就過去了。
如果30天都這種寫法,這種文章風格樹立超高的門檻。
所以真的錯估了前端技術學習曲線的長度,不是陡峭度。
tony1223提到:
筆者在 Facebook 上也有經營專門討論 JavaScript 討論的社群,
也歡迎大家一起來參與討論:
http://www.facebook.com/groups/javascript.tw/
上次看介紹,這是台灣女姓工程師參與最多的社群,還是研討會的會後檢討,女性志工人數超多的社群,如果再年輕10歲,一定要來參加。
每年cosup都會找北一女,夾著幾個中山女高的小女生來當工作人員,一片綠色制服,算很鮮明的特色。
在內部介紹,覺得付費研討會的水準愈來愈高了!!
那是 JSDC (JavaScript Developer Conference) 啦, JSDC 研討會主要由三個討論社群組成,除了我目前主持的 JavaScript.tw 以外,另外還有 NodeJS 跟 Html5 Group 。 XD
http://www.facebook.com/groups/htmlfive/
http://www.facebook.com/groups/node.js.tw/
另外 coscup 目前都還是免費研討會喔,
JSDC 是收費研討會,但是費用相當低廉就是了。(今年門票費用是 $400 每人。)
有關 JSDC ,更多訊息請參考 JSDC 官網。
http://jsdc.tw/2013/
tony1223提到:
就跟原子筆跟原子沒什麼直接關係一樣...
[讚]
笑得類都快噴出來了,是說JSDC 2013門票才約400元,就算沒有龍蝦,也絕對要去湊熱鬧啦!!(其實在像我這種IT人眼裏,這些辣妹比龍蝦還.....)
2012 是 $400,2013 還在籌備中,目前尚未公告費用唷