iT邦幫忙

DAY 4
6

網站系統規劃實務系列 第 4

網站系統規劃 - 基本網頁元素介紹, JS

本篇作為第四篇,我們來談談網頁世界中,
讓前端工程師百思不解,讓 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 起源與需求。

http://disp.cc/b/540-385P

* 無所遁形之 Selector:

如何找到正確的 html 對象進行操作?
這也是 jQuery 這個函式庫筆者認為最有幫住的部份。

http://disp.cc/b/540-385R

* 可怕的事件叢林:

細談大多數事件的類型,另外介紹 bubble event 的事件重要特性。

http://disp.cc/b/540-385S

這一篇補充資料則談論到定義自訂事件,屬於比較高階的用法。

http://disp.cc/b/540-385V

* 屬性與樣式:

我們提到過 JS 的功能幾乎都是再修改 html 的屬性,
有哪些屬性可以修改,如何修改屬性,這中間的細節都在這篇文章談論到。

http://disp.cc/b/540-385W

* 巡覽‧跳過來跳過去:

跟 selector 很像,但是這篇是談論 dom 元件彼此之間的關係。

http://disp.cc/b/540-385X

* 五光四色的特效世界:

談論特效的幾個原則,計時器、屬性的變動,
透過這些基本元素可以構成很複雜的視覺效果。
< http://disp.cc/b/540-385Z >

ps. 除這篇提到的以外,近幾年來 HTML5 興起,瀏覽器支援度也慢慢普及,
所以也有越來越多使用 canvas / svg 等,元素進行繪圖的特效出現。

* 網頁元素的工廠美學:

詳細討論如何透過 JS 新增各種不同的 html 標籤。

< http://disp.cc/b/540-3861 >

* 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/


上一篇
網站系統規劃 - 基本網頁元素介紹, CSS
下一篇
網站系統規劃 - 基本網頁元素介紹 表單(Form)
系列文
網站系統規劃實務27
0
jamesfisher
iT邦研究生 5 級 ‧ 2012-09-28 10:03:02

tony大寫的真的是篇篇好文...
看完後都覺得自己懂了 (明明還是什麼都不會,XD)

0
timloo
iT邦研究生 2 級 ‧ 2012-09-28 15:17:35

tony1223提到:
雖然有時候我覺得作網站系統,的確是跟慢性自殺沒什麼差別,
不過人本來就是在這樣的過程中度過得嘛,
所謂有愛無礙(喂)~熱血無敵(喂喂)~青春萬歲(喂喂喂)~*


蠻好笑的,

果然接下來的文章很硬。

行文很流暢,資深前端工程師文筆都這麼流暢嗎?感覺很像有練過。

這個行業好像要隨時keep住流行的技術,
過了40歲的老頭子每次閱讀,真有趕不上的感覺。
連範例來不及測試,理解,一大堆demo就過去了。

如果30天都這種寫法,這種文章風格樹立超高的門檻。

所以真的錯估了前端技術學習曲線的長度,不是陡峭度。

0
timloo
iT邦研究生 2 級 ‧ 2012-09-28 15:22:54

tony1223提到:
筆者在 Facebook 上也有經營專門討論 JavaScript 討論的社群,
也歡迎大家一起來參與討論:
http://www.facebook.com/groups/javascript.tw/

上次看介紹,這是台灣女姓工程師參與最多的社群,還是研討會的會後檢討,女性志工人數超多的社群,如果再年輕10歲,一定要來參加。

每年cosup都會找北一女,夾著幾個中山女高的小女生來當工作人員,一片綠色制服,算很鮮明的特色。

在內部介紹,覺得付費研討會的水準愈來愈高了!!

tony1223 iT邦新手 2 級 ‧ 2012-09-28 16:47:46 檢舉

那是 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/

0
ted99tw
iT邦高手 1 級 ‧ 2012-09-28 17:08:47

tony1223提到:
就跟原子筆跟原子沒什麼直接關係一樣...

[讚讚]讚
笑得類都快噴出來了,是說JSDC 2013門票才約400元,就算沒有龍蝦,也絕對要去湊熱鬧啦!!(其實在像我這種IT人眼裏,這些辣妹比龍蝦還.....)偷笑

tony1223 iT邦新手 2 級 ‧ 2012-09-28 20:19:05 檢舉

2012 是 $400,2013 還在籌備中,目前尚未公告費用唷

我要留言

立即登入留言