JavaScript Note

本網頁以打造無障礙閱讀為目標,可以用任何瀏覽器來觀看本網頁


簡介

瀏覽器的支援差異

JavaScript的撰寫在不同瀏覽器上的表現都有些許差異, 一般而言, IE對於錯誤的程式碼容忍度較高, Mozilla則較為嚴謹。

在指定瀏覽器上的表單物件時,IE可不指定document,而 mozilla則否, 例如mozilla需指定為 document.forms.text.value , 而IE可簡寫為 forms.text.value ,但還好我們可以先用一個變數來取代指定的麻煩, 如

var s="document.forms";
s.text.value=....... ;

JavaScript的區段宣告

舊的語法

行內宣告
<script language="JavaScript">
<!--
 script
//-->
</script>
預防瀏覽器不支援 <!-- -->
不讓-->成為JavaScript的一部份,需加入//
宣告依版本而有不同
<script language="JavaScript">
<script language="JavaScript1.1">
<script language="JavaScript1.2">
<script language="JavaScript1.3">
<script language="JavaScript1.4">
<script language="JavaScript1.5">
<script language="JScript">
嵌入宣告
<script language="JavaScript" src="外部的.js檔案URL">
</script>

新的語法

行內宣告
<script type="text/javascript">
<!--
 script
//-->
</script>
預防瀏覽器不支援 <!-- -->
不讓-->成為JavaScript的一部份,需加入//

<script type="text/javascript">

</script>

嵌入宣告
<script type="text/javascript" src="外部的.js檔案URL">
</script>

宣告不支援JavaScript的語法

為了無障礙網頁的考量,請特別針對不支援JavaScript的瀏覽器撰寫讓他們該如何看到內容的提示。

<noscript>本網頁使用了JavaScript,請點選文字版本來觀看內容 </noscript>

JavaScript的執行方式

有二種方式可以執行JavaScript

  1. 網頁直接執行:JavaScript的程式碼置於任何區段,要配合宣告。
  2. 事件驅動執行: 配合body區段的事件(event),JavaScript的程式碼可置於
    1. 事件的參數中 (建議少量的code時) ,不需宣告 。
    2. head 區段或body區段中,要配合宣告,但建議放在head區段中以方便管理。

網頁直接執行JavaScript

JavaScript的程式碼置於head 區段顯示文字
javascript程式碼 瀏覽器畫面
<html>
<head>

<script type="text/javascript">
document.write("Hello World!")
</script>

</head>
</html>

Hello World!

JavaScript的程式碼置於body 區段顯示html
javascript程式碼 瀏覽器畫面
<html>
<body>

<script type="text/javascript">
document.write("<h6>Hello World!</h6>")
</script>

</body>
</html>

Hello World!

事件驅動執行JavaScript

配合事件驅動,JavaScript的程式碼置head區段
javascript程式碼 瀏覽器畫面
<html>
<head>
<script type="text/javascript">
function message() {
alert("This alert box was called with the onload event")
}
</script>
</head>

<body onload="message()">

</body>
</html>

JavaScript事件驅動例圖1

配合事件驅動,少量的JavaScript直接放在事件的參數中
javascript程式碼 瀏覽器畫面
<html>
<head>
</head>

<body>
<input name="S1" type="button" onclick="document.bgColor='red'" value="紅色背景" />
<input name="S2" type="button" onclick="document.bgColor='yellow'" value="黃色背景" />
<input name="S3" type="button" onclick="document.bgColor='green'" value="綠色背景" />
<input name="S4" type="button" onclick="document.bgColor='white'" value="白色背景" />
</body>
</html>

JavaScript事件驅動例圖2

資料型態(Data Type)

JavaScript無法明確地宣告資料型態。在許多情況下,JavaScript 會在需要時自動執行轉換。例如,如果在文字 (字串) 所組成的項目中加入一個數字,這個數字就會轉換成文字。

原生資料型態(Primitive Data Type)

字串(string)

字串值是一串由 0 個或 0 個以上的 Unicode 字元(字母,小數點和標點符號)結合而成。
雙括號可以包含在括在單括號的字串裡,而單括號也可以包含在括在雙括號的字串裡。
  s="Happy am I; from care I'm free!";
s='"Avast, ye lubbers!" roared the technician.';
s="42";
s='c';
s="";

數字(number)

JavaScript 中的整數和浮點值並無明顯區分;兩者都可以作為 JavaScript 數字 (JavaScript 內部把所有的數字表示成浮點數)。

特殊數值
NaN:用不正確的資料,像字串或未定義的值執行數學運算時,就會使用這個數值
Positive Infinity:當正數大到無法顯示在JavaScript中時,就會使用這個數值
Negative Infinity:當負數大到無法顯示在JavaScript中時,就會使用這個數值
Positive and Negative 0:JavaScript 區分正 0 和負 0。

  .0001; 0.0001; 1e-4; 1.0e-4; 0378; 0377; 0Xff

布林(boolean)

布林資料型態卻只能有 2 種值,那就是 true 和 false。
  flag=true; flag=false; flag = (x == 2000);

特殊資料型態

null 和 undefined 最大的不同是, null 就好比數字 0,而 undefined 好比特殊值 NaN (非數字)。
null 值和 undefined 值經比較後一律相等。

null

一個包含null的變數,就是"無值" 或 "無物件"。換句話說,它是無效的數字、字串、布林值、陣列、或物件。您可以指定變數的值為null以刪除這個變數的內容,但又不刪掉這個變數。
JavaScript 的null 資料型態只有一個值:null。null 關鍵字不能拿來作為一個函數或變數的名稱。
 

undefined

遇到下列情況,會傳回未定義的值。也就是使用:
  1. 不存在的物件屬性。
  2. 已經宣告,但未指定值的變數。
要檢測一個變數是否存在,可以藉此檢查這個變數的型態是否為 "undefined"。
 

if (typeof(x) == "undefined") .................  //檢查變數 x 是否存在

var currentCount;
var finalCount = 1 * currentCount;   // finalCount 的值是 NaN,因為 currentCount 為Undefined。

組合 (引用) 資料型態

物件(object)

  • 陣列中的元素可存放各種資料型態
  • 陣列的註標除了數字外,也可存放文字,這種陣列稱之為關聯式陣列(associative array)
  • 陣列就是物件,物件就是陣列,可用typeof()來觀看
 

var a="abc"; //雙引號的字串
var b='def'; //單引號的字串
var c=123; //數字
var d=[123,"abc",a,b]; //使用中括弧定義陣列,陣列中可存放各種資料型態
var e=new Array(123,"abc",a,c); //使用 Array 建構子定義陣列,陣列中可存放各種資料型態

var f={"peter":123,"john":456,"jane":789};  //使用大括弧定義一個關聯式陣列
var g=new Object;  //定義一個物件
g.peter=123;  //利用「物件.屬性」給值
g.john=456;  
g["jane"]=789;  //也可用陣列的方式給值

alert(f["peter"]);
alert(f.john);  //對陣列以「物件.屬性」的方式取值
alert(g["peter"]);  //對物件以陣列的方式取值
alert(g.john);

函數(function)

JavaScript可將函數當成資料來傳遞
   

資料型態轉換

JavaScript的語言型態並不嚴謹,這表示您不需要非常明確地宣告變數的資料型態,是一種弱型態(weakly typed)的語言,它會自動根據內容來調整資料型態,所以也稱之為動態類型(Dynamically typed)的語言。

自動轉換原則

  1. 運算式中有數字的字串且使用(+),運算式視為字串
  2. 運算式中有數字的字串且使用(-*/....)其他運算子,運算式視為數值
  3. null乘以任何數皆為0
  4. undefined乘以任何數皆為NaN(Not a Number)

強制轉換

  1. 將字串強迫轉為數值:eval("字串")
  2. 將字串強迫轉為指定底數的數值:parseInt("字串",[底數])
  3. 將字串強迫轉為浮點數:parseFloat("字串")

變數(Variable)

宣告

類型

  區域變數 var 變數名;
  全域變數 變數名;

方式

  單一宣告 var name;
  多變數同時宣告 var name,sex;
  宣告時並賦予初值,否則其值為undefined var name="peter",sex="女";
  雖然變數型態不同,宣告方式都一樣 var num=30,flag=true;

命名/識別子 (identifier)

提供作為命名變數,命名函數,提供迴圈的標籤。

區分大小寫

var x; var X

第一個字元必須是ASCII字母 (大小寫皆可)、底線 (_)字元
注意數字不能拿來當第一個字元
後面的字元必須是字母、數字、或底線

var _x; var x_1

複合字的第一個字建議要大寫

var MyFriend;

變數名稱不能為保留字

 

函數(Function)

JavaScript的函數有3種指定方式

  1. 一般的函數定義方式
  2. 使用函數文字
  3. 使用Function()建構子

看下面的範例會更清楚

<script type="text/javascript">
function fun1(n1,n2,op) { // 一般的函數定義方式
return eval("n1"+op+"n2");
}
var fun2 = function(n1,n2,op) {return eval("n1"+op+"n2")}; // 使用函數文字
var fun3 = new Function("n1","n2","op","return eval('n1'+op+'n2')"); // 使用Function()建構子
</script>

呼叫這3種函數的方法都一樣,範例如下 ,可以看出資料型態都是函數

<script type="text/javascript">
document.write("fun1 = "+fun1(6,4,"-")+" , fun1 is a "+typeof(fun1)+"<br />"); // fun1 = 2 , fun1 is a function
document.write("fun2 = "+fun2(6,4,"+")+" , fun2 is a "+typeof(fun2)+"<br />"); // fun1 = 10 , fun2 is a function
document.write("fun3 = "+fun3(6,4,"*")+" , fun3 is a "+typeof(fun3)+"<br />"); // fun1 = 24 , fun3 is a function
</script>

JavaScript的這種將函數視為資料的能力,可以讓我們使用其它函數構成所需要的函數文字,動態的產生所需要的函數,如同LISP語言中的 lambda 。筆者目前尚未找到這種函數文字的殺手級應用 ,或許讀者有資料可以提供給我?

以<a>....</a>標籤連結至javascript的函數有2種方式

文字瀏覽器不可用(假連結)

<a href='javascript:show_url("argument")' >連結至函數</a>

文字瀏覽器可用

<a href="#" onclick='show_url("argument");return false;' >連結至函數</a>

物件模型DOM

Window物件

屬性

由於windows物件是瀏覽器的最上層物件,因此在撰寫script可省略window描述
屬性名稱 說明 是否可讀寫
defaultstatus 網頁載入完成後,狀態列上的預設文字 讀/寫
status 目前視窗狀態列上的文字 讀/寫
history 已經瀏覽過的URL資料
length 傳回集合裡的元件數目
location 網頁裡的URL位址 讀/寫
name 視窗名稱
navigator 瀏覽器資訊
document 瀏覽器內的網頁文件
opener 傳回目前開啟著的物件
closed 目前視窗是否關閉
parent 目前視窗的母視窗
self 目前視窗
top 最上層視窗

方法

方法 說明
alert 開啟警告對話框
blur 讓網頁失去焦點
clearinterval 取消setinterval的作用
cleartimeout 取消settimeout的作用
close 關閉瀏覽器視窗
confirm 開啟確認對話框
execscript 執行某個script,預設為javascript
focus 讓網頁取得焦點
navigate 連結到其他網頁
open 新增瀏覽器視窗
prompt 開啟輸入對話框
scroll 將網頁視窗捲動X位移與Y位移
setinterval 固定的毫秒時間間隔來反覆執行某個函數
settimeout 固定的毫秒時間後執行某個函數
showhelp 開啟對話框
showmodaldialog 開啟modal視窗

事件

事件 說明
onload 載入網頁時發生
onunload 離開網頁時發生
onfocus 視窗取得焦點時發生
onblur 視窗失去焦點時發生
onhelp 按下F1按鍵時發生
onresize 使用者調整視窗大小時發生
onscroll 使用者滾動視窗前後時發生
onerror 載入網頁後出現錯誤時發生

事件類別

JavaScript的事件大致上有3類

  1. 鍵盤與滑鼠事件
  2. 載入事件
  3. 表單相關事件

特殊連結程式碼?

上一頁 javascript:window.history.go(-1) javascript:window.history.back()
下一頁 javascript:window.history.go(1) javascript:window.history.forward()
重新整理 javascript:location.reload()  
列印 javascript:window.print()  
開啟視窗 javascript:window.open()  
關閉視窗 javascript:window.close()  

滑鼠游標相關的動作

顯示游標所在位置的說明

利用title屬性,如老闆的家

在狀態列顯示說明

利用onMouseOveronMouseOut屬性,配合window物件模型如 老闆的家

滑鼠指標指到時的樣式

利用a標籤的擬class「a:hover」屬性,如a:hover{color:#ffffff; background-color:#0000ff}

自訂物件

function parent(pname,ptel){  //父建構函數
  this.pname=pname;  // this.屬性=傳入參數
  this.ptel=ptel;
}
function student(username,password) {  //子建構函數
  this.username=username;  //子建構函數中的屬性定義
  this.password=password;
  this.get=show;  //子建構函數中的方法定義
}
function show(obj) {  //子建構函數的方法
  document.write("username : "+this.username+"<br />");
  document.write("password : "+this.password+"<br />");
  document.write("pname : "+this.pname+"<br />");
  document.write("ptel : "+this.ptel+"<br />");
}
student.prototype=new parent();  //原型繼承

var peter=new student();  //利用自訂的基底物件產生自訂衍生物件
with(peter)
{
  username="peter";
  password="123456";
  pname="john";
  ptel="23456789";
}

peter.get(peter);  //呼叫自訂物件中的方法。真正的OOP中括弧內應該可以寫this這裡若寫this的話會被當作window物件

使用技巧

進入網頁後停在第一個欄位

<script language="JavaScript" type="text/javascript"> <!--
function setFocus(){
 for(var i=0; i<document.forms[0].elements.length; i++) {
  var e = document.forms[0].elements[i];
  if (e.type=="text") {
   e.focus();
   break;
  }
 }
}
//--> </script>

<body onload="setFocus()">
......

設定文字欄位的輸入遮罩( input mask ) : 只能輸入數字

<script language="JavaScript" type="text/javascript"> <!--
function check_intkey(key){
 if (key>=48 && key<=57) {
  return true;
 } else {
  return false;
 }
}
//--> </script>

<input type="text" name="birthday" onKeypress="return check_intkey(event.keyCode)" />

設定文字欄位的欄位驗證 : 只能輸入數字

<script language="JavaScript" type="text/javascript"> <!--
function fild_valid(obj){
 var re = /^\d+$/;
 if (obj.value!="" && !re.test(obj.value)) {
  alert("您必須輸入數字喔");
  obj.select();
  return false;
 } else {
  return true;
 }
}
//--> </script>

<input type="text" name="birthday" onBlur="fild_valid(this)" />

游標停留在文字欄位中文字的最後面

<script language="JavaScript" type="text/javascript"> <!--
function fild_center() {
 var e = event.srcElement ;
 var r = e.createTextRange() ;
 r.moveStart('character',e.value.length) ;
 r.collapse(true) ;
 r.select() ;
}
//--> </script>

<input type="text" name="address" onClick="fild_center()" />

將文字欄位的東西拷貝至剪貼簿

<script language="JavaScript" type="text/javascript"> <!--
function addClipboard2(obj) {
 var r = obj.createTextRange() ;
 r.execCommand("Copy") ;
}
//--> </script>

<input type="text" id="address" onClick="addClipboard2(this)">

循序取出欄位的值

<script language="JavaScript" type="text/javascript"> <!--
 for( var i = 1; i<= 40; i++ ) {
 if ( typeof( eval( "document.tform.chk"+i ) ) == "undefined" ){
  break;
 }
 if (eval("document.tform.chk"+i+".value")=="Y") {
  .......................
 }
}
//--> </script>

<select name="chk1" > <option value="Y">是</option> <option value="N">否</option> </select>
<select name="chk2" > <option value="Y">是</option> <option value="N">否</option> </select>
.........
...假設一頁最多有40個select,或可能不足40個
........
<select name="chk40" > <option value="Y">是</option> <option value="N">否</option> </select>

預防自動蒐集email名單的機器人

<script language="JavaScript" type="text/javascript"> <!--
function AntiSpam(Name, Domain) {
 location.href = 'mailto:' + Name + '@' + Domain
}
//--> </script>

在寫電子郵件時,以下列語法呼叫上面的Javascript

<a href="javascript:AntiSpam('peterju','pchome.com.tw');">聯絡作者</a>

逐一取出指定物件屬性的函數

透過此函數可瞭解JavaScript為何被稱之為object based的原因,打開指定物件的黑盒子

<script language="JavaScript" type="text/javascript"> <!--
function listMember(obj) {
  var s="";
  for(key in obj) s+=key+" : "+ obj[key] + "<br />";
  return s;
}
//--> </script>

<script language="JavaScript" type="text/javascript"> <!--
var a="abc"; //雙引號的字串
var b='def'; //單引號的字串
var c=123; //數字
var d=[123,"abc",a,b]; //陣列物件1
var e=new Array(123,"abc",a,c); //陣列物件2
var f=new Object; //自訂物件
f.peter=123;
f.john=456;
f["jane"]=789;

alert(f["peter"]);
document.write(listMember(f));
document.write(listMember(document.location)); //可以推論陣列=物件, 物件.屬性 可以 陣列[註標]的方式來取用
//--> </script>

自訂字串物件的函數:trim(), ltrim(), rtrim()

我們可以利用 prototype 這個關鍵字來增加基底物件的屬性或方法,例如: 「基底物件.prototype.屬性 = 值」,或「基底物件.prototype.方法 =方法」,衍生後的物件自動繼承了增加的屬性或方法。

<script language="JavaScript" type="text/javascript"> <!--
String.prototype.trim=trim;  //傳回去除前後空白的值
String.prototype.ltrim=ltrim;  //傳回去除左邊空白的值
String.prototype.rtrim=rtrim;  //傳回去除右邊空白的值

function trim() {
  return this.replace(/^\s+|\s+$/g, "");
}
function ltrim() {
  return this.replace(/(^\s*)/g, "");
}
function rtrim() {
  return this.replace(/(\s*$)/g, "");
}
//--> </script>

<script language="JavaScript" type="text/javascript"> <!--
var d=new Array(123," abc def "); //陣列物件
document.write("["+d[1].trim()+"]");
document.write("["+d[1].ltrim()+"]");
document.write("["+d[1].rtrim()+"]")
//--> </script>

產生Excel文件

  1. 此範例僅可在IE Client端執行
  2. 在裝有XP2的IE瀏覽器上會遇到安全性訊息的提示,允許後便可執行(無法以Mark of the Web處理)

<script language="JavaScript" type="text/javascript">
var exApp = new ActiveXObject("Excel.Application");
exApp.Visible=true;
var oWB = exApp.Workbooks.Add();
//oWB.Worksheets(1).Activate; //若有多張工作表時改用此法
var exWbook = oWB.ActiveSheet;
exWbook.Columns("A").columnwidth=30;
exWbook.Columns("A").WrapText = true;
exWbook.Columns("B").columnwidth=30;
exWbook.Columns("B").WrapText = true;
exWbook.Range("A1:B1000").NumberFormat = "0";
exWbook.Range("A1:B1000").HorizontalAlignment = -4131;
exWbook.Cells(1,1).Interior.ColorIndex="15";
exWbook.Cells(1,1).value="第一欄, 第一格";
exWbook.Cells(2,1).value="第一欄, 第二格";
exWbook.Cells(1,2).value="第二欄, 第一格";
exWbook.Cells(2,2).value="第二欄, 第二格";
exWbook.Name="以Javascript產生的工作表";
</script>

連結Sql資料庫

  1. 此範例僅可在IE Client端執行
  2. 在裝有XP2的IE瀏覽器上會遇到安全性訊息的提示,允許後便可執行(無法以Mark of the Web處理)

<script language="JavaScript" type="text/javascript">
var objdbConn = new ActiveXObject("ADODB.Connection");
var strdsn = "Driver={SQL Server};Server=127.0.0.1;Database=test;UID=sa;PWD=123456";
objdbConn.Open(strdsn);
var objrs = objdbConn.Execute("select * from student ");
var fdCount = objrs.Fields.Count - 1;
if (!objrs.EOF){
  document.write("<table border=\"1\" style=\"border-collapse:collapse\"><tr>");
  for (var i=0; i <= fdCount; i++)
  document.write("<td><strong>" + objrs.Fields(i).Name + "</strong></td>");
  document.write("</tr>");
  while (!objrs.EOF){
    document.write("<tr>");
    for (i=0; i <= fdCount; i++)
    document.write("<td>" + objrs.Fields(i).Value + "&nbsp;</td>");
    document.write("</tr>");
    objrs.moveNext();
  }
  document.write("</table>");
}
else
  document.write("資料庫中無記錄!<br / >");
objrs.Close();
objdbConn.Close();
</script>

參考書目

網路資源

主 網 站:http://peterju.notlong.com (目前轉址至 http://irw.ncut.edu.tw/peterju/) Sitetag Logo

Level Triple-A conformance icon | [歡迎使用任何作業系統、瀏覽器觀看!] | Valid XHTML 1.0 Transitional | Valid CSS! | [Valid RSS] | [創意公眾許可証]
This work is licensed under a Creative Commons License