javascript 行為互動 




現代化行動網頁設計基礎入門班 DAY 3


講師:張凱迪(KD.Chang)







Copyright © 2013 All rights reserved





提醒您鍵盤左右鍵可以移動投影片

 Sorry,  PPT is not suitable for Hackers : ( 

Outline 

JavaScript 簡史與基礎介紹 

流程控制

函數  Function 基礎

物件  Object 基礎

BOM & DOM

事件處理  Event Handle

前情提要


內容架構 - HTML

外觀樣式 - CSS

行為互動 - JavaScript







Javascript 簡史與基礎介紹

javascript 發展簡史

源自1995年Netscape網景Brendan Eich所設計的LiveScript

當初網景和昇陽Sun有合作,因行銷策略改名為JavaScript

從此JavaScript成為全世界最被人誤解的程式語言

JavaScript是腳本語言(script language),不用編譯(compile)

JavaScript過去常用在client端,現在也常用於server和其它地

JavaScript是原型基礎的腳本語言和類別物件導向有所差異





javascript vs. java


  







台灣最大網路書店博客來把JavaScript和Java分在同一類 : (

JavaScript和Java並不一樣!


JavaScript由網景(Netscape)所發展 / Java為昇陽(Sun)所打造

JavaScript是直譯式腳本語言 / Java是需要編譯的程式語言

JavaScript 是寬鬆型別  /  Java需先事先宣告變數型別 

 JavaScript是原型基礎的物件導向 /  Java是類別基礎物件導向

  JavaScript 可以動態增加方法和屬性  /   Java 不行動態新增

JavaScript 一般不能讀寫檔案 / Java 可以讀寫檔案







那javascript可以做什麼?


動態新增文件內容 /  更改HTML樣式和屬性

表單送出驗證

監聽瀏覽器事件並作出回應

開發伺服器(Server)端程式 (Node.js)

開發(Mobile) Web Application

開發Open Hardware ( Tessel )


關於Javascript的一些小事


曾經微軟還有個叫JScript,也是ECMA-262標準實現之一

廣義JavaScript包含ECMAScript、BOM、DOM 物件模型

JavaScript很容易學,但要玩的深不容易

使用文字編輯器即可編輯。存成 .js 檔案

網路很多函式庫(Library)、框架(Framework)、套件(Plug-in)

HTML5最重要的一部分就是JavaScript

第一個Js程式


 <script>
    document.getElementById('head').innerHTML = 'Hello   JavaScript!!';
 </script>
<h1 id="head"></h1>
//這裡做了1.用JS選取元素 2.動態改變HTML內容

按這看結果

JAVASCRIPT使用方式

1. 內嵌於<head></head> (因JS為直譯式,讀到即會執行)
 <head> //一般函數或事件處理會放置於此
	<script>
		alert("Hello JavaScript");
	</script>
</head>
2. 內嵌於<body></body>之中 (可以讓HTML優先載入)
 <body> //一般呼叫函式或更動HTML結構(DOM)程式放置
	<script>
		    alert("Hello JavaScript");
	</script>
 </body>
3. 外部引入檔案置於<head>或<body>內 (推薦使用)
 <script src="js/main.js"></script>
外部引入的<script></script>中不可再寫JS

善用開發者工具


善用開發者工具


Google Chrome 內建開發者工具

練習一(SAMPLE 3-1)


麻煩打開發者工具的console(主控台),幫google首頁換衣服

 document.getElementById('hplogo').style.background = 'url("http://www.turn.com/sites/default/files/wp-content/uploads/2010/03/yahoo_logo1.jpg")'; 


寫 JS 的好習慣


1.  JS是一段段程式敘述組成,習慣用分號 ; 結束一段程式敘述

2. 程式區塊 { } 是由多個程式敘述組成,可視為單獨一段敘述

3.  JS註解方式和CSS相同,單行 //註解,多行 /*註解 */

4.  程式縮排方便閱讀,區塊會往內縮排(四格或兩格皆可)


按這看結果

變數


JS 是一種寬鬆型別的程式語言,不需事先宣告型別即可以使用。變數可以視為一容器,可以在程式碼暫存資料,也可以更改所存的資料 (看成裝東西的盒子)。JS的基本型別( Primitives)有String(文字)、Number(數字)、Boolean(true/false)、undefined、null

使用var宣告變數,可直接初始化內容,或只先宣告之後再初始化(未初始化前為undefined)
 var name = "KD.Chang";  var name, age;







變數命名原則


區分大小寫、不用保留字、不可以用數字開頭、不可用 .

 錯誤示範: var if = 123; // 使用保留字  var 12ol = 'AB'; //用數字當開頭 var err.or = 'DJ'; //使用 .

指定敘述


在宣告變數的同時也可以給定初始值,給值的同時也決定了變數的型別(type),給定值使用等號(=),變數只是暫存,可以重新再指定值。等號並非數學相等而是賦值的意思,在JS中另外有(===)符號來比較相等

var name = 'KD.Chang'; //Stringvar lucky_num = 7 ; // Numbervar hot = true; //Booleanvar NONO;  //undefined



基本資料型別


基本上 JS 有五大基本資料型別(Primitives Data Types),Number ( 數字 )、 String(字串) 、Boolean(布林值)、undefined、null(又可視為object)。 任何不屬於基本資料型別的都是Object(物件),可以使用typeof觀察變數資料型別


按這看結果

number 數字


在JS中,沒有分所謂的整數、浮點數,一律都是Number。數字可以儲存:正負整數、浮點數、十六進位、八進位、指數、非數字(NaN)、Infinity、-Infinity





NUMBER 數字

整數:
 17   -> 17  // 十進位 0382 -> 382 // 因為有8,所以雖然是0開頭,仍是十進位 0377 -> 255 // 0開頭,八進位 0xff -> 255 // 0x開頭,十六進位

浮點數(整數加小數,可用e或E表以十為底指數):
 0.003 -> 0.003  .03 -> 0.03 4e-4 -> 0.0004   //最大值約:1.79E+308,最小值約:5e-324

NUMBER 數字

特殊值:
1. NaN(非數字)
亦即Not a Number,當運算結果為不正確時顯示(EX. 字串轉數字,數字和undefined做運算),任何數跟NaN運算都變NaN

2. Infinity(正無限)
當數字太大超過JS最大值範圍

3. -Infinity(負無限)
當數字太小超過JS最小值範圍

按這看結果

String 字串

字串是用兩個單引號 ' ' 或雙引號 " " 所包裹的文字型別(EX. 0或多個Unicode字元,包含文字、標點符號和數字),和C語言不同,並未支援如char()這種單一字元,只要引號中為單一字元即可。推薦用單引號,將雙引號保留給HTML屬性值

 var po = '念天地之悠悠'; var num = ''; // 空字串 var movie = 'D'; var num = '17';

boolean 布林值


常用於條件判斷,決定要進入程式的哪個區塊,只有true和false兩種值。

以下六種falsy值會自動轉為false :
1. 空字串 " "
2. null
3. undefined
4. 數字 0
5. 非數字 NaN(仍屬Number Type)
6. false
(除以上六種外,其餘包括字串"0"、"false"皆視為true)

undefined 


主要有兩種情形會產生undefined值:
1. 宣告變數後未初始值,會自動將其指定為undefined

2. 訪問物件不存在屬性或未宣告變數

 var name; console.log(gogo);

null 


null值不像undefined會在未初始化自動給值,只能由我們給定,意思代表變數沒有值或是不是個物件,和undefined不一樣,在轉換成數字時會變成0

 var someover = null; typeof someover;

escape 跳脫/逸出序列


Escape Sequence是以\開頭的字元,可以在字串中表示需用特殊方式表示的字元或鍵盤無法輸入的字元,這邊只列最常用三個

 \' -> ' \" -> " \\ -> \

運算子


 JS 的敘述運算式由運算元(operands)和運算子(operators )兩者組成。JS 中有算術、指定、位元、邏輯等運算子

 a + b = 7  // a, b, 7為運算元; +, =為運算子

運算子優先順序


運算式中通常有多個運算子,為了讓運算式可以有相同運算解果,運算式會有預設的優先順序。其實最簡單的就是我們耳熟能詳的『括號內先運算,先乘除後加減』


算術運算子


JS 提供了一般常用的數學運算符號:

1. 四則運算:+(加)、-(減)、*(乘)、/(除)、%(取餘數)
其中加號也用於連結兩字串,減號於數字前表負數,所以使用上需注意

2.  ++(遞增運算 x = x + 1)、--(遞減運算 x = x - 1)使用上需注意置於變數前後結果可能不同,置於變數前為先運算再指定值

按這看結果

位元運算子


JS 支援位元運算,可以進行二進位運算(EX. 向右移動幾位元、執行NOT、AND、XOR、OR運算),唯課程中較不會使用到,這裡只列出參考資料



參考文件:MDN 位元運算子

邏輯運算子


邏輯運算子常和布林值一起使用,並返回布林值。
主要有三種邏輯運算子:
1.  ! 表非(取相反)
2. && 表邏輯且
3. || 表邏輯或
 var a = true; var b = false; !a -> false a && b -> false a || b -> true

參考文件:MDN 邏輯運算子

指定運算子


指定運算子可以簡化運算是,寫出更簡潔程式,同樣的這邊只列出常用指定運算子

x += y  (x = x + y)
x -= y  (x = x - y) 
x *= y  (x = x * y )
x /= y  (x = x / y) 
x %= y (x = x % y)

參考文件:MDN 指定運算子

比較運算子

比較運算子用於比較運算元的大小,並根據比較結果返回布林值。運算元可以是數值、字串、布林或物件的值。字串是以 Unicode 的值作為標準的字典順序來比較。需要注意的是,如果兩個運算元不是同樣的類型(type),JS 會為了比較而嘗試把運算元轉換為適當的類型。等於 (==)、 不等於 (!=) 、嚴格等於 (===) 、嚴格不等於 (!==) 、 (>) 、 (>=)、 (<) 、 (<=)  

強烈建議使用嚴格相等性(===)、(!==)最為比較方式,因為不會自動轉換型別,避免發生錯誤

按這看結果
參考文件:MDN 比較運算子

型別轉換

Type Conversions 表示在同一個運算式中會有不同的型別,所以需要轉換成同一型別方能運算。而 JS 為鬆散型別的語言,在指定值時才決定變數型別,基本上 JS 會強制轉換型別

數值  + 字串 (數值會強制轉字串)
布林 + 字串 (布林會強制轉字串)
布林 + 數值 (布林會強制轉數值)
(布林轉字串 "true" / 轉數值 =  1; 轉字串為"false" / 轉數值 = 0)
用typeof()可以觀察值的型別,有、Number、String、Boolean、undefined、object、function

按這看結果

型別轉換

parseInt()
返回由第二個參數所指定的 radix (基數)的整數。如果 parseInt 遇到不是在指定基數之內的字元,就會直接忽略這個字元及其隨後字元,並返回在此之前已經分析出來的整數值。如果連第一個字元也不可以轉換為指定基數之內的字元,返回NaN(非數字) 。parseInt 函數會切除字串以取得整數
parseFloat()
返回浮點數。如果遇到正負符號 (+ 或 -)、數字 (0-9)、小數點、指數以外的字元,會返回在此之前的數值,並忽略那些字元。如果連第一個字元也不可以轉換為數字,就會返回NaN(非數字)
按這看結果

練習二(SAMPLE 3-2)


運用運算子和運算元計算(1 + 6) * 9 + (23  / 5),並用parseInt()將結果轉成整數







流程控制 

流程控制基礎

一般而言,JS 的程式是由上往下一直執行下去,但我們往往在功能上需要依條件不同而改變執行順序,這時候流程控制就扮演關鍵角色

1. 循序結構(Sequential)
預設的程式執行方式,亦即一個程式一個程式執行下來

2. 選擇結構(Selection)
是一種條件控制,亦即選擇題,可分為單選或二選一或多選

3. 重複結構(Iteration)
亦即迴圈控制,可以重複執行程式區塊,直到符合結束條件



流程控制基礎




http://docs.oracle.com/

邏輯運算子


1.  ! 表非(取相反)
2. && 表邏輯且
3. || 表邏輯或

*如果使用&&連結兩運算子,第一個運算元為true,則回傳第二個運算元。反之,則回傳第一個運算元
 *如果使用 || 連結兩運算子,第一個運算元為true,則回傳第一個運算元。反之,則回傳第二個運算元

按這看結果

比較運算子





http://www.pcstar.com.tw/blog/

循序結構


http://www.thevbprogrammer.com/

選擇結構




http://www.geocities.ws/paylook/Module6_files/image012.png

if 是非題


if 條件敘述是一種是否執行的是非題,如果符合條件運算結果為true則執行程式區塊(括號內程式碼)

 var grades = 70;  if(grades > 60){    console.log('真假,你竟然及格了!?');  } //若區塊內只有一行敘述可以不用大括號,但建議使用方便閱讀


按這看結果

if / else 二選一


若有兩個區塊,則可以變成二選一的選擇題。符合條件執行第一個區塊,不符合則執行第二個區塊

 var age = 20;

if(age >= 20){
  console.log('你可以投票了!');
}
else {
  console.log('小朋友,你還未成年喔~');
}

按這看結果

if / else if / else 多選一

若需要有多選一的情況,則可以運用if/if else if/else建立多選一的條件選擇

  var time = 7;

 if (time < 10 && time > 5) { 
   console.log('Good morning'); 
 } else if (time > 20 && time < 24) { 
   console.log('Good Night');
 } else { 
  console.log('Good Evening');
 }


按這看結果

switch 多選一

建立多選一的另一種方式為使用switch條件敘述,若是條件非邏輯判斷且選擇很多,建議使用switch,避免過多的if else判斷導致程式閱讀不易。請注意break敘述為必須,才會在符合條件執行完該區塊後跳出迴圈,否則會依序一直執行下去,至於最後的default值為選擇性,主要是提供都不符合條件執行的區塊


按這看結果

三元運算子 ? :


三元運算為簡化的條件判斷,其中 ? 代表" if "," : "代表else

var age = 30; var vote = (age >= 20) ? "成年" : "未成年";console.log(vote);

按這看結果

重複結構(前測、後測)



http://cdn2-b.examiner.com/

前測試重複結構



http://www.twivs.tnc.edu.tw/testnew/vbtest/VBPIC/loop1.gif

for 迴圈


for迴圈可以透過計數器的增加減少執行固定次數的程式區塊,由於是在迴圈開始前檢查條件,故稱前測迴圈

 for (起始值; 條件式; 更新值) {    指令; }
for(var i = 0; i < 10; i++){ console.log(i); }

按這看結果

for in 迴圈


for/in迴圈類似for迴圈,但for/in主要用於存取出物件(包含陣列)的屬性與方法

 var a = ['Andy', 'Tony', 'KD'];

for(var key in a){
  console.log(key + " : " + a[i]);
}

按這看結果

while 迴圈


while迴圈同樣也是前測迴圈,但和 for 迴圈不同的地方是,while需要自行在程式區塊內處理計數器的增減,若符合條件(true)才進入迴圈內,否則(false)則離開迴圈

*請注意不要讓while變成無窮迴圈(1.忘記加計數器 2.讓條件永遠成立 EX. while(1) or while(true) )避免系統耗盡當機


按這看結果

後測式程式結構



http://www.twivs.tnc.edu.tw/testnew/vbtest/VBPIC/loop2.gif

do while 迴圈


do/while 迴圈和 while 類似,只是do/while迴圈是在迴圈結尾才檢查條件是否符合,亦即迴圈區塊至少會執行一次

var i = 11;
var sum = 0;

do {
  sum += i;
  i++;
} while(i <= 10);

console.log(sum);

按這看結果

break / continue 

除了依照條件控制程式的流程外,我們也可以使用break和continue來控制程式的流程。注意的是兩者只能在程式區塊中使用

1. break
 當某些條件成立時,強迫迴圈終止,跳出迴圈(程式區塊),如同我們之前看到switch在條件符合時整個跳出迴圈
2. continue
 和break不同的是continue不會完全跳出程式區塊,只會結束這次迴圈,直接開始下次的迴圈

按這看結果

巢狀迴圈


巢狀迴圈亦即在迴圈中擁有其他迴圈,EX. while中有for,for中有while迴圈

for(var i = 1; i <=9; i++){
  console.log(i + ":");
  var j = 1;
  while(j <= 9){

    console.log(i * j);
    j++;
  }  
}

按這看結果

練習三(SAMPLE 3-3)


運用流程控制製作一判斷季節系統,3-5月為春季,6-8夏季,9-11秋季,12-2月冬季







函數 Function

function 是什麼?



http://captivatedev.com/

函數就像一個黑盒子


當我們程式越寫越大就會碰到程式碼重複的問題,而函數就是要解決這個問題,將一些共用的程式碼集合成一個區塊,可以傳入參數(Parameter)和回傳執行結果。也可以想成數學上的函數,將參數傳入後,會產生結果,而那個回傳結果就是函數的return值

執行函數稱為"Call Function",呼叫函數時不一定要傳入參數,但函數一定會有回傳值,若沒有設置則回傳undefined

Syntax : 需要傳入參數的資料型別
Semantics : 函數的功能

撰寫函數的習慣


 當我們呼叫函式時可以只知道需要傳入的參數並在傳入後取的傳回值,通常我們不需要知道內部的實作過程,但要達到這個目標,使用函數的人必須了解一些規則:

1. 函數的對外的介面接口需要定義良好、完整

2. 使用函數時,我們通常不需要知道背後的實作過程,但要知道如何使用介面

3. 在實作函數時專心於處理傳入的參數和傳回值,並確實完成函數功能的實作


js 函數


一般而言,JavaScript有內建函數和自定義的函數
JS中函數在被執行之前會被 解析(hoisted),因此它可以在任意 的地方都是有宣告的 ,即便在比這個函式還早呼叫

最簡單的函數長這樣:
 function sum(a, b) { //定義了傳入參數    var c = a + b;     //執行內容    return c;     //回傳值,若未設定回傳undefined }

JS 函數

JS function主要有三種方式:
1. 定義命名函數
 function sum(a, b){   return a + b; }
2. 定義匿名函數
 var sum = function(a, b){    return a + b; };
3. Function物件匿名函數
 var sum = new Function('a', 'b', '{return a + b }');

js 內建函數


1. parseInt() / parseFloat()
2. isNaN() / isFinite()
3. encodeURI() / decodeURI()
4. encodeURIComponent() / decodeURIComponent()
5. escape() / unescape()
6. eval()
7. alert() / confirm() / prompt() 

parseInt() / parseFloat()


之前在型別轉換時已經先介紹了這個函數,只是當時尚未正是介紹函數的特性,現在了解後就知道當時將參數傳入並接受回傳值的意義

parseInt()
返回由第二個參數所指定的 radix (基數)的整數

parseFloat()
返回浮點數,不過只支持10進位

按這看結果

isNaN() / isFinite()


透過isNaN() 可以得知傳入的數值是否是非數字,也可以同時知道是否能運用parseInt()、parseFloat()成功。此外NaN自己不存在等值的概念,故NaN == NaN 會return false

isFinite() 可以用來檢驗傳入數字是否為一既非infinity且非NaN的數字


URI 編碼/解碼


根據Wiki表示:統一資源標識符(Uniform Resource Identifier,或URI)是一個用於標識某一網際網路資源名稱的字元串,而URL(定義位置) 和URN(定義身份)則是URI的子集

在處理網頁(址)資料,常會有遇到中文字或是空白、標點符號等問題(英文、數字通常不會有問題) ,此時就可以使用 URI 編碼函數(通常標點轉為十六進位ASCII、中文轉成十六進位統一字元碼),如需轉回則使用解碼函數

參考文件:

URI 編碼/解碼

以下三種函數皆可以進行URI編碼,各有應用情境:
1. escape() 
除了ASCII Code、數字、英文字和符號包括: @ * / + 不編碼外,其餘都編碼,如果想對URI編碼,建議不用

2. encodeURI() 不編碼符號包括: ~ ! @ # $ & * ( ) = : / , ; ? + ' 
URI中的合法字符都不會被編碼,適合用於網址編碼

3. encodeURIComponent() 不編碼符號包括: ~ ! * ( ) '  
適合參數編碼,應用範圍廣
按這看結果
參考文件:Javascript URL 编码区别及转义字符处理

eval()


eval()函數可以將運算式的字串當做運算式,傳回運算式的計算結果。但使用上有安全顧慮(eval is evil),特別是用它執行第三方的JSON數據(其中可能包含惡意代碼),盡量少用

 eval(1+4); // 5

alert() / confirm() / prompt()


alert()、confirm()、prompt () 三者皆會在瀏覽器顯示對話框,但用處各自不同,其中confirm("text") 和 alert("text") 類似,都會把參數內的字串顯示在對話視窗中,但confirm()有確定和取消,會回傳true或false

 var name = prompt("Please key your name.", "預設值");  //若取消則回傳null

自己建立 js 函數


使用函數最重要的目的就是希望將重複的程式碼聚集在一起,透過函數的呼叫來執行重複的程式碼,亦即將重複的程式碼隱藏,以供重複使用

JS 基本函數由function關鍵字、函數名稱(也可以不用,為匿名函數)和程式區塊(傳入值和回傳值)所組成
 function help(){    alert('help'); }  help(); //此為沒有輸入值和回傳值的函數
按這看結果

傳值 / 傳址參數

傳值呼叫(call by value):將變數傳入函數時,函數會另外配置記憶體空間來儲存參數值(只copy value),故不會變更原始值

傳址呼叫(call by reference):將變數的記憶體位址傳入,如果說在函數中變更參數值,也會更動到原始值

JS 函數參數是依據不同資料型別預設不同傳遞、比較方式:
1. 傳值:Number、String、Boolean(基本型別)
2. 傳址:物件、陣列、函數
3. 傳址:String物件(另一種產生String方式)
*注意物件和陣列傳入函數,雖使用傳址,並不改物件本身
按這看結果

參數陣列

若在呼叫函數時有傳入參數,但在定義函數時沒有指名參數,我們仍可以用arguments參數陣列的物件取得參數個數和個別參數值,注意arguments 物件不是 一個 Array,雖然都有類似 Array 的語法,但是它沒有繼承來自 Array.prototype 事實上它繼承 object,所以不可以使用Array物件方法
 function sum(){ } sum(1,2,3);  sum.arguments.length; sum.arguments[0]; sum.arguments[1]; sum.arguments[1];
按這看結果

全域變數和區域變數

JS  中有一個很重要的觀念就是scope,亦即變數所存活的範圍(可被存取和生命週期範圍),在進階的JS 中常需要這樣的觀念。要特別注意的是JS 是function scope而不是C語言的block 區塊變數,也就是說變數存活範圍是以函數為分界,非以區塊 { } 為分界 。注意盡量使用區域變數,且使用var 宣告變數

1. 區域變數(Local):在函數內宣告的變數或傳入值,只能在函數內使用,函數外無法使用
2. 全域變數(Global):如果此變數在函數外宣告,或是未使用var宣告的變數,整個程式皆可存取,盡量避免使用全域變數

按這看結果

variable hoisting


JS 是 function scope ,且無論你在那裏宣告,都會提升到最前面宣告,稱為變數的拉升(Variable Hoisting)



按這看結果

scope chaing

我們之前提過:用var所宣告的變數,作用範圍是在當時所在環境(函數內),而不使用var直接指定值而建立的變數,則是全域物件上的一個屬性,也就全域範圍

在JS 中有稱作scope chain(範圍鏈)的特性,JS在查找變數時,會循著範圍鏈(Scope chain)一層一層往外找,若函數內找不到,則往外找

注意:內層函式都可以存取外部函式的變數

按這看結果
參考文章:[JavaScript] 忍之道解謎(一) - function Scope

SCOPE CHAING


http://docstore.mik.ua/orelly/


closure(閉包)

將作用域升級為全域或是return給全域變數,就會突破scope chain產生 closure,常用於1. 嵌套callback 函數 2. 實現private
 function add(x){
  return function(y){
    return x + y;
  };
}

var add6 = add(6);
var num = add6(4);
document.write(num); //return 10
按這看結果 參考文章:簡單看命名空間(Namespace)與jQuery原始碼

自調用函數


自我呼叫的函數,不用額外呼叫可自己執行。Self-invoking functions (自調用函數)是一種立刻執行,並建構自己的 closure 的函式

 (function () {
        var cat = "momo";
        document.write(cat);
})();
alert(cat); //undefined

按這看結果

js 除錯



打開瀏覽器的開發者工具,先看console!

練習四(SAMPLE 3-4)


運用function製作一華氏攝氏溫度轉化器,輸入值為攝氏,回傳值為華氏,轉換公式: F = ( 9 . 0 * C) / 5 . 0  +  32 . 0 








基礎物件 Object




wht oop ? 

物件導向程式語言(OOP)

一般而言程式語言具備以下四種特性稱之為OOP(Object-oriented programming) [主要為前三種] 
1. 封裝(Encapsulation)
封裝是將資料和函數建立成物件,亦即物件是由屬性和method方法(函數)所組成的黑盒子,JS沒有類別有建構函數
2. 繼承(Inheritance)
繼承可以讓物件重複利用類別的屬性和方法,JS用prototype
3. 多型(Polymorphism)
類別如需處理不同資料型,只需繼承基礎類別並使用同名方法但參數和程式碼不同,亦即同名異式(另有rewrite比較)
4. 聚合(Aggregation)
物件的某一個性質可以是另一種物件

js 物件、屬性和方法

JS 雖然是一種物件導向語言,不過和其沒有class(類別),在JS 世界中function也是物件

1. 物件(Objects)
在JS 中物件只是name和value的集合體,我們可以視為其他語言中的Dictionary或是Associative Arrays,亦即Object Literals(大括號包起分號名值成對的屬性和方法,用 , 分隔)
 var cat = {    name : "momo",    eat : function(){       alert('delicious!');    } }  var cat = new Object();  //另種建立物件方式

JS 物件、屬性和方法


2. 屬性(Properties)
物件屬性可以存取物件的儲存的資料,存取物件屬性用 . 運算子,也可以使用[ ]符號,JS 可以動態增刪物件屬性 
 cat.name; cat['name']; //兩種語法是相等的,唯一的差別是,使用中括號可以用動態的設定屬性,使用點操作不允許屬性為變數,否則會造成語法錯誤
3. 方法(Methods)
在JS 中物件方法是用來處理物件儲存資料的函數,JS 的物件方法是一個Function()函數的物件,取用方式為 . 運算子
 cat.eat();


JS 物件、屬性和方法





http://blog.rx836.tw/blog/javascript-patterns-1/

JS 支援的物件


1.內建物件
JS 語言中原生的物件,一般有11種(String、Array、Boolean、Date、Global、Math、Number、Object、RegExp、Error)

2.自訂物件
由使用者自己定義的物件

3.宿主物件(Host Objects) 
由宿主提供物件(如瀏覽器),像是BOM(Browser Object Model)

建立自定義物件

一般JS 建立自定義物件的方式有三種:
1. 使用物件字面值(Object Literal) 
使用大括號 {} 將屬性、方法包起來,屬性方法用 : 分隔成對的名稱和值,使用 , 分隔每一對屬性名稱和值,最後一個不用 ,
 var nameCard = {    name : 'Tony',    age : 20,    email : tonycc@gmail.com,    printCard : function(){  //名稱:值(匿名函數),物件方法      console.log(this.name);      console.log(this.email);    }  } //this關鍵字參考物件本身 nameCard.name;  // 亦可用 nameCard['name']; 存取 nameCard.printCard(); 

建立自定義物件

2. 使用Object物件建立
Object為所有JS物件的祖先,我們也可以使用Object當做建構函數來建立物件,建立的是空屬性,繼承Obeject的物件
 var nameCard = new Object(); // 等同 var nameCard = {}; nameCard.name = 'Tony'; // 新增屬性 delete nameCard.name; // 再存取就成undefined //新增方法#1 nameCard.printCard = print; function print() {     console.log(this.name); } //新增方法#2(使用匿名函數的方式) nameCard.printCard = function(){     console.log(this.name); }

建立自定義物件

3 . 使用建構函數建立
注意JS 中並無class(類別),但提供類似建構函數來協助建立多個物件,此種方式可以運用prototype繼承的特性

Constructor(建構函數)是一個函數,能夠定義物件的屬性和方法,JS的內建函數(EX. String等)就是建構函數,一般建構函數的首字大寫,this關鍵字指物件本身,建立物件步驟如下:

Step1. 使用建構函數宣告物件
Step2. 使用new 運算子建立物件

按這看結果

物件中建立物件


物件中可以建立階層架構(Object Hierarchy),因為物件的屬性值可以是另一物件,所以可以建立階層關係的物件架構,亦實現了OOP中的聚合的特性



按這看結果

物件方法與this 關鍵字


在物件中this關鍵字指的是物件本身,但不是固定指到同一物件,而是根據呼叫的物件的不同指到該物件本身。this關鍵字為物件導向中極重要的觀念,務必把握住


按這看結果

js 的 Prototype 原型物件

我們之前已經提到過JS是Prototype-based(原型基礎)的物件導向,不同於C++/Java/C#等的Class-based(類別基礎)的物件導向

請注意JS中並無類別,使用建構函數來建立物件,我們使用現成物件作為Prototype(原型)來建立其他物件,複本出的物件則擁有原型物件的屬性與方法。兩物件繼承於同一原型物件,則屬於同一類別實例(並非絕對,因可能使用 {} 建立物件)

類別和原型的主要差別在於類別可以視為一個模子,開模後製出的一個個物件實體都具備相同的功能。原型可視為基底或是賽車底盤,可以動態在上面加蓋其他功能或屬性

原型物件、建構函數和繼承


http://www.herongyang.com/

原型物件、建構函數和繼承


JS 中每個物件擁有prototype的屬性參考繼承的原型物件,同時擁有constructor屬性指到其建構函數
 var mycard = NameCard('KD', '093456789');  var youcard = NameCard('XD', '0912345678');

由instanceof運算子可以檢查物件是屬於哪個建構函數所建立的物件

 if(myCard instanceof NameCard) {    console.log('Yes!!'); }

原型物件、建構函數和繼承

在JS中,每個物件都會繼承一整串上層原型物件的繼承鏈,往上繼承到Object.prototype基底原型物件為止(所有物件的老祖宗)

當JS在執行物件的屬性或方法時會先看一下現有的物件是否有具備,若沒有則往上一層原型物件看,沒有則再往上,直到Object.prototype為止

當變更或擴充原型物件時,繼承此原型物件的所有物件都可以存取新增屬性或方法。變更下一層不會影響上層。若建立的是同名屬性或方法可以覆蓋上一層的同名屬性方法


prototype 物件繼承



JS 物件繼承可以將一個物件擴充成其他物件,亦即不但可以使用物件作為原型來建立其他物件,還可以擴充物件的屬性和方法



按這看結果
參考文章:JavaScript 物件導向介紹

JS private 私有成員


私有成員代表外界無法直接取用必須透過物件方法來存取私有屬性,在JS使用closure來實作





按這看結果

靜態屬性、方法

靜態屬性和方法為其他物件導向語言中類別(class)的屬性和方法。在JS 中則是直接對建構函數新增靜態屬性和方法,不需要實例化才能存取,且靜態類別不能實現化 (Instantiated)

 NameCard.belong = 'KD'; NameCard.now = function(){   return new Data(); };
console.log( NameCard.belong +  NameCard.now);
參考文章:

命名空間


用於避免變數或函數因名稱相同而產生問題。在JS 中最常使用Function Wrapper來實作命名空間,在各大Library函式庫都可以看到使用。其中回傳的物件為使用介面的相關方法,透過前面提到的自調用函數可以建立獨立的命名空間,避免衝突

 var App = App || {}; (function(a){    var num = 1;    a.add = function(){ return num++ };   })(App);


JS 內建物件

JS 內建物件依照建立方式的不同可以分為使用變數宣告的隱性物件和使用new運算子建立的顯性物件

隱性物件(Implicit)
  var str = 'KD';
隱性物件雖然支援String物件方法但不支援prototype屬性

顯性物件(Explicit)
 var str = new String('KD');

JS 內建物件


JS共有11種內建物件,其中String、Array、Date、Math、Error和RegExp物件較常使用特別說明,其餘物件以下簡單說明並可以參考文件



JS 內建物件

Boolean
Boolean物件是一種資料型態,提供建構函數可以建立boolean資料型別的物件
 boolean = new Boolean();

Function
如之前說明,這是其中一種建立函數的方法,但不建議使用
 var add = new Function("a", "b", "return a + b;");

Object
如果之前所提,是所有物件的祖宗。一種建立物件方式

JS 內建物件


Global
Global物件不能使用new運算子建立,是在腳本語言初始後會自動建立,直接使用即可,其中Global物件主要擁有兩個屬性:Infinity、NaN

Number
類似Boolean一樣為基本資料型別另一種使用方式
 var num = new Number(value);
通常我們是為了使用toString()轉換字串而使用

string 物件


如前所述,字串的使用有兩種方式,除了基本資料型別外,也可以使用new 物件的方式建立,兩者都可以使用字串物件的屬性和方法,唯基本資料型別無法使用prototype屬性

 var obj1 = 'JS'; var obj2 = new String('HI JS');

STRING 物件


 HTML 標籤格式編排
anchor() 
回傳<a>String</a>標籤

字串長度和大小寫
length屬性可以取得字串長度
toLowerCase()方法可以將英文大寫轉小寫
toUpperCase()方法可以將英文小寫轉大寫

按這看結果

STRING 物件

取得字串指定字元
charAt(index)方法可以取得index位置的字元
charCodeAt(index)可以取得index位置的Unicode統一字碼

字串搜尋
indexOf(string, index)傳回第一次搜尋到字串的index,未找到傳回-1,傳入字串為欲搜尋字串,index 為開始位置
lastIndexOf(string)如同上一方法,不過是從尾部反向搜尋
match(string)如同第一種方式,但傳回找到字串,無則傳null
search(string)與indexOf功能類似

按這看結果

STRING 物件


子字串的處理
replace(string1, string2)將找到的string1子字串取代為string2
split(string)使用參數string作為分割,並回傳分割後Array物件
substr(index, length)從index開始取出length個字元
substring(index1, index2)取出index1到index2(不含)間子字串
concat(string)將string新增到string物件字串之後


按這看結果

array 物件

array(陣列)為程式語言常使用的儲存用資料結構,但在JS中並未有資料型別,事實上每個array元素就是Array物件的屬性

JS 的一維陣列
陣列的index是從0開始
 var nameA = new Array(3); //宣告有三個元素的陣列 nameA[0] = 'KD'; nameA[1] = 'XD'; nameA[2] = 'XDD'; var nameB = [];
 nameB[0] = 'KD'; nameB[1] = 'XD'; nameB[2] = 'XDD';

ARRAY 物件


也可以在建立物件時建立元素值
 var num = new Array(100, 22, 34);

走訪一維陣列( 印出所有元素)
 for(var i = 0; i < 3; i++){  //建議條件不要寫死,可以3可以改使用num.length     document.write(num[i]); }


ARRAY 物件


Array物件屬性和方法
length可以取得陣列長度

join()將陣列元素用"逗號," 串成一個字串
reverse()將陣列元素反轉
sort()將陣列元素進行排序
concat(array)將參數中的陣列合併到目前陣列

按這看結果

ARRAY 物件


在JS 中並不能直接建立二維或多維陣列,所以需要透過於陣列元素中再建立陣列物件來建立多為陣列

 var users = new Array(2);
for(var i = 0; i < 2; i++){
  users[i] = new Array(2);
}

按這看結果

date 物件


透過Date物件取得電腦日期和時間
getDate()傳回日期值,
getDay()傳回星期值,0-6(星期日開始)
getMonth()傳回月份值,0-11
getFullYear()傳回完整年份
getYear()傳回年份,注意在1900-1999傳回後兩碼
getHours()傳回小時,0-23
getMinutes()傳回分,0-59
getSeconds()傳回秒,0-59
getMilliseconds()傳回千分之一秒,0-999
getTime()傳回自1/1/1970年開始的秒數,以千分之一秒單位

DATE 物件


設定Date物件的日期和時間,非改變電腦時間
setDate()設定日期值,
setDay()設定星期值,0-6(星期日開始)
setMonth()設定月份值,0-11
setFullYear()設定完整年份
setYear()設定年份,注意在1900-1999傳回後兩碼
setHours()設定小時,0-23
setMinutes()設定分,0-59
setSeconds()設定秒,0-59
setMilliseconds()設定千分之一秒,0-999
setTime()設定自1/1/1970年開始的秒數,以千分之一秒單位

DATE 物件


日期和時間的轉換
toLocaleString()傳回將GMT轉換成本地時間的字串

math 物件


在JS 的Math物件中擁有數學常數和函數的屬性和方法,Math物件和Global物件一樣為腳本語言引擎內建,不需要new運算子自己就會建立,故可以直接使用屬性和方法

Math物件常用屬性
E = 自然數e = 2.71828...
LN2 = ln2
LOG10e = loge
PI = 圓周率
SQRT2 = 根號2

MATH 物件

Math物件的亂數最大和最小值
max(value1, value2) 傳回兩個參數中的最大值
min(value1, value2) 傳回兩個參數中的最小值
random() 傳回亂數值
round(value) 將參數四捨五入後傳回

Math物件的數學方法
abs()傳回絕對值
log()傳會自然對數
sqrt()傳回平方根
pow()傳回次方
exp()自然對數

error 物件


我們在寫程式時常常會有不預期的錯誤,這時候就需要有錯誤處理的機制來幫我們做處理,否則程式出錯後可能會當機或是發生不可預期的錯誤,在JS中Error物件會儲存執行時發生錯誤的資訊,發生錯誤時會自動建立

Error物件屬性
number錯誤碼,為32-bit值,其中後16bit才是真正錯誤碼
message錯誤訊息字串
description同message為說明錯誤的字串

ERROR 物件


基本錯誤處理架構

 try {   //此區塊內為需要例外處理的程式碼 } catch(e) {   //如果try區塊發生錯誤會執行此一區塊,並傳入e參數(Error物件),可由e取得錯誤訊息 } finally {  //這是選擇性區域,是不管錯誤是否發生都會執行的區塊 }
按這看結果

regexp 物件


RegExp是JS用來使用正規表示法的物件,用以比對其它字串是法符合範本字串,以便進一步對字串進行操作,功能強大

JS   RegExp物件使用

exec(string)檢查參數string字串是否符合正規運算是子字串,符合回傳字串陣列
test(string)檢查參數string字串是否符合正規運算是子字串,符合回傳true不符合回傳false

物件共用屬性及方法


JS內建物件有共用屬性和方法,由所有物件的老祖宗Object.prototype原型物件的屬性和方法繼承而來,這些屬性和方法可以使用於大部分內建物件

共用屬性(以下除了Math和Global外的內建物件都具備)
prototype 參考到Prototype原型物件
constructor 取得建立物件的建構函數名稱



物件共用屬性及方法

共用方法
hasOwnProperty()可以檢查物件是否直接擁有參數的屬性,回傳布林值,如為原型繼承則非直接擁有會回傳false

isPrototypeOf()
可以檢查參數物件是否存在於其它原型物件的繼承鏈中,回傳布林值

toString()
輸出物件的內容字串

valueOf()
可以傳回物件數值

練習五(SAMPLE 3-5)


運用物件建立"名片夾"物件,需有擁有人、電話、地址還有印名片的屬性(印擁有人、電話、地址),完成後由"名片"物件繼承"名片夾"物件並新增自己的姓名、email屬性值和qrCode方法(印出姓名、email)並印出繼承而來的"名片夾"方法

Hint : 使用建構函數和portotype

練習六(SAMPLE 3-6)


從電腦中找出三張圖片,運用內建物件的方法建立一個隨機亂數的圖片顯示器

Hint : 使用Math物件和Array物件







基礎 BOM & DOM

廣義 Javascript






http://www.w3school.com.cn/

物件模型基礎


所謂的物件模型(Object Model)對於HTML網頁來說,是一種規範如何存取HTML元素、CSS樣式和JS程式碼的一種機制,可以將HTML元素、CSS樣式和JS程式碼視為物件

bom


BOM就是Browser Object Model - 中文叫做瀏覽器物件模型。 windows物件就是瀏覽器最頂層的一個物件。是Javascript與瀏覽器溝通的橋樑,讓Javascript可以透過BOM對瀏覽器進行各種操作,也是JS程式設計的核心之一

BOM物件的使用可讓我們操作包含開啟/關閉視窗,改變視窗大小,計時器與取得網址等, 瀏覽器物件模型在Javascript中十分常用,為十分重要的觀念

BOM & DOM 

http://img.my.csdn.net/

BOM


 Window 物件: 瀏覽器物件模型有著階層性的架構,最上層便是Window物件,代表著瀏覽器視窗本身,若是視窗中含有框架(Frame),則每個框架都還有屬於自己的window物件。 所有的BOM都可透過window來存取。window物件的使用不須經過宣告,可以直接使用。事實上,在JS中,所有的全域變數、函式、物件,其實都是屬於window物件


Window物件


Window物件下有History、Navigator、Screen、Location、Document和Event物件

Window物件代表的是瀏覽器的一頁分頁,我們可以透過JS存取Window物件的屬性

defaultStatus存取瀏覽器下方狀態列的預設文字
status存取瀏覽器狀態列的訊息文字

setTimeout( )


setTimeout( ) 是設定一個指定等候時間 (千分之一秒為單位 ),時間到了,瀏覽器就會執行一個指定的函數,使用完記得用clearTimeout()停止setTimeout()方法

第一個參數為要執行的method 或 function,第二個參數為等候的時間 
 function helloWord(){   console.log("Hello");  setTimeout("helloWord()", 1000) ;
var id = setTimeout("alert('Hello')", 1000) ;  clearTimeout(id);

setInterval()


setInterval() 每隔「時間長度」所指定的時間(以千分之一秒為單位)後,瀏覽器就會去執行指定函數 ,和setTimeout不同是會其會每隔段時間執行一次,同樣可用clearInterval(id)清除

第一個參數為要執行的method 或 function,第二個參數為每隔的時間

  var id = setInterval("showTime()", 1000); //每一秒更新一次  clearInterval(id) //傳入清除欲id

視窗開關


Window物件提供open()方法可以用來開啟、關閉新分頁

 winId = window.open('欲開啟的網頁', '視窗名稱') ; winId.close(); //關閉視窗

交談窗


亦即我們之前有介紹的三種和使用互動的視窗:

alert(message) 警告訊息

confirm(message) 確認視窗,回傳true or false

prompt(msg, default value) 輸入文字視窗,可用變數接回傳值,未輸入回傳null

視窗內容的捲動


Window物件提供三種方式可以捲動視窗

scroll(x, y)移動指定位置
scrollTo(x, y)移動到指定位置
scrollBy(offsetx, offsety)從目前視窗位置移動到參數位移量

Screen和navigator物件

Window物件中的screen子物件可以取得螢幕解析度和色彩數,Navigator物件可以取得瀏覽器和系統資源相關資訊

Screen物件屬性
height螢幕解析度高度
width螢幕解析度寬度
availHeight螢幕解析度排除工具列的高度
availWidth螢幕解析度排除工具列的寬度
colorDepth螢幕色彩數

Navigator物件屬性
appName傳回瀏覽器名稱

history和location物件

Window物件中的History子物件可以取得瀏覽歷史紀錄,Location物件可以取得URL網址資訊

History物件
length傳回物件歷史記錄數
back()上一頁
forward()下一頁
go(num)移動第num頁

Location物件
window.location.href 為URL網址,可以用於轉址
reload() 如同重新整理
replace(url) 轉到參數網址,但會取代歷史紀錄(無法上一頁)

練習六(SAMPLE 3-6)


參考小鴨畢業倒數,製作一倒數計時器(2014/6/7)




DOM


文件物件模型(Document Object Model,DOM)是給 HTML 與 XML 文件使用的一組 API。

簡單的說就是將文件(文件可以想成單一網頁)物件化,以便提供一套通用存取的方式來處理文件內容。DOM提供HTML網頁一種存取的方式,可以將HTML元素轉換成一棵節點樹,每一個標籤和文字內容是為一個節點,讓我們可以走訪節點(Nodes)來存取HTML元素 

一般DOM分為 DOM Core(針對XML和HTML)和DOM HTML

DOM 的優點



提供跨平台和程式語言的程式介面

支援HTML和XML文件

支援多種程式語言存取(JS、Java、PHP)

DOM


 <!doctype html>
 <html lang="en">
 <head>
	<meta charset="UTF-8">
	<title>Document</title>
 </head>
 <body>
	
 </body>
 </html>

dom


http://www.w3schools.com/js/pic_htmltree.gif

搭配dom api選取元素

取得指定唯一元素情況
根據ID名稱選取 
document.getElementById(elementId)
有很多元素符合,回傳的是NodeList物件集合,使用item()存取
(注意Element's')
根據元素名稱選取
document.getElementsByTagName(tagName)
根據名稱選取 
document.getElementsByName(name) 
根據Class名稱選取 
document.getElementsByClassName(classname) 
按這看結果

搭配DOM API選取元素


nodeName和tagName可以取得元素標籤名稱(為大寫)
length可以取得符合元素的個數(NodeList長度)

 var a = document.getElementById('google');

 document.write(a.nodeName + '<br>');


 document.write(a.tagName);

HTML5 : css選擇器


Document物件也提供使用CSS選擇器來選取HTML元素

document.querySelectorAll()方法
 Document物件的querySelectorAll()方法可以取得HTML的節點陣列或清單,為一個NodeList物件,類似getElementsByClass等,需要用陣列存取方式存取

document.querySelector()方法
只會回傳一個符合的元素,沒有就回傳null

按這看結果

元素物件 element 的屬性 

InnerHTML
存取元素的子標籤和內容但不包含標籤
OuterHTML
存取元素的子標籤和內容包含標籤
innerText
取純文字內容,但會保留HTML格式
textContent
取純文字內容,不含任何標籤

html ELEMENT 的尺寸和位置 


DOM 有提供節點物件屬性來存取HTML標籤位置和尺寸

offsetLeft 節點物件距離左方邊界的距離
offsetTop 節點物件距離上方邊界的距離
offsetHeight 節點物件的高
offsetWidth 節點物件的寬
offsetParent 取得節點物件的上一層物件

scrollInto()若視窗看不到此元素,就自動捲動視窗顯示此元素

走訪DOM元素

除了前述所用的方式存取DOM元素外,也可以用相對位置方式存取DOM樹上的節點或元素

DOM的節點屬性
firstChild 傳回第一個子節點
lastChild 傳回最後的子節點
parentChild 傳回父節點
nextSibling 傳回下一個兄弟節點的物件
previousSibling 傳回前一個兄弟節點的物件
nodeName 傳回HTML的名稱,為大寫
nodeType 傳回節點種類(1.標籤 2.屬性 3.文字節點)
specified 傳回是否HTML 標籤擁有布林值

走訪DOM元素


DOM的瀏覽元素屬性
對於DOM API來說,我們在乎的事實上是DOM上的元素節點,然而前述的存取方式,會存取到其他文字與註解節點,若只需要存取元素節點,可以使用以下屬性:

firstElementChild 傳回第一個子元素
lastElementChild 傳回最後一個子元素
nextElementSibling 傳回下一個兄弟元素的物件
previousElementSibling 傳回前一個兄弟元素的物件
childElementCount 子元素的個數,相當於是children.length

走訪DOM元素


DOM的存取屬性
data存取文字節點內容,其他種類節點回傳undefined
nodeValue存取文字節點內容,其他種類節點回傳null

DOM的集合物件
DOM的集合物件可以取得下一層子節點和節點屬性
attributes 節點屬性的集合物件,可以直接用名稱存取
childNodes 子節點的集合物件,為陣列物件
children 子元素的集合物件,不包含文字和註解節點的子節點,亦為一陣列

瀏覽dom節點


一般來說,我們在HTML元素中選擇特定元素後,通常我們還需要再找出DOM元素中的相關節點,如 : 父、子或兄弟節點
特別注意在 DOM節點樹中,HTML 標籤是一節點,裡面的標籤內容則是其子節點

瀏覽父節點
 var node = document.getElementById('papa'); var nodeParent = node.parentNode; document.write(nodeParent.nodeName);

瀏覽DOM節點


瀏覽兄弟節點
 var node = document.getElementById('bro');  var nodeBro = node.previousSibling; document.write(nodeBro.firstChild.data);


按這看結果

瀏覽HTML元素

事實上DOM API支援元素基礎的節點瀏覽,可以讓我們專注在HTML網頁元素的節點上,忽略文字和註解節點。基本上parentNode屬性一定取得的是元素節點

瀏覽第一元素
 var node = document.getElementById('bro');  var nodeFirst = node.firstElementChild; document.write(nodeFirst.textContent);
瀏覽兄弟元素
 var node = document.getElementById('bro');  var nodeBro = node.previousElementSibling; document.write(nodeBro.firstChild.data);

存取html屬性


在取得HTML網頁的元素後,我們還可以取得其屬性

getAttribute(attribute) 取得傳入參數attribute屬性的屬性值

setAttribute(attribute, value) 將傳入參數attribute設為value值

removeAttribute(attribute) 刪除傳入參數的attribute屬性

 var a = document.getElementById('hyper'); document.write(a.src);

html5 : 自定DATA - * 屬性


HTML5可以讓使用者自訂屬性值,方便可以記錄一些屬性

 <div data-num="1">HTML</div> <div data-num="2">CSS</div>

更改CSS樣式

CSS樣式在DOM API中可以對應到Style屬性,讓我們可以用JS去動態更改CSS樣式
 部分改變 document.getElementById('id').className= '動態加className'; document.getElementById('id').style.cssText = 'color: red'; document.getElementById('id').style.backgroundColor= '#003366'
全局改變(動態加入外部引入css檔) <button on click="javascript:document.getElementById('css').href = 'ie.css'">點我改變樣式</button>

按這看結果

更改css樣式


常用的Style屬性如下, CSS樣式屬性和Style物件屬性差異在於CSS樣式屬性中的 " - " 在Style物件屬性會刪除後面字母轉大寫

CSS樣式屬性 / Style物件屬性
color / color
font-size / fontSize
font-family / fontFamily
background-color / backgroundColor
background-image / backgroundImage
display / display

取出input值


透過value屬性可以取得所選取的input標籤的值,但記得取出為字串,若希望進行數字運算,記得要使用parseInt()或是parseFloat()進行轉換

 var num = document.getElementById('id').value

節點元素的新增


透過JS 可以針對DOM文件樹結構元素進行動態操作,包括動態建立元素,加入子元素或是移除指定元素等操作

新增節點元素 createElement('element name')
 document.getElementById('son'); var ele = document.createElement('div');



節點元素的附加


插入元素 
欲插入其後面的元素 . appendChild(新增的元素) 

欲插入元素所在的容器 . insertBefore(新增元素,  相對節點)

dad.appendChild(ele);

ele.className = "css";

dad.insertBefore(ele, son);

按這看結果

節點元素的刪除


移除元素 removeChild()

先取得欲移除元素的父元素,便可以透過removeChild(),移除其子元素


按這看結果

動態載入 JS


我們也可以透過DOM的操作來動態載入JaavaScript,讓程式更具彈性

 var head = document.getElementByTagName('HEAD')[0]; var js = document.createElement('script'); js.src = 'dynamic.js'; head.appendChild(js);

練習七(SAMPLE 3-7)


使用DOM API 製作一簡易計算機(含加減乘除)

練習八(SAMPLE 3-8)


使用監聽 click 事件來監聽按鈕,當按鈕按下時,讓原來黑色h1文字變成紅色達到變換css效果







事件處理 Event Handle

事件


事件處理(Event Handlers)是JS非常重要的功能,事件是用來處理JS 與HTML之間的互動、建立動畫效果並和使用者互動

事件處理簡單說就是當一個事件發生時(網頁載入、按下右鍵等),程式會相對應做出怎樣的處理。例如:當使用者按下按鈕時會觸發click的事件(事件發生)並讓按鈕變成紅色(處理事件),這就是一種事件處理機制

事件處理機制是JS中最重要的功能之一

事件


事件種類(Event Type)
又稱事件名稱(Event Name),為一個字串,說明發生了什麼事件,例如:click(點擊)、mousemove(滑鼠滑過)

事件處理(Event Handlers)
係指處理事件的函數名稱,當事件發生時要呼叫哪個函數進行處理

  <button onclick="show()">Click Me!</button> 

基本事件處理


 <script>    function changetext(id) { id.innerHTML="Ooops!"; }  </script> // 改變<h1>文字內容  <h1 onclick="changetext(this)">Click on this text!</h1>   //注意這邊的this指的是被點擊的元素


參考文件: JS 事件的處理

事件處理過程


當事件發生時會,整個DOM架構中的節點都有機會來處理此事件,不同瀏覽器的事件處理模型上並不相同,因此有不同的處理過程,我們稱為『事件傳播(Event Propagation)』,它會影響HTML元素處理事件的順序

一般可分為事件補抓模型(Event Capturing)和事件氣泡模型(Event Bubbling)

建立事件處理


基本上JS建立事件處理有三種方式

1. HTML屬性:在HTML屬性中指定JS事件處理

2. JS屬性:在物件屬性中設定JS事件處理

3. 呼叫DOM方法:使用addEventListener()方法處理事件

 HTML屬性指定事件


只要在屬性中指定事件處理即可以使用(事件前面加上on),但當應用程式越來越複雜時不好管理,不建議使用

 <h1 onclick="show();"> Hi JS </h1>

JS屬性指定事件


透過在選取的DOM元素增加事件屬性,當複雜時,不方便管理,同樣不建議使用

  var btn = document.getElementById('id');  btn.onclick = eventHandler; //

註冊監聽事件


新增監聽函數(第三個參數false為使用氣泡事件)
 [選元素].addEventListener("event", Handler, 是否氣泡處理); 

刪除監聽函數
 [選元素].removeEventListener("event", Handler, 是否氣泡);
 
(*註冊監聽事件為建議寫法,同一事件可以註冊多個處理器,第三個參數flase為氣泡處理)

事件物件


當事件觸發時會產生一個事件物件(Event Object),這個物件記錄事件觸發的一些資料並傳入處理器方便做進一步處理,例如 : 位置、標籤、事件名稱

 function show(event) {    console.log(event.target); } <button onclick="show();">Clik</button>

事件物件

常用屬性如下:

bubbles 是否是氣泡事件
cancelable 預設行為是否可以取消
currentTarget 可以取得事件處理的元素物件
eventPhase 傳回事件處理階段  
1.  事件捕捉 2. 觸發事件 3. 氣泡

target 觸發事件的元素
type 觸發事件的名稱
clientX,  clientY 取得滑鼠點擊時游標位置

取消預設行為


有些HTML在觸發事件後會有預設行為,例如超連結會打開視窗,連到新網站,透過event.preventDefault()這個方法可以取消事件的預設行為(如,按下超連結預設行為為連到新網頁)


取消事件傳遞


event.stopPropagation()可以取消事件捕捉或是氣泡事件傳遞

若使用return flase;,則既取消事件傳遞也取消預設行為




 事件捕捉




http://catcode.com/domcontent/events/

事件捕捉


當事件發生時,首先是由Document物件開始(目前各瀏覽器實作上是由Window物件開始),然後是最大範圍的<html>元素有機會回應此事件,再來是下一層的<body>,依序往下

原本是W3C順序是先執行事件捕捉再執行氣泡處理,但就瀏覽器實作不多,目前實務上多用氣泡事件處理

氣泡事件




http://catcode.com/domcontent/events/

氣泡事件


和事件捕捉的順序相反,當事件發生時,這個事件會元素的父元素向上傳播。首先是觸發事件的元素有機會處理事件,然後像氣泡在水中一樣浮起來,往上到更上一層的元素。亦即可以在最上面設計事件處理,下層更元素發生事件都可以用這個回應


動態事件註冊


除了網頁中現存的元素外,事件亦可以註冊在動態產生的元素上



事件處理的this


之前在講解object時,有提到this關鍵字會指到該物件。在事件處理的callback function中,this則是會指到觸發事件的元素,這點要特別注意



搭配dom api選取元素


根據元素名稱選取
document . getElementsByTagName(tagName)
根據Class名稱選取
document . getElementByClassName(classname)
根據ID名稱選取
document . getElementById(elementId)



window 事件


window物件支援數個事件,並於特定狀態下觸發

常見事件:
load 網頁完全下載完成後觸發(含外部資源)
unload 離開網頁觸發
DOMContentLoaded 網頁文件(DOM)載入完成(不含其他外部資源),注意和load的比較
resize 調整視窗大小
scroll 捲動視窗

滑鼠事件


滑鼠按一下:相關的「事件」有 mousedown,mouseup,click 
滑鼠連按二下 :相關的「事件」有mousedown,mouseup,click,dblclick 
滑鼠移動:相關的事件為 mouseover,mousemove,mouseout 
滑鼠拖曳:相關的事件為 mousedown , dragstart ,( mousemove ),dragend

參考文件:滑鼠事件

鍵盤事件



keydown 按下鍵盤
keypress 在按下與放開之間
keyup 放開鍵盤按鍵

* 可以用event.keyCode取得鍵入的Unicode對應值

HTML5 : 拖曳事件



dragstart開始拖曳操作時被觸發
dragover拖曳經過目標元素時被觸發
drop拖曳並且置放至目標元素時被觸發



HTML5 : input事件


input事件在HTML5中導入,可以取得input 中使用者的輸入,與keypress效果相同,keypress事件於DOM Level3中被取消,建議使用input事件

練習九(SAMPLE 3-9)


使用三種監聽事件方式來監聽按鈕,當按鈕按兩下時,讓原來黑色h1文字變成紅色達到變換css效果

練習十(SAMPLE 3-10)


使用事件處理的機制,設計一個有輸入框、送出鈕,可以計算還剩多少可以輸入字元的網頁(類似Twitter只能輸入140字元)。當使用按送出後,輸入文字會出現在網頁上


Hint : 監聽鍵盤事件

練習 十一(SAMPLE 3-11)


製作點選標籤切換內容的網頁選單(請參考Yahoo奇摩首頁)


練習 十二(SAMPLE 3-12)

運用事件處理和新增刪除DOM的技巧,製作出一個可以新增刪除的代辦事項清單


Hint : click事件、this、createElement()和appendChild() 

JS 那些框架和函式庫們








Q & A

JavaScript 行為互動

By 張凱迪(KD Chang)

JavaScript 行為互動

隨著智慧型裝置的起飛,現在幾乎已是人手一支智慧型手機,根據統計今年全球智慧型手機出貨量已達10億支,由於大量的需求,開發Mobile Web也成為原生(Native App)外另一種較低成本的選擇。因此本課程將著重在網頁開發基礎介紹以及如何運用HTML5/CSS3/JavaScript(jQuery)來開發Mobile Web App。希望讓沒有基礎(或有基礎)的學員能在學習完課程後具備自學能力未來能持續進修,進而開發出搭配Facebook API、Google Map API的Mobile Web App。 課程網站:http://kdchang.cc/mobile-web-dev/

  • 5,969
Loading comments...

More from 張凱迪(KD Chang)