JavaScript基礎

JavaScript站點: http://javascript.internet.com/scrolls/

JavaScript特效代碼大全420:http://www.codesky.net/article/200508/72743.html

實際上,一個完整的JavaScript實現是由以下3個不同部分組成的:核心ECMAScript瀏覽器對象模型BOM文檔對象模型DOM

一、核心的ECMAScript

ECMAScript可以爲不同各類的宿主環境提供核心的腳本編程能力,因此核心的腳本語言是與任何特定的宿主環境分開進行規定的。Web瀏覽器對於ECMAScript來說就是一個宿主環境,但它並不是唯一的宿主環境。在ECMAScript描述了以下的內容:語法變量關鍵字保留字原始值和引用值原始類型和引用類型類型轉換運算符語句函數對象作用域定義類或對象繼承

1. 語法Top

區分大小寫。與Java一樣,變量名、函數名、運算符以及其他一切東西都是區分大小寫的。
變量是弱類型的。ECMAScript中變量無特定的類型,只用var運算符,可以將它初始化爲任意的值,可以隨時改變變量所存數據的類型。
每行結尾的分號可有可無。習慣問題加上分號,因爲沒有分號,有些瀏覽器就不有正常運行。
註釋與Java、C和PHP語言的註釋相同。單選註釋以雙斜線(//)開頭;多選註釋以單斜線和星號(/*)開頭,以星號加單斜線結尾(*/)。
括號表明代碼塊。這些語句被封裝在左括號({)和右括號(})之間。

2. 變量Top

ECMAScript中的變量是用var運算符(variable的縮寫)加變量名定義的。例如:var test = "hi", age = 25;
與Java不同,ECMAScript中的變量並不一定要初始化(它們是在幕後初始化的)。例如:var test;
與Java不同的還有,變量可以存放不同類型的值,這也是弱類型的優勢。例如:var test = "hi"; test = 25;
ECMAScript中的變量允許使用之前不必聲明,解釋程序遇到未聲明過的標識符時,用該變量名創建一個全局變量並初始化爲指定的值。
變量名規則:第一個必須是字母、下劃線(_)或美元符號($),餘下字符可以是下劃線、美元符號或任何字母或數字字符。
通常在變量名前加上一個前綴,如數組(a)、布爾開型(b)、浮點型(f)、函數(fn)、整型(i)、對象(o)、正則表達式(re)、字符串(s)、變型(v)。

3. 關鍵字Top

根據規定,關鍵字是保留的,不能用作變量名或函數名。如果把關鍵字用作變量名或函數名,可以得到諸如"Identifier excepted"這樣的錯誤消息。ECMAScript關鍵字的完整列表如下:
try、catch、finally、break、continue、default、throw、return、for、in、if、else、do、while、switch、case、new、var、delete、void、function、this、with、instanceof、typeof

4. 保留字Top

保留字在某種意義上是爲將來的關鍵字而保留的單詞,因此,保留字也不能用作變量名或函數名。ECMAScript保留字的完整列表如下:
boolean、char、byte、short、int、long、float、double、extends、abstract、implements、interface、import、package、class、public、protected、private、transient、static、final、native、volatile、synchronized、enum、export、super、throws、const、goto、debugger

5. 原始值和引用值Top

在ECMAScript中,變量可以存放兩種類型的值,即原始值和引用值。
原始值是存儲在棧(Stack)中的簡單數據段,也就是說,它們的值直接存儲在變量訪問的位置。原始類型佔據的空間是固定的,這樣存儲便於迅速查尋變量的值。
引用值是存儲在堆(Heap)中的對象,也就是說,存儲在變量處的值是一個指針,指向存儲對象的內存處。引用值的大小會改變,不能把它放在棧中,否則會降低變量查尋的速度。

6.  原始類型Top

ECMAScript有5種原始類型,即Undefined、Null、Boolean、Number和String。每種類型定義了它包含的值的範圍及其字面量表示形式。
typeof運算符可以用來判斷一個值是否在某種類型的範圍內。
typeof運算符將返回下列值之一:"undefined(Undefined類型)"、"boolean(Boolean類型)"、"number(Number類型)"、"string(String類型)"、"object(引用類型或Null類型)"

當聲明的變量未初始化時,該變量的默認值是undefined;如:var tmp; alert(typeof tmp); //undefined
當typeof作用於未聲明的變量上時,返回的也是undefined;如:alert(typeof tmp); //undefined
當函數無明確返回值時,返回的也是undefined;如:function testFn(){...}  alert(testFn() == undefined); //true
alert(null == undefined); //true,儘管這兩個值相等,但是含義不同,一個是聲明瞭變量但未對其初始化時賦予該變量的值,一個表示尚未存在的對象,如果函數或方法要返回的是對象,那麼找不到該對象時,返回的通常是null。

Boolean只有兩個字面量:true和false。

Number即可表示32位的整數,也可表示64位的浮點數,也可表示8進制、16進制和科學計數法。如:var iN=55, fN=1.0, iN1=070; iN3=0XAB, fN2=3.12e7。
儘管所有整數都可表示爲八進制或十六進制的字面量,但所有數學運算返回的都是十進制結果。
浮點數在用它進行計算之前,真正存儲的是字符串。IEEE 754規定64位的浮點數最多可以有17個十進制位。
Number.MAX_VALUE和Number.MIN_VALUE定義了Number值集合的外邊界。Number.POSITIVE_INFINITY和Number.NEGATIVE_INFINITY表示超出外邊界的無窮大和無窮小,也可用Infinity和-Infinity表示。
對於任何數調用isFinite()方法,以確保該數不是無窮大;調用isNaN()方法來判斷該數是否是數值。alert(NaN == NaN); //false,NaN自身不相等

字符串字面量是由雙引號或單引號聲明的,首字符從0開始,換行\n、製表符\t、空格\b、回車\r、換頁符\f、反斜槓\\、單引號\'、雙引號\"、八進制代碼\0nnn、十六進制代碼\Xnnn、十六進制代碼\Unnnn(Unicode字符)。

7. 引用類型Top

Object類:與Java中的java.lang.Object類似,ECMAScript中的所有類都由這個類繼承而來,Object類中的所有屬性和方法都會出現在其他類中。
屬性:
Constructor 對創建對象的函數的引用,對於Object類,該指針指向原始的object()函數。
Prototype 對該對象的對象原型的引用,對於所有的類,它默認返回Object對象的一個實例,允許您向對象添加屬性和方法。
方法:
HasOwnProperty(property) 判斷對象是否有某個特定的屬性,必須用字符串指定該屬性
IsPrototypeOf(object) 判斷該對象是否爲另一個對象的原型
PropertyIsEnumerable(property) 判斷給定的屬性是否可以用for...in語句進行枚舉
ToString() 返回對象的原始字符串表示
ValueOf() 返回最適合該對象的原始值

Boolean類:將覆蓋object類的valueOf()方法,返回原始值,即true或false;toString()方法也會被覆蓋,返回字符串"true"或"false"。很少使用Boolean對象,不易理解。
var oFalseObject = new Boolean(false);
var bResult = oFalseObject && true;  //true
var cResult = oFalseObject.valueOf() && true;  //false

Number類:除了覆蓋valueOf()和toString()方法,還有幾個處理數值的專用方法。應該少使用這種對象,以避免發生潛在的問題。
var oNumberObject = new Number(99);
alert(oNumberObject.valueOf()); //99
alert(oNumberObject.toFixed(2)); //99.00,返回具有指定位數小數的數字的字符串表示
alert(oNumberObject.toExponential(1)); //9.9e+1,返回用科學計數法表示的字符串形式
alert(oNumberObject.toPrecision(1)); //1e+2,根據最有意義的形式來返回數字的預定形式或指數形式
alert(oNumberObject.toPrecision(2)); //99
alert(oNumberObject.toPrecision(3)); //99.0,相當於toFixed(1)

String類:valueOf()和toString()方法都會返回String型的原始值,String類的所有屬性和方法都可應用於String原始值上,因爲它們都是僞對象。
var oStringObject = new String("hello world");
alert(oStringObject.valueOf() == oStringObject.toString()); //true
alert(oStringObject.length); //11,求字符串中字符的個數
alert(oStringObject.charAt(1)); //"e",訪問字符串中的單個字符
alert(oStringObject.charCodeAt(1)); //101,訪問字符串中的單個字符的字符代碼
alert(oStringObject.fromCharCode(1)); //
var sResult = oStringObject.concat(" again");
alert(sResult); //"hello world again",把一個或多個字符串連接到String對象的原始值上,返回的是String的原始值,也可用"+"號連接
alert(oStringObject.indexOf("o")); //4,從字符串的開頭開始檢索子串的位置
alert(oStringObject.lastIndexOf("o")); //7,從字符串的結尾開始檢索子串的位置
alert(oStringObject.localeCompare("zoo")); //-1,對字符串值進行排序,返回-1、0或1
alert(oStringObject.slice(3)); //"lo world",返回字符串的子串,同substring(),只有在參數爲負數時,它們的處理方式稍有不同
alert(oStringObject.substring(3)); //"lo world"
alert(oStringObject.slice(3, 7)); //"lo w"
alert(oStringObject.substring(3, 7)); //"lo w"
alert(oStringObject.slice(-3)); //"rld",對於負數,slice()會用字符串的長度加上參數,相當於slice(8)
alert(oStringObject.substring(-3)); //"hello world",substring()將其作爲0處理,也就是忽略它
alert(oStringObject.slice(3, -4)); //"lo w",相當於slice(3, 7)
alert(oStringObject.substring(3, -4)); //"hel",相當於substring(3, 0),也就是substring(0, 3)
alert(oStringObject.match("world"));  //"world",用於檢索一個字符串
alert(oStringObject.match(/\w+/g));  //"hello world",用來檢索一個正則表達式的匹配
alert(oStringObject.search(/World/));  //"-1",因爲search對大小寫敏感,檢索不到World
alert(oStringObject.search(/World/i));  //"6",忽略大小寫的檢索
alert(oStringObject.replace(/Hello/i, "hi"));  //"hi world",用來替換字符串中的字符
alert(oStringObject.split(" "));  //["hello","world"],用來分割字符串
alert(oStringObject.toLowerCase()); //"hello world",把字符串轉成小寫
alert(oStringObject.toLocaleLowerCase()); //"hello world",基於特定區域實現的,同localeCompare()
alert(oStringObject.toUpperCase()); //"HELLO WORLD",把字符串轉成大寫
alert(oStringObject.toLocaleUpperCase()); //"HELLO WORLD",基於特定區域實現的,同localeCompare()

8. 類型轉換Top

轉換成字符串:3種主要的原始值Boolean值、數字和字符串都有toString()方法,可以把它們的值轉換成字符串。
var bFound = false;
alert(bFound.toString());  //"false"
var iNum1 = 10;
var fNum2 = 10.0;
alert(iNum1.toString());  //"10"
alert(fNum2.toString());  //"10"
alert(iNum1.toString(2));  //"1010"
alert(iNum1.toString(8));  //"12"
alert(iNum1.toString(16));  //"A"
轉換成數字:ECMAScript提供了兩種把非數字的原始值轉換成數字的方法,即parseInt()和parseFloat(),從位置0開始查看每個字符,直到找到第一個非有效的字符爲止,然後將該字符轉換爲數字。只有對String類型調用這些方法,才能正確運行,對其他類型返回的都是NaN。
var iNum1 = parseInt("1234blue");  //1234
var iNum2 = parseInt("0XA");  //10
var iNum3 = parseInt("22.5");  //22
var iNum4 = parseInt("blue");  //NaN
var iNum5 = parseInt("10", 2);  //2
var iNum6 = parseInt("10", 8);  //8
var iNum7 = parseInt("AF", 16);  //175
var fNum1 = parseFloat("1234blue");  //1234.0
var iNum2 = parseFloat("0XA");  //0
var fNum3 = parseFloat("22.5");  //22.5
var fNum4 = parseFloat("22.34.5");  //22.34
var fNum5 = parseFloat("0908");  //908
var fNum6 = parseFloat("blue");  //NaN
強制類型轉換:Boolean(value)、Number(value)、String(value)分別用於強制轉換成Boolean型、數字和字符串。當要轉換的值是至少有一個字符的字符串、非0數字或對象時,Boolean()函數將返回true;如果該值是空字符串、數字0、undefined或null,將返回false。Number()的強制轉換轉換的是整個值,而不是部分值。String()可把任何值轉換成字符串,與toString()的區別在於對null或undefined值強制類型轉換可以生成字符串而不引發錯誤。
var b1 = Boolean("");  //false
var b2 = Boolean("hi");  //true
var b3 = Boolean(100);  //true
var b4 = Boolean(0);  //false
var b5 = Boolean(null);  //false
var b6 = Boolean(new Object());  //true
var n1 = Number(false);  //0
var n2 = Number(true);  //1
var n3 = Number(undefined);  //NaN
var n4 = Number(null);  //0
var n5 = Number("5.5");  //5.5
var n6 = Number("56");  //56
var n7 = Number("5.6.7");  //NaN
var n8 = Number(new Object());  //NaN
var n9 = Number(100);  //100
var s1 = String(null);  //"null"
var s2 = String(undefined);  //"undefined"

9. 運算符Top

instanceof:在使用typeof運算符時採用引用類型存儲值會出現一個問題,無論引用的是什麼類型的對象,它都返回"Object"、instanceof用於識別正在處理的對象的類型,要求開發者明確地確認對象爲某特定類型。
var oStringObject = new String("hello world");
alert(oStringObject instanceof String);  //true
一元運算符delete:刪除對以前定義的對象屬性或方法的引用,但不能刪除開發者未定義的屬性和方法。delete o.toString()將引發錯誤
	var o = new Object; 
	o.name = "Channing";
	alert(o.name);  //"Channing"
	delete o.name;
	alert(o.name);  //"undefined"
一元運算符void:對任何值都返回undefined,通常用於避免輸出不應該輸出的值,如:<a href="javascript:void(window.open('about:blank'));">Click Me</a>,否則瀏覽器將清空頁面,只顯示函數結果。
前增量/前減量運算符 ++i/--i
後增量/後減量運算符 i++/i--
一元加法和一元減法 
	var sNum = "25";
	var iNum1 = +sNum; //25 數值型
	var iNum2 = -sNum;  //-25 數值型
加法運算符:+
	如果某個運算數是NaN,結果爲NaN
	Infinity + Infinity = Infinity
	-Infinity + (-Infinity) = -Infinity
	Infinity + (-Infinity) = NaN
	0 + 0 = 0
	-0 + 0 = 0
	-0 + (-0) = -0
	如果兩個運算數都是字符串,把第二個字符串連接到第一個字符串上。
	如果只有一個運算數是字符串,把另一個運算數轉換成字符串,結果是兩個字符串連接成的字符串。
減法運算符:-
	如果某個運算數是NaN,結果爲NaN
	Infinity - Infinity = NaN
	-Infinity - (-Infinity) = NaN
	Infinity - (-Infinity) = Infinity 
	-Infinity - Infinity = -Infinity
	0 - 0 = 0
	-0 - 0 = -0
	-0 - (-0) = 0
	如果某個運算數不是數字,結果爲NaN。
乘法運算符:*
	如果某個運算數是NaN,結果爲NaN。
	Infinity乘以0,結果爲NaN。
	Infinity乘以0以外的任何數字,結果爲Infinity或-Infinity,由第二運算數的符號決定。
	Infinity乘以Infinity,結果爲Infinity。
除法運算符:/
	如果某個運算數是NaN,結果爲NaN。
	Infinity被Infinity除,結果爲NaN。
	Infinity被任何數字除,結果爲Infinity。
	一個非無窮大的數字除0,結果爲Infinity。
	Infinity被0以外的任何數字除,結果爲Infinity或-Infinity,由第二運算數的符號決定。
取模運算符:%
	如果被除數是Infinity,或者除數是0,結果爲NaN。
	Infinity被Infinity除,結果爲NaN。
	如果除數是無窮大的數,結果爲被除數。
	如果被除數爲0,結果爲0。
位運算符:與(&)、或(|)、非(~)、異或(^)、左移(<<)、有符號右移(>>)、無符號右移(>>>)
邏輯運算符:與(&&)、或(||)、非(!)
	如果一個運算數是對象,另一個是Boolean值,返回該對象。
	如果兩個運算數都是對象,||返回第一個對象,&&返回第二個對象。
	如果某個運算數是null,返回null。
	如果某個運算數是NaN,返回NaN。
	如果某個運算數是undefined,發生錯誤。
關係運算符:<、>、<=、>=,(只要有一方爲NaN就返回false)
等性運算符:==、!=、===(同類型比較)、!==,注意null == undefined、NaN  != NaN
條件運算符:variable = boolean_expression ? true_value : false_value;
賦值運算符:=、+=、-=、*=、/=、%=、<<=、>>=、>>>=
逗號運算符:可以在一條語句中執行多個運算,如var iNum1 = 1, iNum2 = 2, iNum3 = 3;
10. 語句Top
If語句:
if( condition1 ) 
	statement1 
else if ( condition2 ) 
	statement2 
else
	statement3

迭代語句/循環語句:
do {
	statement
} while ( expression );

while ( expression )
	statement;

for ( initialization; expression; post-loop-expression )
	statement;

for ( property in expression )
	statement;

有標籤的語句:
label: statement

break語句和continue語句:break立即退出循環,阻止再次反覆執行任何代碼;continue只是退出當前循環,允許進入下一次循環。可以結合標籤語句使用。

with語句:用於設置代碼在特定對象中的作用域。
with ( expression ) statement;
var sMessage = "hello world";
with(sMessage){
	alert(toUpperCase());  //"HELLO WORLD"
}

switch語句:
switch ( expression ) {
	case value : 
		statement;
		berak;
	......
	default:
		statement;
}

11. 函數Top

function functionName(arg0, arg1, ... , argN) {
	statements;
	return statement;
}
如果函數無明確的返回值,或調用了沒有對象的return語句;那麼它真正返回的值是undefined。
函數不能重載,當相同的名字在同一個作用域中定義兩個函數時,並不會引發錯誤,但真正使用的是後一個函數,第二個函數覆蓋了第一個函數的定義,但可以使用argumnets對象避開這種限制。
使用arguments對象時,開發者無需明確指出參數名,就能訪問它們。arguments[0]、arguments[1]、arguments.length
function doAdd(){
	if(arguments.length == 1)
		alert(arguments[0] + 10);
	else if (arguments.length == 2)
		alert(arguments[0] + arguments[1]);
}

Function類:var function_name = new Function(arg1, arg2, ... ,argN, function_body);
儘管可用Function構造函數創建函數,但最好不要使用它,因爲用它定義函數比用傳統方式要慢的多。不過,所有函數都應看作是Function類的實例。

函數的屬性和方法:
	length屬性,返回的是函數的參數個數,最多有25個。
	valueOf()和toString()方法,返回的都是函數的源代碼。

函數的難點:閉包
"所謂閉包,是指詞法表示包括不必計算的變量的函數,也就是說,該函數能使用函數外定義的變量。"
"也有說,閉包就是能夠讀取其他函數內部變量的函數,在本質上,閉包就是將函數內部和函數外部連接起來的一座橋樑"
"又有說,當一個函數被嵌套在另一個函數中,並且在外層函數執行結束之後,內層函數可以繼續訪問外層函數中的變量。使用閉包可以實現類似私有變量的功能,並且能夠阻止外層函數被GC回收。"
它的最大用處有兩個,一個是前面提到的可以讀取函數內部的變量,另一個就是讓這些變量的值始終保持在內存中。
使用全局變量是一個簡單的閉包實例
var sMessage = "Hello World";
function sayHelloWorld(){
	alert(sMessage); //腳本被載入內存後並未爲函數計算變量的值,sMessage而是在函數調用時被賦值
}
sayHelloWorld();

在一個函數中定義另一個函數會使閉包變得更復雜
var iBaseNum  = 10;
function addNumbers(iNum1, iNum2){
	function doAddition(){
		return iNum1 + iNum2 + iBaseNum; //內部函數是個閉包,獲取外部函數的參數iNum1和iNum2以及全局變量iBaseNum的值
	}
return doAddition();
}

function f1(){
	var n=999;
	nAdd=function(){n+=1}
	function f2(){
		alert(n);
	}
	return f2;
}
var result=f1();
result(); // 999
nAdd();
result(); // 1000
在這段代碼中,result實際上就是閉包f2函數。它一共運行了兩次,第一次的值是999,第二次的值是1000。這證明了,函數f1中的局部變量n一直保存在內存中,並沒有在f1調用後被自動清除。 
爲什麼會這樣呢?原因就在於f1是f2的父函數,而f2被賦給了一個全局變量,這導致f2始終在內存中,而f2的存在依賴於f1,因此f1也始終在內存中,不會在調用結束後,被垃圾回收機制(garbage collection)回收。 
這段代碼中另一個值得注意的地方,就是“nAdd=function(){n+=1}”這一行,首先在nAdd前面沒有使用var關鍵字,因此 nAdd是一個全局變量,而不是局部變量。其次,nAdd的值是一個匿名函數(anonymous function),而這個匿名函數本身也是一個閉包,所以nAdd相當於是一個setter,可以在函數外部對函數內部的局部變量進行操作。

使用閉包的注意點 
1)由於閉包會使得函數中的變量都被保存在內存中,內存消耗很大,所以不能濫用閉包,否則會造成網頁的性能問題,在IE中可能導致內存泄露。解決方法是,在退出函數之前,將不使用的局部變量全部刪除。 
2)閉包會在父函數外部,改變父函數內部變量的值。所以,如果你把父函數當作對象(object)使用,把閉包當作它的公用方法(Public Method),把內部變量當作它的私有屬性(private value),這時一定要小心,不要隨便改變父函數內部變量的值。 

12. 對象Top

對象聲明和實例化: 
	var oObject = new Object(); //如果構造函數無參數,則括號不是必需的
	var oStringObject = new String();
對象的引用:每次創建對象,存儲在變量中的都是該對象的引用,而不是對象本身。
對象廢除:每當函數執行完它的代碼,無用存儲單元收集程序(垃圾回收器)都會執行,釋放所有的局部變量。把對象的所有引用都設置爲null,可以強制性的廢除對象。
本地對象:
Object、Boolean、Number、String、Function、Array、Date、RegExp、Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError
創建Array對象:
var aValues = new Array(); 或 var aValues = new Array(20); 或 var aValues = new Array("red","green");
aValues[0] = "red";
aValues[2] = "green";

Array對象的屬性和方法:
	alert(aValues.length);  //3,返回數組元素的個數
	alert(aValues.valueOf());  //"red,,green",返回數組元素的字符串表示,以逗號分隔
	alert(aValues.toString());  //"red,,green",返回數組元素的字符串表示,以逗號分隔
	alert(aValues.toLocaleString());  //"red,,green",與toString()方法相同,但同區域關聯
	alert(array.join("]["));  //"red][][green",連接數組中的值組成字符串,與String的split()方法正好相反
	var aValue2 = array.concat("blue", "yellow");
	alert(aValue2.toString());  //"red,,green,blue,yellow",將新元素添加在數組末尾,並返回一個新的對象,不影響原來的Array,同String的concat()
	alert(aValue2.slice(1, 4));  //",green,blue",返回具有特定項的新數組,不影響原來的Array,同String的slice()方法
	alert(array.push("blue"));  //"red,,green,blue",用於在Array結尾添加一個新項,並返回Array的個數4
	alert(array.pop());  //"red,,green",刪除最後一個數組項,length減1,並返回它作爲函數值"blue"
	alert(array.shift());  //",green",刪除數組中的第一個項,並將其作爲函數值返回"red"
	array.unshift("black");  //"black,,green",無返回值,把一個項放在數組中第一個位置,然後把餘下的項下移一個位置
	alert(array.reverse());  //"green,,red",顛倒數組項的順序並返回
	alert(array.sort());  //"green,red,",根據數組項的值按升序爲它們排序並返回
	alert(array.splice(0, 2));  //刪除數組中的前兩項並返回被刪除的數組項"red,",第一個參數爲起始位置(刪除)
	alert(array.splice(2, 0, "blue", "yellow"));  //"red,,blue,yellow,green",在第2個位置上插入後面的數組項並返回被刪除的數組項"",第二個參數爲要刪除的數組項個數(替換而不刪除)
	alert(array.splice(2, 1, "blue", "yellow"));  //"red,,blue,yellow",在第2個位置上插入後面的數組項並返回被刪除的數組項"green",第二個參數爲要刪除的數組項個數(替換並刪除)
創建Date對象:
var date = new Date();  //"Wed Mar 20 15:52:28 UTC+0800 2013",用當前的日期和時間創建新的Date對象
var date = new Date(0); //"Thu Jan 1 08:00:00 UTC+0800 1970",聲明距離1970年1月1日凌晨12點的毫秒數
var date = new Date(Date.parse("May 25 2004"));  //"Tue May 25 00:00:00 UTC+0800 2004",parse可以獲得毫秒錶示,如果字符串不能轉換成日期,返回NaN
var date = new Date(Date.UTC(2004, 1, 5, 21, 5));  //"Thu Feb 5 21:05:00 UTC+0800 2004",參數爲年月日時分秒毫秒,年月爲必需的,0爲一月
var date = new Date(2004, 1, 5, 21, 5);  //直接聲明UTC()方法接受的參數

Date對象的屬性和方法:
	valueOf(),返回日期的毫秒錶示,如1075962840000
	toString(),返回由實現的特定的字符串,如Thu Feb 5 14:34:00 UTC+0800 2004
	toDateString(),以實現的特定的格式顯示Date的日期部分,年月日,如Thu Feb 5 2004
	toTimeString(),以實現的特定的格式顯示Date的時間部分,時分秒和時區,如14:34:00 UTC+0800
	toLocaleString(),以地點的特定的格式顯示Date的日期和日間,如2004年2月5日 14:34:00
	toLocaleDateString(),以地點的特定的格式顯示Date的日期部分,如2004年2月5日
	toLocaleTimeString(),以地點的特定的格式顯示Date的時間部分,如14:34:00
	toUTCString(),以實現的特定的格式顯示Date的UTC時間,如Thu, 5 Feb 2004 06:34:00 UTC
	getTimezoneOffset(),返回某個時區與UTC時間的關係,如-480表示比UTC時間提前8個小時,還可用來判斷是否是夏令時
	getTime()/setTime(milliseconds),設置/返回日期的毫秒錶示
	getFullYear()/setFullYear(year)),設置/返回日期的四位數字的年份值
	getUTCFullYear()/setUTCFullYear(year),設置/返回UTC日期的四位數字的年份值
	getMonth()/setMonth(month),設置/返回日期的月份值,由數字0到11表示,set時對大於11的數開始累計年數
	getUTCMonth()/setUTCMonth(month),設置/返回UTC日期的月份值,由數字0到11表示,set時對大於11的數開始累計年數
	getDate()/setDate(date),設置/返回日期中該月中的某天
	getUTCDate()/setUTCDate(date),設置/返回UTC日期中該月中的某天
	getDay()/setDay(day),設置/返回日期爲星期幾
	getUTCDay()/setUTCDay(day),設置/返回UTC日期爲星期幾
	getHours()/setHours(hours),設置/返回日期中的小時值
	getUTCHours()/setUTCHours(hours),設置/返回UTC日期中的小時值
	getMinutes()/setMinutes(minutes),設置/返回日期中的分鐘值
	getUTCMinutes()/setUTCMinutes(minutes),設置/返回UTC日期中的分鐘值
	getSeconds()/setSeconds(seconds),設置/返回日期中的秒值
	getUTCSeconds()/setUTCSeconds(seconds),設置/返回UTC日期中的秒值
	getMilliseconds()/setMilliseconds(seconds),設置/返回日期中的毫秒值
	getUTCMilliseconds()/setUTCMilliseconds(seconds),設置/返回UTC日期中的毫秒值

RegExp對象

參考JavaScript正則表達式一篇 

內置對象Global
Global對象實際上並不存在,var pointer = Global; 將顯示錯誤消息。Global對象的屬性和方法主要有:
	undefined、NaN、Infinity、Object、Boolean、Number、String、Function、Array、Date、RegExp、
	Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError
	isNaN()、isFinite()、parseInt()、parseFloat()
	eval(),解釋程序發現eval()調用時,它將把參數解釋爲真正的語句,然後把它插入到該函數所在的位置,很強大也可進行代碼注入
	encodeURI(),用於處理完整的URI,不對URI中特殊字符進行編碼,如冒號、前斜槓、問號和英鎊符號
	encodeURIComponent(),用於處理URI的一個片斷,對它發現的所有非標準字符進行編碼
	decodeURI()/decodeURIComponent(),針對上面兩個方法的解碼,BOM的escape()和unescape()方法只能對ASCII符號進行編碼解碼,應避免使用
內置對象Math
Math對象的屬性和方法主要有:
	E,返回算術常量e,即自然對數的底數(約等於2.718)
	LN10,返回 2 的自然對數(約等於0.693)
	LN2,返回 10 的自然對數(約等於2.302)
	LOG2E,返回以 2 爲底的 e 的對數(約等於1.414)
	LOG10E,返回以 10 爲底的 e 的對數(約等於0.434)
	PI,返回圓周率(約等於3.14159)
	SQRT1_2,返回 2 的平方根的倒數(約等於0.707)
	SQRT2,返回 2 的平方根(約等於1.414)
	max()、min()、abs()、ceil()向上舍入、floor()向下舍入、round()標準舍入、exp()、log()、
	pow()、sqrt()、sin()、asin()、cos()、acos()、tan()、atan()、atan2()、random()
宿主對象
所有非本地對象都是宿主對象,由ECMAScript實現的宿主環境提供的對象,所有BOM和DOM對象都是宿主對象。將在BOM和DOM中詳細說明。
作用域Top
ECMAScript中沒有公用、受保護和私有作用域。
由於缺少私有作用域,開發者們制定了一個規約,規定在屬性名前後加下劃線,obj._color_ = "red";,但這並不改變這些屬性是公用屬性的事實。只是告訴其他開發者,應該把該屬性看作私有的。
ECMAScript中也沒有靜態作用域。 但可以給構造函數提供屬性和方法,因爲構造函數只是函數,函數是對象,對象就可以有屬性和方法。如:
function sayHi(){ alert("hi"); }
sayHi.alternate = function(){ alert("hola"); }
sayHi();  //"hi"
sayHi.alternate();  //"hola"

關鍵字this總是指向調用該方法的對象,隨着函數使用場合不同,this的值會發生變化。但是總有一個原則,那就是this指的是調用該函數的那個對象。
var oCar = new Object;
oCar.color = "red";
oCar.showColor = function(){ 
	alert(this.color);  //"red",this指向oCar,也可以用alert(oCar.color);
}

那爲什麼要用this呢?因爲在實例化對象時,總是不能確定開發者會使用什麼樣的變量名,使用this,即可在任意多個地方重用同一個函數。如:
function showColor(){ 
	alert(this.color);  //如果不用this關鍵字引用變量,ECMAScript就會把它看作局部變量或全局變量,找不到就會顯示null
}

var oCar1 = new Object;
oCar1.color = "red";
oCar1.showColor = showColor;

var oCar2 = new Object;
oCar2.color = "blue";
oCar2.showColor = showColor;

oCar1.showColor();  //"red"
oCar2.showColor();  //"blue"

定義類或對象Top

1. 工廠方式:創建一個返回特定類型的對象的工廠函數
function createCar(sColor, iDoors, iMpg){
	var oTempCar = new Object;
	oTempCar.color = sColor;
	oTempCar.doors = iDoors;
	oTempCar.mpg = iMpg;
	oTempCar.showColor = showColor;
	return oTempCar;
}
function showColor(){ 
	alert(this.color); 
};
var oCar1 = createCar("red", 4, 23);
var oCar2 = createCar("blue", 3, 25);

2. 構造函數方式:在構造函數內部無創建對象,而是使用this關鍵字,在執行第一行代碼前先創建一個對象,只有用this才能訪問該對象。
function Car(sColor, iDoors, iMpg){
	this.color = sColor;
	this.doors = iDoors;
	this.mpg = iMpg;
	this.showColor = showColor;
}
var oCar1 = new Car("red", 4, 23);
var oCar2 = new Car("blue", 3, 25);

3. 原型方式:利用了對象的prototype屬性,使用此方法,還能用instanceof運算符檢查給定變量指向的對象的類型
function Car(){  }
Car.prototype.color = "red";
Car.prototype.doors = 4;
Car.prototype.mpg = 23;
Car.prototype.drivers = new Array("Mike", "Sue");
Car.prototype.showColor = showColor;
var oCar1 = new Car();
var oCar2 = new Car();
oCar1.drivers.push("Matt");  //對象會被多個實例共享
alert(oCar1.drivers);  //"Mike,Sue,Matt"
alert(oCar2.drivers);  //"Mike,Sue,Matt" 

4. 混合的構造函數/原型方式:用構造函數定義對象的所有非函數屬性,用原型方式定義對象的函數屬性(方法),結果是所有的函數都只創建一次,而每個對象都具有自己的對象屬性實例。
function Car(sColor, iDoors, iMpg){
	this.color = sColor;
	this.doors = iDoors;
	this.mpg = iMpg;
	this.drivers = new array("Mike", "Sue");
}
Car.prototype.showColor = function(){
	alert(this.color);
}
var oCar1 = new Car("red", 4, 23);
var oCar2 = new Car("blue", 3, 25);
oCar1.drivers.push("Matt"); 
alert(oCar1.drivers);  //"Mike,Sue,Matt"
alert(oCar2.drivers);  //"Mike,Sue" 

5. 動態原型方法:基本想法與混合的構造函數/原型方式相同,在構造函數內定義非函數屬性,而函數屬性則利用原型方式定義。唯一的區別是賦予對象方法的位置。
function Car(sColor, iDoors, iMpg){
	this.color = sColor;
	this.doors = iDoors;
	this.mpg = iMpg;
	this.drivers = new array("Mike", "Sue");
	if(typeof Car._initialized == "undefined"){
		Car.prototype.showColor = function(){  //該方法只被創建一次
			alert(this.color);
		}
		Car._initialized = true;
	}
}

6.混合工廠方式:這種方式通常是在不能應用前一種方式時的變通方法,它的目的是創建假構造函數,只返回另一種對象的新實例。代碼與工廠函數相似,不同的是使用new運算符,使它看起來像真正的構造函數。
function Car(sColor, iDoors, iMpg){
	var oTempCar = new Object;
	oTempCar.color = sColor;
	oTempCar.doors = iDoors;
	oTempCar.mpg = iMpg;
	oTempCar.showColor = showColor;
	return oTempCar;
}
var car = new Car("red", 4, 23);

工廠函數方式和構造函數方式以及混合工廠方式都存在函數管理方面的問題,會重複生成函數屬性,爲每個對象都創建獨立的函數版本。
目前使用最廣泛的是混合的構造函數/原型方式和動態原型方法,不過不要單獨使用經典構造函數或原型方式,因爲這樣會給代碼引入問題。

類實例--StringBuffer類(String的+=效率很低,次數多時會造成性能問題)
function StringBuffer(){
	this._strings = new Array;
}
StringBuffer.prototype.append = function(str){
	this._strings.push(str)
}
StringBuffer.prototype.toString = function(){
	return this._strings.join("");
}
var buffer = new StringBuffer();
buffer.append("hello");
buffer.append("world");
var result =  buffer.toString();

創建新方法
Number.prototype.toHexString = function(){
	return this.toString(16);
}

Array.prototype.indexof = function(item){
	for(var i=0; i<this.length; i++)
		if(item == this[i])
			return i;
	return -1;
}

Object.prototype.showValue = function(){  //String和Number對象繼承自Object,所以也有showValue()方法
	alert(this.valueOf());
}

String.prototype.trim = function(){
	var reExtraSpace = /^\s+(.*?)\s+$/;
	return this.replace(reExtraSpace, "$1");
}

重寫義已有方法
Function.prototype.originalToString = Function.prototype.toString;
Function.prototype.toString = function(){
	if(this.originalToString().length > 100)
		return "Function too long to display.";
	else
		return this.originalToString();
}

繼承Top

本地類和宿主類不能作爲基類,這樣可以防止公用訪問編譯過的瀏覽器級的代碼,因爲這些代碼可以被用於惡意攻擊。
創建的子類將繼承超類的所有屬性和方法,包括構造函數及方法的實現,記住所有屬性和方法都是公用的,因此子類可直接訪問這些方法,子類還可添加超類中沒有的新屬性和方法,也可以覆蓋超類中的屬性和方法。

1. 對象冒充:構造函數使用this關鍵字給所有屬性和方法賦值,因爲構造函數只是一個函數,所以可使ClassA的構造函數成爲ClassB的方法,然後調用它,ClassB就會收到ClassA的構造函數中定義的屬性和方法。支持多重繼承。
function ClassA(acolor){
	this.color = sColor;
	this.sayColor = function(){ alert(this.color); }
}

function ClassB(sColor, sName){
	this.newMethod = ClassA;
	this.newMethod(sColor);  //調用ClassA來達到繼承的目的
	delete this.newMethod;

	this.name = sName;  //所有的新屬性和新方法都必須在代碼行後定義,否則可能會覆蓋超類的相關屬性和方法
	this.sayName = function(){ alert(this.name); }
}
var objA = new ClassA("red");
var objB = new ClassB("blue", "Nicholas");
objA.sayColor();  //"red"
objB.sayColor();  //"blue"
objB.sayName();  //"Nicholas"

2. Function的call()方法:與經典的對象冒充方法最相似的方法,它的第一個對數用作this的對象,其他對象都直接傳遞給函數自身。如:
function sayColor(sPrefix, sSuffix){
	alert(sPrefix + this.color + sSuffix);
}
var obj = new Object();
obj.color = "red";
sayColor.call(obj, "The Color is ", ", a very nice color indeed.");
下面方法實現繼承
function ClassB(sColor, sName){
	ClassA.call(this, sColor);  //使用Function的call()方法來達到繼承的目的
	this.name = sName;  //所有的新屬性和新方法都必須在代碼行後定義,否則可能會覆蓋超類的相關屬性和方法
	this.sayName = function(){ alert(this.name); }
}

3. Function的apply()方法:與經典的對象冒充方法最相似的方法,有兩個對數,用作this的對象和要傳遞給函數的參數的數組,與call()的唯一區別就是參數傳遞的形式不同。如:
function sayColor(sPrefix, sSuffix){
	alert(sPrefix + this.color + sSuffix);
}
var obj = new Object();
obj.color = "red";
sayColor.apply(obj, new Array("The Color is ", ", a very nice color indeed."));
下面方法實現繼承
function ClassB(sColor, sName){
	ClassA.apply(this, new Array(sColor));  //使用Function的apply()方法來達到繼承的目的
	this.name = sName;  //所有的新屬性和新方法都必須在代碼行後定義,否則可能會覆蓋超類的相關屬性和方法
	this.sayName = function(){ alert(this.name); }
}

4. 原型鏈:prototype對象的任何屬性和方法都被傳遞給那個類的所有實例,不支持多重繼承,對ClassB的所有實例,instanceof爲ClassA和ClassB都返回true。
function ClassA(){ }
ClassA.prototype.color = "red";
ClassA.prototype.sayColor = function(){
	alert(this.color);
}

function ClassB(){ }
ClassB.prototype = new ClassA();  //必須是無參的構造函數
ClassB.prototype.name = "Sue";  //子類的所有屬性和方法都必須在prototype屬性被賦值之後

5. 混合方式:結合前兩者的做優點,用對象冒充繼承構造函數的屬性,用原型鏈繼承prototype對象的方法。如:
function ClassA(scolor){
	this.color = sColor;
}
ClassA.prototype.sayColor = function(){ alert(this.color); }

function ClassB(sColor, sName){
	ClassA.apply(this, new Array(sColor));
	this.name = sName;  
}
ClassB.prototype = new ClassA();
ClassB.prototype.sayName = function(){ alert(this.name); }

其他繼承方式如:zInherit和xbObjects

二、瀏覽器對象模型BOMTop

 BOM主要處理瀏覽器窗口和框架,描述了與瀏覽器進行交互的方法和接口,不過通常瀏覽器特定的JavaScript擴展都被看作BOM的一部分,這些擴展包括:彈出新的瀏覽器窗口、移動和關閉瀏覽器窗口以及調整窗口大小、提供Web瀏覽器詳細信息的導航對象、提供裝載到瀏覽器中頁面的詳細信息的定位對象、提供用戶屏幕分辨率詳細信息的屏幕對象、對Cookie的支持、IE擴展了BOM,加入了ActiveXObject類,可以通過JavaScript實例化ActiveX對象。由於沒有相關的BOM標準,每種瀏覽器都有自己的BOM實現。

1. 瀏覽器中的JavaScript

首先在在HTML中引入JavaScript標籤(可以放在任何位置,通常放在head標籤中)
<script language="JavaScript" type="text/javascript">  //language特性聲明要使用的腳本語言,一般默認爲JavaScript
	...... //type特性聲明內嵌代碼或要加入的外部文件的mime類型,用type而不用language,以提供更好的XHTML支持
</script>
<script language="JavaScript" src="../scripts/external.js"></script>  //src是可選的,聲明要加入頁面的外部JavaScript文件

大量的JavaScript代碼不應內嵌在HTML文件中,因爲只要查看源代碼,就可能發現安全漏洞,安全性不高;代碼散佈於多個頁面,代碼維護性差;如果多個頁面使用同一個文件,使用緩存只需要下載一次,內嵌增加了頁面大小,從而增加下載時間。

<script/>標籤放在<body/>標籤內時,只要腳本所屬的那部分頁面被載入瀏覽器,腳本就會被執行。這樣在載入整個頁面之前也可執行JavaScript代碼。

對舊的瀏覽器隱藏JavaScript代碼的格式,在內嵌代碼周圍加入HTML註釋,這樣其他瀏覽器就不會在屏幕上顯示這段代碼。如今卻不再是必須的,目前大多數Web瀏覽器都支持JavaScript,而不支持JavaScript的瀏覽器通常足夠聰明,自己就能夠忽略它。
<script type="text/javascript"> <!--  
	......
//-->
</script>

對於不支持或者禁用JavaScript的瀏覽器,用<noscript />提供替代的內容,<noscript />可包含任何HTML代碼。
CDATA段用於聲明不應被解析爲標籤的文本,這樣就可以使用特殊字符,如<、>、&、"等,而不必使用它們的字符實體<、>,使用CDATA段可以以常規形式編寫JavaScript代碼。
<script type="text/javascript"> 
//<![CDATA[
	......
//]]>
</script>

2. BOM體系結構

window對象:表示整個瀏覽器窗口,但不必表示其中包含的內容,此外,還可用於移動或調整它表示的瀏覽器的大小,或者對它產生其他影響。
如果頁面使用框架集合,每個框架都由它自己的window對象表示,存放在frames集合中,可用數字或名字對框架進行索引。如:window.frames[0]或window.frames["topFrame"],也可用top.frames[0]代替window
如果頁面上沒有框架,window和self就等於top,frames集合的長度就爲0。

window.moveBy(dx, dy);  //把瀏覽器窗口相對當前位置水平移動dx個像素,垂直移動dy個像素
window.moveTo(x, y);  //移動瀏覽器窗口使它的左上角位於用戶屏幕的x、y處
window.resizeBy(dw, dh);  // 相對於瀏覽器窗口的當前大小,把它的寬度調整dw個像素,高度調整dh個像素
window.resizeTo(w, h);  //把窗口的寬度調整爲w,高度調整爲h,不能使用負數
IE提供了window.screenLeft 和window.screenTop對象來判斷窗口的位置,但未提供任何判斷窗口大小的方法,用document.body.offsetWidth和document.body.offsetHeight屬性可以獲取視口的大小,但它們不是標準屬性。
Mozilla/Opera/Safari提供window.screenX和window.screenY屬性判斷窗口的位置,window.innerWidth和window.innerHeight屬性來判斷視口的大小,window.outerWidth和window.outerHeight屬性判斷瀏覽器窗口自身的大小。

window.open();  //打開新窗口,返回window對象。接受4個參數,即要載入新窗口的頁面URL、新窗口的名字、特性字符串和說明是否用新載入的頁面替換當前載入的頁面的Boolean值。一般只用前三個參數,最後一個參數只有在調用open()方法卻不打開新窗口時纔有效。
如果用已有框架的名字作爲open()方法的第二個參數,那麼URL所指的頁面就會載入該框架,如:window.open("baidu.com", "topFrame"),專用的框架名有:_self、_parent、_top、_blank。
如果框架名無效,將打開新窗口,新窗口的特性由第三個參數決定。可設置的屬性有:left、top、width、height、resizable、scrollable、toolbar、status、location,以逗號分隔,值爲yew或no。忽略將採取默認瀏覽器的設置。
新窗口還有對打開它的窗口的引用,存放在opener屬性中,只有新窗口的最高層window對象都有opener屬性。
如:var newWin = window.open("http://www.baidu.com","_blank","left=50,top=50,width=300,height=300,resizable=no,scrollable=no,toolbar=no,status=no,location=no");
alert(newWin.opener == window);  //"true"

window.close();  //關閉窗口
window.alert("message");  //彈出一個具有OK按鈕的系統消息框,顯示指定的文本
window.confirm("Are you sure?");  //彈出一個具有OK和Cancel按鈕的詢問對話框,返回一個布爾值
window.prompt("What's your name?", "Default");  //提示用戶輸入信息,接受兩個參數,即要顯示給用戶的文本和文本框中的默認值,將文本框中的值作爲函數值返回
window.status  //可以使狀態欄的文本暫時改變
window.defaultStatus  //默認的狀態欄信息,可在用戶離開當前頁面前一直改變文本
window.setTimeout("alert('xxx')", 1000);  //設置在指定的毫秒數後執行指定的代碼,接受2個參數,要執行的代碼和等待的毫秒數
window.clearTimeout("ID");  //取消還未執行的暫停,將暫停ID傳遞給它
window.setInterval(function, 1000);  //無限次地每隔指定的時間段重複一次指定的代碼,參數同setTimeout()一樣
window.clearInterval("ID");  //取消時間間隔,將間隔ID傳遞給它
window.history.go(-1);  //訪問瀏覽器窗口的歷史,負數爲後退,正數爲前進
window.history.back();  //同上
window.history.forward();  //同上
window.history.length  //可以查看歷史中的頁面數
document對象:實際上是window對象的屬性,document == window.document爲true,是唯一一個既屬於BOM又屬於DOM的對象
document.lastModified  //獲取最後一次修改頁面的日期的字符串表示
document.referrer  //用於跟蹤用戶從哪裏鏈接過來的
document.title  //獲取當前頁面的標題,可讀寫
document.URL  //獲取當前頁面的URL,可讀寫
document.anchors[0]或document.anchors["anchName"] //訪問頁面中所有的錨
document.forms[0]或document.forms["formName"]  //訪問頁面中所有的表單
document.images[0]或document.images["imgName"]  // 訪問頁面中所有的圖像
document.links [0]或document.links["linkName"]  //訪問頁面中所有的鏈接
document.applets [0]或document.applets["appletName"]  //訪問頁面中所有的Applet
document.embeds [0]或document.embeds["embedName"]  //訪問頁面中所有的嵌入式對象
document.write(); 或document.writeln();  //將字符串插入到調用它們的位置
location對象:表示載入窗口的URL,也可用window.location引用它
location.href  //當前載入頁面的完整URL,如http://www.somewhere.com/pictures/index.htm
location.portocol  //URL中使用的協議,即雙斜槓之前的部分,如http
location.host  //服務器的名字,如www.wrox.com
location.hostname  //通常等於host,有時會省略前面的www
location.port  //URL聲明的請求的端口,默認情況下,大多數URL沒有端口信息,如8080
location.pathname  //URL中主機名後的部分,如/pictures/index.htm
location.search  //執行GET請求的URL中的問號後的部分,又稱查詢字符串,如?param=xxxx
location.hash  //如果URL包含#,返回該符號之後的內容,如#anchor1
location.assign("http:www.baidu.com");  //同location.href,新地址都會被加到瀏覽器的歷史棧中
location.replace("http:www.baidu.com");  //同assign(),但新地址不會被加到瀏覽器的歷史棧中,不能通過back和forward訪問
location.reload(true | false);  //重新載入當前頁面,爲false時從瀏覽器緩存中重載,爲true時從服務器端重載,默認爲false
navigator對象:包含大量有關Web瀏覽器的信息,在檢測瀏覽器及操作系統上非常有用,也可用window.navigator引用它
navigator.appCodeName  //瀏覽器代碼名的字符串表示
navigator.appName  //官方瀏覽器名的字符串表示
navigator.appVersion  //瀏覽器版本信息的字符串表示
navigator.cookieEnabled  //如果啓用cookie返回true,否則返回false
navigator.javaEnabled  //如果啓用java返回true,否則返回false
navigator.platform  //瀏覽器所在計算機平臺的字符串表示
navigator.plugins  //安裝在瀏覽器中的插件數組
navigator.taintEnabled  //如果啓用了數據污點返回true,否則返回false
navigator.userAgent  //用戶代理頭的字符串表示
瀏覽器檢測方式:對象/特徵檢測和user-agent字符串檢測
對象/特徵檢測:是一種判斷瀏覽器能力的通用方法,而非目標瀏覽器的確切型號
if(document.getElementById){
	/the method exists, so use it here
} else {
	/do something else
}

user-agent字符串檢測:
IE各個版本典型的userAgent如下(其中,版本號是MSIE之後的數字): 
  Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) 
  Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2) 
  Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) 
  Mozilla/4.0 (compatible; MSIE 5.0; Windows NT) 
Firefox幾個版本的userAgent大致如下(其中,版本號是Firefox之後的數字): 
  Mozilla/5.0 (Windows; U; Windows NT 5.2) Gecko/2008070208 Firefox/3.0.1 
  Mozilla/5.0 (Windows; U; Windows NT 5.1) Gecko/20070309 Firefox/2.0.0.3 
  Mozilla/5.0 (Windows; U; Windows NT 5.1) Gecko/20070803 Firefox/1.5.0.12  
Opera典型的userAgent如下(其中,版本號是靠近Opera的數字)
  Opera/9.27 (Windows NT 5.2; U; zh-cn) 
  Opera/8.0 (Macintosh; PPC Mac OS X; U; en) 
  Mozilla/5.0 (Macintosh; PPC Mac OS X; U; en) Opera 8.0  
Safari典型的userAgent如下(其版本號是Version之後的數字):
  Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/525.13 (KHTML, like Gecko) Version/3.1 Safari/525.13 
  Mozilla/5.0 (iPhone; U; CPU like Mac OS X) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/4A93 Safari/419.3 
Chrome的userAgent是(其中,版本號在Chrome之後的數字)
  Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13  
  Navigator的userAgent是(其中,版本號在Navigator之後的數字):
  Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.12) Gecko/20080219 Firefox/2.0.0.12 Navigator/9.0.0.6 
以下出自高級JavaScript程序設計detect.js
var sUserAgent = navigator.userAgent; 
var fAppVersion = parseFloat(navigator.appVersion); 

function compareVersions(sVersion1, sVersion2) { 
	var aVersion1 = sVersion1.split("."); 
	var aVersion2 = sVersion2.split("."); 
	if (aVersion1.length > aVersion2.length) { 
		for (var i=0; i < aVersion1.length - aVersion2.length; i++) { 
			aVersion2.push("0"); 
		} 
	} else if (aVersion1.length < aVersion2.length) { 
		for (var i=0; i < aVersion2.length - aVersion1.length; i++) { 
		aVersion1.push("0"); 
		} 
	} 
	for (var i=0; i < aVersion1.length; i++) { 
		if (aVersion1[i] < aVersion2[i]) { 
			return -1; 
		} else if (aVersion1[i] > aVersion2[i]) { 
			return 1; 
		} 
	} 
	return 0; 
} 
var isOpera = sUserAgent.indexOf("Opera") > -1; 
var isMinOpera4 = isMinOpera5 = isMinOpera6 = isMinOpera7 = isMinOpera7_5 = false; 
if (isOpera) { 
	var fOperaVersion; 
	if(navigator.appName == "Opera") { 
		fOperaVersion = fAppVersion; 
	} else { 
		var reOperaVersion = new RegExp("Opera (//d+//.//d+)"); 
		reOperaVersion.test(sUserAgent); 
		fOperaVersion = parseFloat(RegExp["$1"]); 
	} 
	isMinOpera4 = fOperaVersion >= 4; 
	isMinOpera5 = fOperaVersion >= 5; 
	isMinOpera6 = fOperaVersion >= 6; 
	isMinOpera7 = fOperaVersion >= 7; 
	isMinOpera7_5 = fOperaVersion >= 7.5; 
} 
var isKHTML = sUserAgent.indexOf("KHTML") > -1 || sUserAgent.indexOf("Konqueror") > -1 || sUserAgent.indexOf("AppleWebKit") > -1; 
var isMinSafari1 = isMinSafari1_2 = false; 
var isMinKonq2_2 = isMinKonq3 = isMinKonq3_1 = isMinKonq3_2 = false; 
if (isKHTML) { 
	isSafari = sUserAgent.indexOf("AppleWebKit") > -1; 
	isKonq = sUserAgent.indexOf("Konqueror") > -1; 
	if (isSafari) { 
		var reAppleWebKit = new RegExp("AppleWebKit///(//d+(?://.//d*)?)"); 
		reAppleWebKit.test(sUserAgent); 
		var fAppleWebKitVersion = parseFloat(RegExp["$1"]); 
		isMinSafari1 = fAppleWebKitVersion >= 85; 
		isMinSafari1_2 = fAppleWebKitVersion >= 124; 
	} else if (isKonq) { 
		var reKonq = new RegExp("Konqueror///(//d+(?://.//d+(?://.//d)?)?)"); 
		reKonq.test(sUserAgent); 
		isMinKonq2_2 = compareVersions(RegExp["$1"], "2.2") >= 0; 
		isMinKonq3 = compareVersions(RegExp["$1"], "3.0") >= 0; 
		isMinKonq3_1 = compareVersions(RegExp["$1"], "3.1") >= 0; 
		isMinKonq3_2 = compareVersions(RegExp["$1"], "3.2") >= 0; 
	} 
} 
var isIE = sUserAgent.indexOf("compatible") > -1 && sUserAgent.indexOf("MSIE") > -1 && !isOpera; 
var isMinIE4 = isMinIE5 = isMinIE5_5 = isMinIE6 = false; 
if (isIE) { 
	var reIE = new RegExp("MSIE (//d+//.//d+);"); 
	reIE.test(sUserAgent); 
	var fIEVersion = parseFloat(RegExp["$1"]); 
	isMinIE4 = fIEVersion >= 4; 
	isMinIE5 = fIEVersion >= 5; 
	isMinIE5_5 = fIEVersion >= 5.5; 
	isMinIE6 = fIEVersion >= 6.0; 
} 
var isMoz = sUserAgent.indexOf("Gecko") > -1 
&& !isKHTML; 
var isMinMoz1 = sMinMoz1_4 = isMinMoz1_5 = false; 
if (isMoz) { 
	var reMoz = new RegExp("rv:(//d+//.//d+(?://.//d+)?)"); 
	reMoz.test(sUserAgent); 
	isMinMoz1 = compareVersions(RegExp["$1"], "1.0") >= 0; 
	isMinMoz1_4 = compareVersions(RegExp["$1"], "1.4") >= 0; 
	isMinMoz1_5 = compareVersions(RegExp["$1"], "1.5") >= 0; 
} 
var isNS4 = !isIE && !isOpera && !isMoz && !isKHTML && (sUserAgent.indexOf("Mozilla") == 0) && (navigator.appName == "Netscape") && (fAppVersion >= 4.0 && fAppVersion < 5.0); 
var isMinNS4 = isMinNS4_5 = isMinNS4_7 = isMinNS4_8 = false; 
if (isNS4) { 
	isMinNS4 = true; 
	isMinNS4_5 = fAppVersion >= 4.5; 
	isMinNS4_7 = fAppVersion >= 4.7; 
	isMinNS4_8 = fAppVersion >= 4.8; 
} 
var isWin = (navigator.platform == "Win32") || (navigator.platform == "Windows"); 
var isMac = (navigator.platform == "Mac68K") || (navigator.platform == "MacPPC") || (navigator.platform == "Macintosh"); 
var isUnix = (navigator.platform == "X11") && !isWin && !isMac; 
var isWin95 = isWin98 = isWinNT4 = isWin2K = isWinME = isWinXP = false; 
var isMac68K = isMacPPC = false; 
var isSunOS = isMinSunOS4 = isMinSunOS5 = isMinSunOS5_5 = false; 
if (isWin) { 
	isWin95 = sUserAgent.indexOf("Win95") > -1 || sUserAgent.indexOf("Windows 95") > -1; 
	isWin98 = sUserAgent.indexOf("Win98") > -1 || sUserAgent.indexOf("Windows 98") > -1; 
	isWinME = sUserAgent.indexOf("Win 9x 4.90") > -1 || sUserAgent.indexOf("Windows ME") > -1; 
	isWin2K = sUserAgent.indexOf("Windows NT 5.0") > -1 || sUserAgent.indexOf("Windows 2000") > -1; 
	isWinXP = sUserAgent.indexOf("Windows NT 5.1") > -1 || sUserAgent.indexOf("Windows XP") > -1; 
	isWinNT4 = sUserAgent.indexOf("WinNT") > -1 || sUserAgent.indexOf("Windows NT") > -1 || sUserAgent.indexOf("WinNT4.0") > -1 
	|| sUserAgent.indexOf("Windows NT 4.0") > -1 && (!isWinME && !isWin2K && !isWinXP); 
} 
if (isMac) { 
	isMac68K = sUserAgent.indexOf("Mac_68000") > -1 || sUserAgent.indexOf("68K") > -1; 
	isMacPPC = sUserAgent.indexOf("Mac_PowerPC") > -1 || sUserAgent.indexOf("PPC") > -1; 
} 
if (isUnix) { 
	isSunOS = sUserAgent.indexOf("SunOS") > -1; 
	if (isSunOS) { 
	var reSunOS = new RegExp("SunOS (//d+//.//d+(?://.//d+)?)"); 
	reSunOS.test(sUserAgent); 
	isMinSunOS4 = compareVersions(RegExp["$1"], "4.0") >= 0; 
	isMinSunOS5 = compareVersions(RegExp["$1"], "5.0") >= 0; 
	isMinSunOS5_5 = compareVersions(RegExp["$1"], "5.5") >= 0; 
} 
screen對象:用於獲取某些關於用戶屏幕的信息,也可用window.screen引用它
screen.width/height  //屏幕的寬度與高度,以像素計
screen.availWidth/availHeight  //窗口可以使用的屏幕的寬度和高度,以像素計
screen.colorDepth  //用戶表示顏色的位數,大多數系統採用32位
	window.moveTo(0, 0);
	window.resizeTo(screen.availWidth, screen.availHeight);  //填充用戶的屏幕

三、文檔對象模型DOMTop

文檔對象模型DOM是HTML和XML的應用程序接口(API),DOM把整個頁面規劃面由節點層級構成的文檔,HTML或XML頁面的每個部分都是一個節點的衍生物。DOM通過創建樹來表示文檔,描述了處理網頁內容的方法和接口,從而使開發者對文檔的內容和結構具有空前的控制力,用DOM API可以輕鬆地刪除、添加和替換節點。

1. 訪問節點
var oHtml = document.documentElement;  //返回存在於 XML 以及 HTML 文檔中的文檔根節點,oHtml包含了一個表示<html />的HTMLElement對象
var oHead = oHtml.firstChild | oHtml.childNodes[0] | oHtml.childNodes.item(0);
var oBody = oHtml.lastChild | oHtml.childNodes[1] | oHtml.childNodes.item(1);
document.body  //是對 HTML 頁面的特殊擴展,提供了對 <body> 標籤的直接訪問
document.getElementById("ID");  //通過指定的 ID 來返回元素,getElementById() 無法工作在 XML 中,IE6還會返回name爲指定ID的元素
document.getElementByName("name");  //獲取所有name特性等於指定值的元素,不過在IE6和Opera7.5上還會返回id爲給定名稱的元素且僅檢查<input/>和<img/>元素
var x=document.getElementsByTagName("p");  //使用指定的標籤名返回所有的元素列表NodeList,索引號從0開始。當參數是一個星號的時候,IE6並不返回所有的元素,必須用document.all來替代它
for (var i=0;i<x.length;i++) { 
	// do something with each paragraph
}
2. Node節點的特性和方法
nodeName  //String,節點的名字,根據節點的類型而定義
nodeValue  //String,節點的值,根據節點的類型而定義
nodeType  //Number,節點的類型常量值之一
	在IE中,不支持noteType常量,但可以通過定義匹配節點類型的常量來糾正這種情況。如:
	if(typeof Node == "undefined"){
		var Node = {
			ELEMENT_NODE: 1,  //元素
			ATTRIBUTE_NODE: 2,  //屬性
			TEXT_NODE: 3,  //文本
			CDATA_SECTION_NODE: 4,  //CDATA段
			ENTITY_REFERENCE_NODE: 5,  //DTD中實體的引用
			ENTITY_NODE: 6,  //DTD中的一個實體
			PROCESSING_INSTRUCTION_NODE: 7,
			COMMENT_NODE: 8,  //註釋
			DOCUMENT_NODE: 9,  //文檔
			DOCUMENT_TYPE_NODE: 10,  //DTD引用,如<! DOCTYPE..>
			DOCUMENT_FRAGMENT_NODE: 11,  //文檔碎片
			NOTATION_NODE: 12  //DTD中定義的記號
		}
	}
ownerDocument  //Document,指向這個節點所屬的文檔
firstChild  //Node,指向在childNodes列表中的第一個節點
lastChild  //Node,指向在childNodes列表中的最後一個節點
parentNode  //Node,指向父節點
childNodes  //NodeList,所有子節點的列表
previousSibling  /Node,/指向前一個兄弟節點:如果這個節點就是第一個節點,那麼該值爲null
nextSibling  //Node,指向後一個兄弟節點:如果這個節點就是最後一個節點,那麼該值爲null
hasChildNodes()  //Boolean,當childNodes包含一個或多個節點時,返回真
attributes  //NamedNodeMap,包含了代表一個元素的特性的Attr對象;僅用於Element節點
	length  //指示它所包含的節點的數量
	getNamedItem(name)  //返回nodeName屬性值等於name的節點
	removeNamedItem(name)  //刪除nodeName屬性值等於name的節點
	setNamedItem(node)  //將node添加到列表中,按其nodeName屬性進行索引
	item(pos)  //像NodeList一樣,返回在位置pos的節點
	getAttribute(name) == attributes.getNamedItem(name).value == attributes.item[0].nodeValue
	setAttribute(name, newValue) == attributes.getNamedItem(name).value = newValue
	removeAttribute(name) == attributes.removeNamedItem(name)
	核心DOM的oImg.getAttribute("src")等價於HTML DOM的oImg.src(在IE在最好使用這種方式),class屬性會有點不同,分別對應class和className
appendChild(node)  //Node,將node添加到childNodes的末尾
removeChild(node)  //Node,從childNodes中刪除node
replaceChild(newNode, oldNode)  //Node,將childNodes中的oldNode替換成newNode
insertBefore(newNode, refNode)  //Node,在childNodes中的refNode之前插入newNode
3. 創建和操作節點
document.createAttribute(name)  //用指定名稱name創建特性節點
document.createCDATASection(text)  //用包含文本text的文本子節點創建一個CDATA Section
document.createComment(text)  //創建包含文本text的註釋節點
document.createEntityReference(name)  //創建給定名稱的實體引用節點
document.createProcessingInstruction(target, data)  //創建包含給定target和data的PI節點
document.createDocuemntFragment()  //創建文檔碎片節點,常用且所有瀏覽器支持。
document.createElement(tagName)  //創建標籤名爲tagName的元素,常用且所有瀏覽器支持。
document.createTextNode(text)  //創建包含文本text的文本節點,常用且所有瀏覽器支持。
舉例:
var arrText = ["first","second","third","fourth","fifth","sixth","seventh"];
var oFragment = document.createDocumentFragment();
for(var i=0; i<arrText.length; i++){
	var oP = document.createElement("p");
	var oText = document.createTextNode("Hello World");
	oP.appendChild(oText);
	oFragment.appendChild(oP);  //使用碎片將減少屏幕刷新,不然將調用n次document.body.appendChild,頁面刷新n次
}
document.body.appendChild(oFragment);
document.body.removeChild(oP); 
4. HTML DOM的table特性和方法
給<table />元素添加了以下內容:
caption  //指向<caption />元素(如果存在)
tBodies  //<tdody/>元素的集合
tFoot  //指向<tfoot/>元素(如果存在)
tHead  //指向<thead/>元素(如果存在)
rows  //表格中所有行的集合
createTHead()/deleteTHead()  //創建和刪除<thead />元素並將其放入表格
createTFoot()/deleteTFoot()  //創建和刪除<tfoot />元素並將其放入表格
createCaption()/deleteCaption()  //創建和刪除<caption />元素並將其放入表格
insertRow(pos)/deleteRow(pos)  //在rows集合中的指定位置上插入一個新行和刪除指定位置上的行

給<body />元素添加了以下內容:
rows  //<tbody />中所有行的集合
insertRow(pos)/deleteRow(pos)  //在rows集合中的指定位置上插入一個新行和刪除指定位置上的行

給<tr />元素添加了以下內容:
cells  //<tr />元素中所有單元格的集合
insertCell(pos)/deleteCell(pos)  //在cells集合中的指定位置上插入一個新單元格和刪除指定位置上的單元格

舉例:
var oTable = document.createElement("table");
oTable.setAttribute("border","1");
oTable.setAttribute("width","100%");
var oTBody = document.createElement("tbody");
oTable.appendChild(oTBody);
oTBody.insertRow(0);
oTBody.rows[0].insertCell(0);
oTBody.rows[0].cells[0].appendChild(document.createTextNode("cell 1,1"));
oTBody.rows[0].insertCell(1);
oTBody.rows[0].cells[1].appendChild(document.createTextNode("cell 2,1"));
oTBody.insertRow(1);
oTBody.rows[1].insertCell(0);
oTBody.rows[1].cells[0].appendChild(document.createTextNode("cell 1,2"));
oTBody.rows[1].insertCell(1);
oTBody.rows[1].cells[1].appendChild(document.createTextNode("cell 2,2"));
document.body.appendChild(oTable);

5. DOM事件

DOM同時兩種事件模型:冒泡型事件和捕獲型事件
冒泡型事件:事件按照從最特定的事件目標到最不特定的事件目標的順序觸發
<body onclick="handleClick()">
	<div onclick="handleClick()">Click Me</div>
</body>
觸發的順序是:div、body、html(IE 6.0和Mozilla 1.0)、document、window(Mozilla 1.0)

捕獲型事件:與冒泡事件相反的過程,事件從最不精確的對象開始觸發,然後到最精確
上面例子觸發的順序是:document、div
DOM事件模型最獨特的性質是,文本節點也觸發事件(在IE中不會)。 
事件處理函數/監聽函數
在JavaScript中:
var oDiv = document.getElementById("div1");
oDiv.onclick = function(){  //onclick只能用小寫,默認爲冒泡型事件
	alert("Clicked!");
}
在HTML中:
<div onclick="javascript: alert("Clicked!")"></div>  //onclick大小寫任意
在IE中,每個元素和window對象都有兩個方法:attachEvent()和detachEvent(),如:
[object].attachEvent("name_of_event_handler","function_to_attach")
[object].detachEvent("name_of_event_handler","function_to_remove")
var fnClick = function(){
	alert("Clicked!");
}
oDiv.attachEvent("onclick", fnClick);  //添加事件處理函數
oDiv.attachEvent("onclick", fnClickAnother);  // 可以添加多個事件處理函數
oDiv.detachEvent("onclick", fnClick);  //移除事件處理函數
在DOM中,addEventListener()和removeEventListener()用來分配和移除事件處理函數,與IE不同的是,這些方法需要三個參數:事件名稱,要分配的函數和處理函數是用於冒泡階段(false)還是捕獲階段(true),默認爲冒泡階段false
[object].addEventListener("name_of_event",fnhander,bcapture)
[object].removeEventListener("name_of_event",fnhander,bcapture)
var fnClick = function(){
	alert("Clicked!");
}
oDiv.addEventListener("onclick", fnClick, false);  //添加事件處理函數
oDiv.addEventListener("onclick", fnClickAnother, false);  // 與IE一樣,可以添加多個事件處理函數
oDiv.removeEventListener("onclick", fnClick, false);  //移除事件處理函數
如果使用addEventListener()將事件處理函數加入到捕獲階段,則必須在removeEventListener()中指明是捕獲階段,才能正確地將這個事件處理函數刪除
oDiv.onclick = fnClick;
oDiv.onclick = fnClickAnother;  //使用直接賦值,後續的事件處理函數會覆蓋前面的處理函數
oDiv.onclick = fnClick;  
oDiv.addEventListener("onclick", fnClickAnother, false);  //會按順序進行調用,不會覆蓋
事件類型
鼠標事件:click、dbclick、mousedown、mouseup、mouseover、mouseout、mousemove
鍵盤事件:keydown、keypress、keyup
HTML事件:load、unload、abort、error、select、change、submit、reset、resize、scroll、focus、blur
事件對象,包括引起事件的對象、事件發生時鼠標的信息、事件發生時鍵盤的信息
相似性
oEvent.type  //可以在任何一種瀏覽器中獲取事件的類型,如:click、mouseover
oEvent.keyCode  //在keydown和keyup事件中獲取按下的按鍵的數值代碼,如:回車爲13,空格爲32,回退爲8
oEvent.button  //0爲未按下按鈕,1爲左鍵,2爲右鍵,3爲左右鍵,4爲中鍵,5爲左中鍵,6爲右中鍵,7爲左中右鍵
oEvent.shiftKey  //Shift鍵
oEvent.altKey  //Alt鍵
oEvent.ctrlKey  //Ctrl鍵
oEvent.X/oEvent.Y  //在鼠標事件中,獲取鼠標指針在客戶端的區域的位置,不含工具欄和滾動條等
oEvent.screenX/oEvent.screenY  //在鼠標事件中,獲取鼠標指針在計算機屏幕的位置
DOM中還有charCode、bubbles(事件是否正在冒泡階段中)、currentTarget、relatedTarget、detail(鼠標點擊次數)、eventPhase(0捕獲1在目標上2冒泡)、calcelable(事件能否取消)、isChar、meatKey(META鍵)、pageX(鼠標相對於頁面的xy座標)、pageY、timeStamp(事件發生時間)、preventDefault()、stopPropagation()、target等IE中沒有的屬性和方法。
IE中還有returnValue、fromElement、toElement、calcelBubble、srcElement、offsetX(鼠標相對於引起事件對象的xy座標)、offsetY、repeat(不觸發keydown事件時爲true)等DOM中沒有的屬性和方法。
區別
a. 事件對象的定位
在IE中,事件對象是windows對象的一個屬性event,事件處理函數必須這樣訪問事件對象:
oDiv.onclick = function(){
	var oEvent = window.event;
}
在DOM中,event對象必須作爲唯一的參數傳遞給事件處理函數,所以要這麼做:
oDiv.onclick = function(){
	var oEvent = argunments[0];  //在arguments屬性,在event對象中總是事件處理函數的第一個參數
}
或者 oDiv.onclick = function(oEvent){ ... }
所以要用不同的方法來獲取event對象,所以我們經常見到這種寫法:var e =  event || window.event
b. 獲取事件源
在IE中,目標包含在event對象的srcElement屬性中:
	var oTarget = oEvent.srcElement;
在DOM中,目標包含在target屬性中:
	var oTarget = oEvent.target;
IE目標只能是元素、文檔或者窗口;DOM兼容的瀏覽器也允許把文本節點作爲目標
c. 獲取字符代碼
IE和DOM都支持event對象的keyCode屬性,它會返回按下按鍵的數值代碼
在IE中:var oCharCode = oEvent.keyCode;
在DOM中:var oCharCode = oEvent.charCode;
d. 阻止默認行爲
function someHandle(event) { 
	var event = event || window.event; 
	if(event.preventDefault)
		event.preventDefault();  //DOM
	else 
		event.returnValue = false;  //IE
}
e. 停止事件冒泡
function someHandle(event){ 
var event = event || window.event; 
	if(event.stopPropagation)
		event.stopPropagation();  //DOM
	else 
		event.cancelBubble = true; //IE
}
跨平臺的事件對象
var EventUtil = new Object;
EventUtil.addEventHandler = function(element, evtName, callback, useCapture) { 
	if (element.addEventListener)
		element.addEventListener(evtName, callback, useCapture); //DOM
	else if(element.attachEvent)
		element.attachEvent("on" + evtName, callback); //IE
	else
		element["on" + evtName] = callback;
}
EventUtil.removeEventHandler = function(element, evtName, callback, useCapture) { 
	if (element.removeEventListener)
		element.removeEventListener(evtName, callback, useCapture); //DOM
	else if(element.attachEvent)
		element.dettachEvent('on' + evtName, callback); //IE
	else
		element["on" + evtName] = null;
}
EventUtil.formatEvent = function(oEvent){
	if(isIE && isWin){
		oEvent.charCode = (oEvent.type == "keypress") ? oEvent.keyCode : 0;
		oEvent.eventPhase = 2; //IE僅支持2冒泡事件
		oEvent.isChar = (oEvent.charCode > 0);
		oEvent.pageX = oEvent.clientX + document.body.scrollLeft;
		oEvent.pageY = oEvent.clientY + document.body.scrollTop;
		oEvent.preventDefault = function(){ this.returnValue = false; }
		if(oEvent.type == "mouseout")
			oEvent.relatedTarget = oEvent.toElement;
		else if(oEvent.type == "mouseover")
			oEvent.relatedTarget = oEvent.fromElement;
		oEvent.stopPropagation = function(){ this.cancelBubble = true; }
		oEvent.target = oEvent.srcElement;
		oEvent.timestamp = (new Date()).getTime();
	}
	retrun oEvent;
}
EventUtil.getEvent = function(){
	if(window.event)
		return this.formatEvent(window.event);
	else
		return EventUtil.getEvent.caller.arguments[0]; //指向DOM中調用getEvent的函數中的event對象
}
oDiv.onclick = function(){
	var oEvent = EventUtil.getEvent;
	...
}
6. 樣式編程 - style對象
var oDiv = document.getElementById("div1");
oDiv.style.border = "1px solid black";
在style對象中,兩個單詞的樣式的表示方式是通過將第一個單詞加上首字母大寫的第二單詞,且單詞間沒有橫線一表示的,如:background-color就寫作style.backgroundColor
style對象還包含cssText特性,包含了所有描述樣式的CSS字符串,如:
	oDiv.style.cssText = "width:400px; height:300px;";
在DOM中,還描述了一些樣式對象的方法,以達到與單獨的CSS樣式的定義部分進行交互的目的,這些屬性在IE中不支持
	getPropertyValue(propertyName)  //返回CSS特性propertyName的字符串值,如:background-color
	getPropertyPriority()  //如果在規則中指定CSS特性"important",則返回"important",否則返回空字符串
	item(index)  //返回指定索引index處的CSS特性名稱,如:background-color
	removeProperty(propertyName)  //從CSS定義中刪除propertyName
	setProperty(propertyName, value, priority)  //按照指定的優先級來設置CSS特性propertyName的value值
style對象可以方便地獲取某個有style特性的元素的CSS樣式,但是無法表示由CSS規則或者在style特性外部定義的類定義的元素的CSS樣式,這時可以通過document.styleSheets來實現,這個集合包含了HTML頁面中所有樣式表的引用和所有的<style />元素,有以下特性:
	disabled  //表示樣式表是否被禁用
	href  //用於外部引用文件樣式表的URL,對於<style />元素返回null,不過Mozilla返回當前頁面的URL
	media  //可以使用該樣式表的媒體類型,由HTML的media特性指定
	ownerNode  //指定樣式表的DOM節點(<link />或者<style />元素),IE不運行這個特性
	parentStyleSheet  //如果樣式表是通過CSS的@import語句來加載的,將指出出現@import語句的樣式表
	title  //通過HTML title特性分配給樣式表的標題,可用在(<link />或者<style />上
	type  //樣式表的mime類型,對於CSS通常是text/css
在IE中有一個currentStyle對象,包含了所有元素的style對象的特性和任何未被覆蓋的CSS規則的style特性,與style對象的使用方式、特性和方法都完全一樣。如:
	alert(oDiv.currentStyle.backgroundColor);
DOM提供一個getComputedStyle()方法,根據給定的元素創建類似style對象。如:
	alert(document.defaultView.getComputedStyle(oDiv, null).backgroundColor);
innerText: 表示起始標籤和結束標籤之間的文本
innerHTML: 表示元素的所有元素和文本的HTML代碼
如:<div><b>Hello</b> world</div>的innerText爲Hello world,innerHTML爲<b>Hello</b> world
outerText: 與前者的區別是替換的是整個目標節點,問題返回和innerText一樣的內容
outerHTML: 與前者的區別是替換的是整個目標節點,返回元素完整的HTML代碼,包括元素本身
如:<div><b>Hello</b> world</div>的outerText爲Hello world,outerHTML爲<div><b>Hello</b> world</div>

 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章