JavaScript學習筆記+常用js用法、范例


Java Script 基礎
一、 JS的簡介
JavaScript是一種網頁編程技術,經常用於創建動態交互網頁
JavaScript是一種基於對象和事件驅動的解釋性腳本語言,類似C語言和Java的語法
事先不編譯;逐行執行;無需進行嚴格的變量聲明;內置大量現成對象,編寫少量程序可以完成目標
不同的瀏覽器甚至同一瀏覽器的不同版本對JavaScript的支持程度都不一樣

二、 JS的基本語法
0. 有兩種JavaScript寫法:
a. 直接在 html 中嵌入,程序寫法:
<script type="text/javascript" language="JavaScript" charset="UTF-8">
<!--
...javaScript程序...
// -->
</script>
b. 調用獨立JavaScript文件:在html中寫 <script type="text/javascript" src="test1.js"> </script>
<script> 不能用空標志。 JS腳本文件中不需要腳本開始和結束聲明,直接寫 function

1. 在HTML中大小寫是不敏感的,但標准的JavaScript是區分大小寫的

2. 分號表示語句結束。有換行,分號允許不加(建議加上,以免錯誤和歧義)
程序忽略縮進:提倡加上空格或TAB增強程序可讀性

3. 標識符:成份是 不以數字開頭的字母、數字 和下划線(_)、美元符($)
ECMA v3標准保留的JavaScript的關鍵字:
break case catch continue default delete do else false finally
for function if in instanceof new null return switch this
throw true try typeof var void while with

4. 變量的聲明: var x,y; (變量沒類型;未聲明的變量也可以用,且是全局的;函數體內聲明的變量則是局部的)
x=1; y="hello world!"; (變量的類型由所賦的值決定)

5. 函數: function 函數名 (參數){ 函數體; return 返回值;}
參數沒類型或順序,且可變長;可以使用變量、常量或表達式作為函數調用的參數
聲明函數時,參數可不明寫,調用時用 arguments[number] 接收。參數是值傳遞的。
函數由關鍵字 function 定義; 函數名的定義規則與標識符一致,大小寫是敏感的
返回任意類型(不需寫返回類型); 返回值必須使用return
//參數數量是可變的,若要限定參數數量,如下做法: (指定參數數量為0)
if ( arguments.length !== 0 ) throw Error.parameterCount();
caller: 調用此函數的函數。沒有被調用則此變量為 null
arguments: 此函數的參數列表。
arguments.caller: 調用此函數的參數列表,沒有被調用則為 undefined
arguments.callee: 此函數本身的一個引用。在匿名函數里會需要用到。


6. 數據類型:
基本類型: Number:數字、 String:字符串、 Boolean:布爾
特殊類型: Null:空、 Undefined:未定義
組合類型: Array:數組、 Object:對象

7. Number 數值類型:所有數字都采用64位浮點格式存儲,相當於Java和C語言中的double格式
能表示的最大值是 ±1.7976931348623157 x 10^308;能表示的最小值是 ±5 x 10^ -324
10進制的整數的精確表達的范圍是 -9007199254740992 (-2^53) 到 9007199254740992 (2^53)
16進制數據前面加上0x,八進制前面加0
保留多少位小數: var a = 111.115555; var b = a.toFixed(2); alert(b + ' : ' + typeof b); // 111.12 : string

8. String 類型:字符串常量首尾由單引號或雙引號括起
沒有字符,只有字符串(所有字符都按字符串處理)
常用轉義符: \n換行 \'單引號 \"雙引號 \\右斜桿 (字符串中部分特殊字符必須加上右划線\)
漢字常使用特殊字符寫,如: \u4f60 -->"你" \u597d -->"好" (可避免亂碼)

9. Boolean 類型:僅有兩個值:true和false,實際運算中true=1,false=0
也可以看作on/off、yes/no、1/0對應true/false;主要用於JavaScript的控制語句

10.null, undefine 類型:
null 在程序中代表變量沒有值;或者不是一個對象
undefined 代表變量的值尚未指定;或者對象屬性根本不存在
有趣的比較:
null 與空字符串: 不相等, null 代表什么也沒有,空字符串則代表一個為空的字符串
null 與 false : 不相等, 但是 !null 等於 true
null 與 0 : 不相等,(但是在C++等其它語言中是相等的)
null 與 undefined : 相等,但是 null 與 undefined 並不相同

11.數據類型轉換:JavaScript屬於松散類型的程序語言
變量在聲明的時候並不需要指定數據類型;變量只有在賦值的時候才會確定數據類型
表達式中包含不同類型數據則在計算過程中會強制進行類別轉換(優先級:布爾-->數字-->字符)
數字 + 字符串:數字轉換為字符串
數字 + 布爾值:true轉換為1,false轉換為0
字符串 + 布爾值:布爾值轉換為字符串true或false
函數 parseInt: 強制轉換成整數(如果包含字符串,則轉換到字符串為止,后面不再理) //如 parseInt("13a2")=13
函數 parseFloat: 強制轉換成浮點數
函數 eval: 將字符串強制轉換為表達式並返回結果,亦可將字節或變量轉成數值。
函數 typeof: 查詢數據當前類型(string / number / boolean / object ) ,未定義則返回“undefined”

12.運算符:(同java)
算術運算符: 加/字符連接(+)、 減/負號(-)、 乘(*) 、除(/)、 余數(% ); 遞增(++)、 遞減(--)
邏輯運算符: 等於( == )、 不等於( != ) 、 大於( > ) 、 小於( < ) ; 大於等於(>=) 、小於等於(<=)
與(&&) 、或(||) 、非(!) ; 恆等(===)、不恆等(!==)
位運算符: 左移(<<) 、有符號右移(>>);無符號右移(>>>)
位與(&) 、位或(|)、異或(^) 、NOT (~)
賦值運算符: 賦值(=) 、復合賦值(+= -= *= /= %= &= )
(先運行完右邊的,再跟左邊的進行賦值運算;如 var i=10;i-=5-3;結果8)

13.選擇控制語句(同java)
if(...){...} else{...} if 語句允許不使用else子句;允許進行嵌套
switch(表達式){case 值1:語句1;break; case 值2:語句2;break; default:語句3;}

14.循環控制語句(類似java)
for (初始化;條件;增量){ 語句1; ... }
for-each遍歷: for(var key in objs){var element=objs[key];...} // 注意: in 前面的是 key,而不是下標或者集合里面的元素,獲取集合里的元素要使用 集合[key]
while (條件){ 語句1; ... }
do{語句1; ...}while(條件);
break, continue 跳出循環;還可配合標簽使用

15.對象:JavaScript是一種基於對象語言,對象是JavaScript中最重要的元素
對象由屬性和方法封裝而成
javaScript包含四種對象:
內置對象 Date
自定義對象 Cart
瀏覽器對象 window
ActiveX對象 ActionXObject

16. 異常處理:
try{ ... } catch( e ) { ... } finally { ... }
try{ throw new Error("Err0"); } catch( e ) { alert(e.description); } finally { ... }
try{ throw "Err1"; } catch( e ) { if(e == "Err1") alert("錯誤!"); }
try{ ... } catch( e ) { alert(e.message || e.description); } // 查看出錯提示

17.選取頁面的對象:
var obj = document.forms["FormName"].elements["elementName"];
var obj = document.forms[x].elements[y]; //x和y 是int類型,表示第幾個表單,第幾個元素
var obj = document.FormName.elementName;
var obj = document.all["elementName"];
var obj = document.all["elementID"];
var obj = document.getElementById("elementID");
var obj = document.getElementsByName("elementName"); //返回數組
var obj = document.getElementsByTagName("TagName"); //返回數組

18. typeof 查看類型:
undefined, null, boolean, number, string, object, function
也就是 typeof 返回的值只能是上面的其中一個(字符串類型)。
注意:以上單詞都是小寫,不要與內置對象 Number, String, Object, Function 等混淆。
null: typeof(null) 返回 "object", 但null並非object, 具有 null 值的變量也並非object。未定義的返回"undefined"
number: typeof(NaN) 和 typeof(Infinity) 都返回 number; NaN參與任何數值的計算結果都是NaN,且 NaN != NaN, Infinity / Infinity = NaN

19.instanceof 判斷類型:
instanceof 返回一個 boolean 值, 指出對象是否是特定類的一個實例, 實際上就是檢測實例是否有繼承某類的原型鏈。
對於 Array, null 等特殊對象 typeof 一律返回 object,這正是 typeof 的局限性。
instanceof 用於判斷一個變量是否某個對象的實例,或者子類,如: var a=new Array();alert(a instanceof Array);會返回 true, 而 alert(a instanceof Object)也會返回 true
再如: function test(){};var a=new test();alert(a instanceof test)返回 true, alert(test instanceof Function)返回 true, 但 alert(a instanceof Function)返回 false(不明白什么原因)
注意: function 的 arguments, 使用(arguments instanceof Array)返回 false,盡管看起來很像。
另外: (window instanceof Object)返回 false, 這里的 instanceof 測試的 Object 是指js中的對象,不是dom模型對象。而 typeof(window) 會得 "object"

20.in 用法:
通常使用在 for 循環中,作 foreach 用,像 for(var i in obj)...
也可以用在類中,判斷類里面是否有此 key。但注意不能有效用在數組中。
如: var ar = {a:false, b:2}; alert('a' in ar)返回 true;因為 ar['a'] 存在。
在數組中使用時,如: var arr=[4,5,6]; alert(2 in arr)會返回 true,因為 arr[2] 存在。而 alert(5 in arr)會返回 false,arr[5] 不存在。
if (key in obj) 相當於 if(!!obj[key])。
數組中也可以使用 for in,如: var array = ['a', 'b', 'c', 'd'];for(var item in array){alert(array[item]);}
值得注意的是,如果對類進行 .prototype.函數 來擴展, for in 時會受到影響,把擴展的內容也循環出來。
所以不贊成對 Object 類進行擴展,也不贊成數組使用 for in(因為數組有可能被擴展了)

21.閉包(closure)
是一個擁有許多變量和綁定了這些變量的環境的表達式(通常是一個函數),因而這些變量也是該表達式的一部分。
1) 變量的作用域
函數內部可以直接讀取全局變量。(函數內部聲明變量的時候,一定要使用var命令。如果不用的話,你實際上聲明了一個全局變量!)
在函數外部無法讀取函數內的局部變量。
鏈式作用域(chain scope):子對象會一級一級地向上尋找所有父對象的變量。所以,父對象的所有變量,對子對象都是可見的,反之則不成立。
2) 閉包就是能夠讀取其他函數內部變量的函數。
由於在Javascript語言中,只有函數內部的子函數才能讀取局部變量,因此可以把閉包簡單理解成"定義在一個函數內部的函數"。
所以,在本質上,閉包就是將函數內部和函數外部連接起來的一座橋梁。
3) 閉包的最大用處有兩個,一個是可以讀取函數內部的變量,另一個就是避免外部修改這些變量的值。
4) 注意:
閉包使得函數中的變量都被保存在內存中,內存消耗很大,不能濫用,否則影響性能,可能導致內存泄露。解決方法是,在退出函數之前,將不使用的局部變量全部刪除。
閉包會在父函數外部,改變父函數內部變量的值。所以,如果你把父函數當作對象(object)使用,把閉包當作它的公用方法(Public Method),把內部變量當作它的私有屬性(private value),這時一定要小心,不要隨便改變父函數內部變量的值。

22.比較運算
1)“==” 與 “===” 的區別
“==” 雙等號, 用於比較時會忽略類型, 字符串可以與數字相等, null 與 undefined 相等
“===” 三等號, 用於比較時嚴格區分類型,類型不相同的不會認為相等
同理還有不等於( “!=” 與 “!==” ),比較規則與上面的一樣

示例:
alert( '22' == 22 ); // true
alert( '22' === 22 ); // false
alert( null == undefined ); // true
alert( null === undefined ); // false
alert( 0 == null ); // false, 注: null, undefined 這兩者與其它的比較都為false
alert( 1 == true ); // true
alert( 1 === true ); // false
alert( 0 == '' ); // true
alert( 0 === '' ); // false
alert( ' \t\r\n ' == 0 ); // true, 注: 空格、跳格、換行, 都會轉成 0 來處理
alert( [10] == 10 ); // true,注: 對象與基本類型比較時,會先把對象轉成基本類型。
alert( [10] == '10' ); // true
alert( /\d/ > 0 || /\d/ <= 0 ); // false, 無法轉換正則為數字
alert( {} > 0 || {} <= 0 ); // false, 無法轉換Object為數字
alert( NaN == NaN ); // false, NaN 與所有值都不相等,包括它自己。
alert( NaN > 0 || NaN <= 0 ); // false, NaN的比較都為false
alert( NaN > NaN || NaN <= NaN ); // false

2) 比較法則(僅忽略類型的比較,不是嚴格比較,比較運算符有: >, >=, <, <=, ==, !=):
對於基本類型 Boolean, Number, String 三者之間做比較時,總是向 Number進行類型轉換,然后再比較(String 類型的如果沒法轉成數字,則轉成 NaN);
如果有Object,那么將Object轉化成這三者,再進行比較(可以轉成數字的,優先轉成數字,像Date就轉成數字);
對於 null 和 undefined, 只有兩個都是它們時才相同,其他都為false。
比較對象、數組和函數時,進行引用比較,只有引用的是相同地址才認為相同,否則即使擁有相同的屬性和函數都認為不相同。
如果不能轉成數值,或者是NaN,則比較結果為false


三、 JS的內置對象
11種內置對象:Array, Boolean, Date, Math, Number , String
Error, Function, Global , Object, RegExp
在JavaScript中除了null和undefined以外其它的數據類型都被定義成了對象
可以用創建對象的方法定義變量; String、Math、Array、Date、RegExp是JavaScript中常用的對象
內置對象的分類:
數據對象: Number數據對象; String字符串對象; Boolean布爾值對象
組合對象: Array數組對象; Math數學對象; Date日期對象
高級對象: Object自定義對象;Error錯誤對象;Function函數對象; RegExp正則表達式對象;Global全局對象
自動創建對象:調用字符串的對象屬性或方法時自動創建對象,用完就丟棄。 如: var str1="hello world";
手工創建對象:采用new創建字符串對象str1,全局有效。 如:var str1= new String("hello word");

1. String 字符串對象:
格式編排:anchor()錨、blink()閃爍、fixed()固定、bold()粗體、italics()斜體、strike()刪除線
big()字變大、small()字變小、sub()下標、sup()上標;
fontcolor(color)字體顏色、fontsize(size)字體大小、link(url)超鏈接
大小寫轉換: toLowerCase()返回小寫字符串、toUpperCase()返回大寫字符串
獲取指定字符:charAt(index)返回指定位置字符、charCodeAt(index)返回指定位置字符Unicode編碼
用法:str1.bold();//字體變粗;相當於“<b>str1</b>“ str1.anchor(); //把str1標識為錨
子字符串處理:
截取:str1.substr(start,length); //返回從索引位置start開始長為length的子字符串
str1.substring(start,end); //返回start開始end結束的子字符串,不包括最后的一個
str1.slice(start,end); //同substring,但允許使用負數表示從后計算位置,不包括最后的一個
替換:str1.replace(findstr,tostr); //返回替換finstr為tostr之后的字符串
分割:str1.split(bystr); //返回由bystr分割成的字符串數組(通常bystr是連接符號,如逗號或橫桿)
連接:str1.concat(string2); //返回 str1 與 string2 連接后的字符串
查詢字符串: indexOf(findstr,index)返回正向的索引位置、lastIndexOf(findstr)返回反向的索引位置
match(regexp)返回匹配的字符串、search(regexp)返回找到字符串的首字符索引
用法:
str1.indexOf(findstr,index);//查找字符串findstr;從index位置開始的索引,省略index則從0開始找;類似下一句
str1.lastIndexOf(findstr); //從后面找起;返回findstr在str1中出現的首字符位置下標,沒有找到返回-1
str1.match(regexp); //regexp代表正則表達式或字符串;返回匹配字符串的數組,如果沒有匹配則返回null
str1.search(regexp); //返回匹配字符串的首字符位置下標;作用同indexOf方法,但可寫正則表達式
str1.length; //獲取字符串長度;漢字、字母長度均為1;返回大於或等於0的整數
2. Array 數組對象:
1) 創建數組:
var a = new Array(); a[0] = "元素1"; a[1] = "元素2";
var a = new Array(){"元素1", "元素2"};
var a = new Array("元素1","元素2"); //一維數組,效果同上
var a = new Array(); a[0] = new Array(); //二維數組
簡略的數組創建方法:
var a = ['元素1', '元素2']; // 效果等同於: var a = new Array("元素1","元素2");
2) 刪除數組: delete 數組名;
3) 數組操作:
arr.length; //獲取數組元素的個數;返回大於或等於0的整數
連接數組: (原數組不變)
arr.join(bystr); //把數組的各元素由bystr連接起來作為字符串;與字符串的split功能剛好相反
arr.toString(); //返回由逗號(,)連接數組元素組成的字符串
document.write(v.toString());document.write(v); //這兩句效果一樣
arr2 = arr.concat(元素, ...); //把元素添加到數組尾端后,返回另一數組;在參數里填入另一數組,返回合並數組
數組排序: (返回排序后的數組;改變原數組)
arr.reverse(); //按原順序倒着排序
arr.sort(); //按字典順序排序
獲取子數組: (返回被刪/被截取的元素數組)
arr.slice(start,end); //從start下標開始,截取到end;返回被截取的元素數組;不改變原數組
//start和end可用負數表倒數(-1代表最后一個元素);end<start時不截取;忽略end,截取start后的所有元素
arr.splice(start,n,value, ...); //從start下標開始刪除n個,再插入value(可理解為替換);改變原數組
//start為負數時表倒數;n<1表不刪除;可忽略value(不插入);可忽略n,表刪除后面所有;返回被刪元素數組
4) 棧:(數組的基礎; 改變原數組)
arr.pop(); //刪最后的一個元素;返回刪除的元素
arr.push(元素, ...); //添加元素到最后位置;返回數組長度; 等價於: arr[length] = newValue;
arr.unshift(元素, ...); //添加元素到最前位置(多個參數,則按參數順序同時插入);返回數組長度
arr.shift(); //刪最前的一個元素;返回被刪除的元素
5) toString 和 valueOf
把每一項都調用 toString 方法,然后用半角逗號(,)連接每一項。
如: var arr = [1,2,3,4,5]; alert(arr); //output:1,2,3,4,5
toLocaleString 方法在這里不做詳細說明了,他的效果與 toString 方法類似,只是每項調用 toLocateString 方法。
4. Math 數學對象:
都是數學常數:(可直接用)
Math.E (自然數) Math.LN2 (ln2) Math.LN10 (ln10) Math.LOG2E (log 2e)
Math.LOG10E (log e) Math.PI (圓周率) Math.SQRT1_2 (根號1/2) Math.SQRT2 (根號2)
三角函數:
Math.sin(x) 計算正弦值; (x在0~2π之間,返回值-1~1)
Math.cos(x) 計算余弦值; (x在0~2π之間,返回值-1~1)
Math.tan(x) 計算正切值; (x在0~2π之間,返回正切值)
反三角函數:
Math.asin(x) 計算反正弦值;(x在 -1與1之間,返回0~2π)
Math.acos(x) 計算反余弦值;(x在 -1與1之間,返回0~2π)
Math.atan(x) 計算反正切值;(x可以為任意值,返回 -π/2 ~π/2)
Math.atan2(y,x) 計算從X軸到一個點的角度;(y,x分別為點的縱坐標和橫坐標,返回-π ~π)
計算函數:
Math.sqrt(x) 計算平方根
Math.pow(x,y) 計算x^y
Math.exp(x) 計算e的指數 e^x
Math.log(x) 計算自然對數 (x為大於0的整數)
數值比較函數:
Math.abs(x) 計算絕對值
Math.max(x,y,...) 返回參數中最大的一個
Math.min(x,y,...) 返回參數中最小的一個
* Math.random() 返回0~1之間的一個隨機數 //若要整數時,如0~99的隨機數: n=parseInt(Math.random()*100);
Math.round(x) 返回舍入為最接近的整數(四舍五入,負數時五舍六入)
* Math.floor(x) 返回下舍入整數 (結果不大於x;正數時直接舍去小數,負數時 -1.1==-2 )
Math.ceil(x) 返回上舍入整數 (結果大於等於x)
5. Date 時間對象:
創建日期對象:
a.不指定參數時: var nowd1=new Date();document.write(nowd1.toLocaleString( ));
//顯示當前時間,如:2008年11月24日 星期一 19時23分21秒
//不用"toLocaleString()"則顯示: Mon Nov 24 2008 19:23:21 GMT+0800 (CST)
b.參數為日期字符串: var nowd2=new Date("2008/3/20 11:12");alert(nowd2.toLocaleString());
//顯示: 2008年03月20日 星期六 11時12分00秒
var nowd3=new Date("08/03/20 11:12");alert(nowd3.toLocaleString( ));
//顯示: 1920年08月03日 星期六 11時12分00秒 //按 月、日、年 的順序
c.參數為毫秒數: var nowd3=new Date(5000); alert(nowd3.toLocaleString( ));
//顯示: 1970年01月01日 星期四 08時00分05秒 //顯示本國的時間
alert(nowd3.toUTCString()); //顯示西方的時間: Thu, 01 Jan 1970 00:00:05 GMT
d.參數為年月日小時分鍾秒毫秒: var nowd4=new Date(2008,10,24,11,12,0,300);
alert(nowd4.toLocaleString( )); //毫秒並不直接顯示;月份參數從0~11,所以這里10對應11月份
//顯示: 2008年11月24日 星期一 11時12分00秒
獲取和設置日期、時間的方法:
getDate() setDate(day_of_month) 日期 (1~31)
getDay() 星期 (1~7; 沒set方法)
getMonth() setMonth (month) 月份 (0~11; 別忘加1)
getFullYear() setFullYear (year) 完整年份(-271820~275760)
getYear() setYear(year) 年 (范圍同上; 1900年計算為0)
getHours() setHours (hour) 小時 (0~23)
getMinutes() setMinutes (minute) 分鍾 (0~59)
getSeconds() setSeconds (second) 秒 (0~59)
getMilliseconds() setMillliseconds (ms) 毫秒(0-999)
getTime() setTime (allms) 累計毫秒數(從1970/1/1 00:00:00開始)
注意:set方法對任意整數有效,影響上一級的數;如setDate(-1)設為上個月30號。 但對小數沒效。
日期和時間的轉換:
getTimezoneOffset() 返回本地時間與GMT的時間差,以分鍾為單位(中國為-480;差8小時)
toUTCString() 返回國際標准時間字符串(默認)
toLocalString() 返回本地格式時間字符串
Date.parse(x) 返回累計毫秒數(從1970/1/1 00:00:00到x的本地時間,忽略秒以下的數字)
Date.UTC(x) 返回累計毫秒數(從1970/1/1 00:00:00到x的UTC時間) 不明UTC是什么

四、 自定義對象
1. 基本語法:
使用 function 指令定義。其屬性用“this.屬性名”定義。
如: function ObjectName(yName,yAge) {
this.name = yName;
this.age = yAge;
}
調用時:
var myObject = new ObjectName("kk",80); // ObjectName 里面的函數會被執行
document.write("name = " + myObject.name + "<br> age = " + myObject.age);

2. 使用簡略語句快速創建對象
1) 類
正常寫法:
var car = new Object();
car.color = "red";
car.wheels = 4;
car.hubcaps = "spinning";
簡略寫法:
var car = {
color: "red",
wheels:4,
hubcaps:"spinning"
}
對象 car 就此創建,不過需要特別注意,結束花括號前一定不要加 ";" 否則在 IE 會遇到很大麻煩。

2) 數組
正常數組是這樣寫的: var movies = new Array('Transformers','Transformers2','Avatar','Indiana Jones 4');
更簡潔的寫法是: var movies = ['Transformers', 'Transformers2', 'Avatar', 'Indiana Jones 4'];

3)關聯數組
這樣一個特別的東西。 你會發現很多代碼是這樣定義對象的:
var car = new Array();
car['colour'] = 'red';
car['wheels'] = 4;
car['hubcaps'] = 'spinning';
//遍歷的時候
for ( var key in car ) { alert(key + " : " + car[key]); }

3.匿名函數
var myFun = function(args1, args2){ alert('haha'); }
變量 myFun 指向一個匿名函數,這相當於創建函數 function myFun(args1, args2){ alert('haha'); }
由於 javascript 沒有類型,所以變量可以指向任意類型,也可以指向一個函數,對它來說都只是一片內存空間而已
匿名函數一般用在只有一次使用的情況下,也是可以傳遞參數的
如: element.onclick = function(){ alert(0); }

4.JavaScript原生函數
//要找一組數字中的最大數,如下,可以用一個循環
var numbers = [3,342,23,22,124];
var max = 0;
for(var i=0;i<numbers.length;i++){ if(numbers[i] > max){max = numbers[i];} }
alert(max);
//也可以用排序實現同樣的功能:
var numbers = [3,342,23,22,124];
numbers.sort(function(a,b){return b - a});
alert(numbers[0]);
//而最簡潔的寫法是:
Math.max(12,123,3,2,433,4); // returns 433
//你甚至可以使用Math.max來檢測瀏覽器支持哪個屬性:
var scrollTop = Math.max( document.documentElement.scrollTop, document.body.scrollTop );

5.如果你想給一個元素增加class樣式,可能原始的寫法是這樣的:
function addclass(elm,newclass) {
var c = elm.className;
elm.className = (c === '') ? newclass : c+' '+newclass;
}
//而更優雅的寫法是:
function addclass(elm,newclass){
var classes = elm.className.split(' ');
classes.push(newclass);
elm.className = classes.join(' ');
}

6.對象的繼承,一般的做法是復制所有屬性,但還有種方法,就是: Function.apply
函數的 apply 方法能劫持另外一個對象的方法,繼承另外一個對象的屬性
Function.apply(obj,args) 方法接收兩個參數
obj:這個對象將代替Function類里this對象
args:這個是數組,它將作為參數傳給Function(args-->arguments)

示范如:
function Person(name,age){ // 定義一個類,人類
this.name=name; //名字
this.age=age; //年齡
this.sayhello=function(){alert("hello " + this.name);};
}
function Print(){ // 顯示類的屬性
this.show=function(){
var msg=[];
for(var key in this){
if(typeof(this[key])!="function"){
msg.push([key,":",this[key]].join(""));
}
}
alert(msg.join(" "));
};
}
function Student(name,age,grade,school){ //學生類
Person.apply(this,arguments); // this 繼承 Person,具備了它的所有方法和屬性
Print.apply(this,arguments); // this 繼承 Print,具備了它的所有方法和屬性
this.grade=grade; //年級
this.school=school; //學校
}
var p1=new Person("jake",10);
p1.sayhello();
var s1=new Student("tom",13,6,"清華小學");
s1.show();
s1.sayhello();


JavaScript技術
一、 使用DHtml
DHTML
定義:使用JavaScript和CSS級聯樣式表操作HTML創造出各種動態視覺效果統稱為DHTML
DHTML = CSS + Html + JS
是一種瀏覽器端的動態網頁技術
DHTML對象模型(DOM)
將HTML標記、屬性和CSS樣式都對象化
可以動態存取HTML文檔中的所有元素
可以使用屬性name或id來存取或標記對象
改變元素內容或樣式后瀏覽器中顯示效果即時更新
DHTML對象模型包括瀏覽器對象模型和Document對象模型

Window對象的常用屬性:
* document 對象,代表窗口中顯示的HTML文檔
frames 窗口中框架對象的數組
* history 對象,代表瀏覽過窗口的歷史記錄
* location 對象,代表窗口文件地址,修改屬性可以調入新的網頁
* status (defaultStatus)窗口的狀態欄信息
closed 窗口是否關閉,關閉時該值為true
* name 窗口名稱,用於標識該窗口對象
opener 對象,是指打開當前窗口的window對象,如果當前窗口被用戶打開,則它的值為null
parent 對象,當前窗口是框架頁時指的是包含該框架頁的上一級框架窗口
top 對象,當前窗口是框架頁時指的是包含該框架頁的最外部的框架窗口
self 對象,指當前Window對象
window 對象,指當前Window對象,同self

Window對象的常用方法:
(使用這些方法時,通常不加window也沒區別;但在特定情況下必須加,如在內嵌頁面用open();)
* alert(sMsg); 彈出簡單對話框
confirm(sMsg); 選擇對話框
prompt(sMsg, sInit); 彈出輸入對話框
* close(); 關閉窗口
open(sURL, sName, sFeatures, bReplace); 打開窗口
print(); 打印窗口中網頁的內容
focus(); 設置焦點並執行 onfocus 事件的代碼。
blur(); 失去焦點並觸發 onblur 事件。
moveBy(iX, iY); 將窗口的位置移動指定 x 和 y 偏移值。
moveTo(iX, iY); 將窗口左上角的屏幕位置移動到指定的 x 和 y 位置。
resizeBy(iX, iY); 更改窗口的當前位置縮放指定的 x 和 y 偏移量。
resizeTo(iWidth, iHeight); 將窗口的大小更改為指定的寬度和高度值。
scrollBy(iX, iY); 將窗口滾動 x 和 y 偏移量。
scrollTo(iX, iY); 將窗口滾動到指定的 x 和 y 偏移量。
* setInterval(vCode,iMilliSeconds,sLanguage); 每經過指定毫秒值后執行一段代碼。
clearInterval(iIntervalID); 取消 setInterval 方法的事件。
* setTimeout(vCode,iMilliSeconds,sLanguage); 經過指定毫秒值后執行一段代碼。(一次性)
clearTimeout(iTimeoutID); 取消 setTimeout 方法設置的超時事件。

window主要功能:
1.窗口的打開和關閉
window.open(url,name,config) 打開新窗口;url:打開的超鏈接,name:窗口的名稱,返回新窗口對象
config為窗口的配置參數:menubar 菜單條、toolbar 工具條、location 地址欄、directories 鏈接、
status 狀態欄、scrollbars 滾動條、resizeable 可調整大小(以上參數值為yes或no,默認yes);
width 窗口寬,以像素為單位;height 窗口高,以像素為單位(參數值為數值)
* window.close() 關閉窗口
2.對話框
簡單對話框:
alert(str) 提示框,顯示str字符串的內容;按[確定]關閉對話框
confirm(str) 確認對話框,顯示str字符串的內容;按[確定]按鈕返回true,[取消]返回false
prompt(str,value) 輸入對話框,顯示str的內容;按[確定]按鈕返回輸入值,[取消]關閉,返回null
窗口對話框:
showModalDialog(url,arguments,config) IE4或更高版本支持該方法
showModelessDialog(url,arguments,config) IE5或更高版本支持該方法
參數:url 打開鏈接,arguments 傳入參數名,config 窗口配置參數
config 外觀配置參數:status、resizable、help 是否顯示標題欄中的問號按鈕、center 是否在桌面中間
dialogWidth 對話框寬、dialogHeight 對話框高、(上一行參數值為yes或no,這兩行參數為多少像素)
dialogTop 對話框左上角的y坐標、dialogLeft 對話框左上角的x坐標
3.狀態欄
window.status 狀態欄中的字符串信息允許進行設置或讀取
4.定時器
tID1=setInterval(exp,time) 周期性執行exp代碼;exp 代碼塊名,time 周期(毫秒),返回啟動的定時器
clearInterval(tID1) 停止周期性的定時器
tID2=setTimeout(exp,time) 一次性觸發執行代碼exp;返回已經啟動的定時器
clearTimeout(tID2) 停止一次性觸發的定時器
5.內容滾動
window.scroll(x,y) 滾動窗口到指定位置;單位為像素
window.scrollTo(x,y) 同scroll方法
window.scrollBy(ax,ay) 從當前位置開始,向右滾動ax像素,向下滾動ay像素
6.調整窗口大小和位置
window.moveTo(x,y) 移動窗口到指定位置;單位為像素
window.moveBy(ax,ay) 向右移動ax像素,向下移動ay像素,參數為負數表示反方向移動
window.resizeTo(width,height) 調整窗口大小為指定大小
window.resizeBy(ax,ay) 放大或縮小窗口;參數為負數表示縮小
7.Screen對象 // 屏幕信息(屬於window的子對象;常用於獲取屏幕的分辨率和色彩)
screen.width 屏幕分辨率的寬度,例如1024*768分辨率下寬度為1024
screen.height 類似上面,屏幕分辨率的高度
screen.availWidth 屏幕中可用的寬 //排除 Windows 任務欄
screen.availHeight 屏幕中可用的高 //排除 Windows 任務欄
screen.colorDepth 屏幕的色彩數
8.History對象 // 窗口的訪問歷史信息(屬於window的子對象,常用於返回到已經訪問過的頁面)
history.length 歷史記錄數
history.foward() 向下一頁
history.back() 返回上一頁
history.go(0) 刷新。括號里填"-1"就是返回上一頁,填"1"就是下一頁;其它數字類推

9.Navigator對象 瀏覽器和OS(系統)的信息 數組
10.Location對象 瀏覽器地址欄的信息 如: location.href="http://www.google.com/";
location.assign(href); 前往新地址,在歷史記錄中,用 Back 和 Forward 按鈕可回到之前的地址
location.replace(href); 替代當前文文件,在歷史記錄中也回不到之前的地址
location.reload(true); 類似刷新,默認 false
// location 各屬性的用途
location.href 整個URl字符串(在瀏覽器中就是完整的地址欄),如: "http://www.test.com:8080/test/view.htm?id=209&dd=5#cmt1323"
location.protocol 返回scheme(通信協議),如: "http:", "https:", "ftp:", "maito:" 等等(后面帶有冒號的)
location.host 主機部分(域名+端口號),端口號是80時不顯示,返回值如:"www.test.com:8080", "www.test.com"
location.port 端口部分(字符串類型)。如果采用默認的80端口(即使添加了:80),那么返回值並不是默認的80而是空字符。
location.pathname 路徑部分(就是文件地址),如: "/test/view.htm"
location.search 查詢(參數)部分。如: "?id=209&dd=5"
location.hash 錨點,如: "#cmt1323"
不包含參數的地址: location.protocol + '//' + location.host + location.pathname;


應用例子:窗口最大化
window.moveTo(0,0); window.resizeTo(screen.availWidth,screen.availHeight);
或者: moveTo(0,0); resizeTo(screen.width, screen.height);
//采用screen對象的分辨率屬性和resizeTo方法來動態確定窗口最大長度和寬度


二、 Dom 元素
處理 XML 文件的 DOM 元素屬性:
<element>.childNodes 返回目前元素所有子元素的數組
<element>.children 返回目前元素所有子元素的數組(這個在IE、火狐上也可以用)
<element>.firstChild 返回目前元素的第一個子元素
<element>.lastChild 返回目前元素的最后一個子元素
<element>.nodeValue 指定表示元素值的讀/寫屬性
<element>.parentNode 返回元素的父節點
<element>.previousSibling 返回緊鄰目前元素之前的元素
<element>.nextSibling 返回目前元素的后面的元素
<element>.tagName 返回目前元素的標簽名(大寫)

沿 XML 文件來回移動的 DOM 元素方法:
document.getElementById(id) 取得有指定唯一ID屬性值文件中的元素
document.getElementsByTagName(name) 返回目前元素中有指定標簽名的子元素的數組
<element>.hasChildNodes() 返回布爾值,表示元素是否有子元素
<element>.getAttribute(name) 返回元素的屬性值,屬性由name指定

動態建立內容時所用的 W3C DOM 屬性和方法:
document.createElement(tagName) 建立由tagName指定的元素。比如以"div"作為參數,則生成一個div元素。
document.createTextNode(text) 建立一個包含靜態文字的節點。
<element>.appendChild(childNode) 將指定節點增加到目前元素的子節點中。例如:select中增加option子節點
<element>.getAttribute(name) 取得元素中的name屬性的值
<element>.setAttribute(name,value) 設定元素中的name屬性的值
<element>.insertBefore(Node1,Node2) 將節點Node1作為目前元素的子節點插到Node2元素前面。
<element>.removeAttribute(name) 從元素中刪除屬性name
<element>.removeChild(childNode) 從元素中刪除子元素childNode
<element>.replaceChild(newN,oldN) 將節點oldN替換為節點newN
<element>.hasChildnodes() 返回布爾值,表示元素是否有子元素

注意:文字實際上是父元素的一個子節點,所以可以使用firstChild屬性來存取元素的文字節點。
有了文字節點后,可以參考文字節點的nodeValue屬性來得到文字。
讀取XML時,須考慮它的空格和換行符也作為子節點。


處理 HTML DOM 元素中3個常用的屬性: nodeName、 nodeValue 以及 nodeType
nodeName 屬性(只讀)含有某個節點的名稱:
元素節點的 nodeName 是標簽名稱(永遠是大寫的)
屬性節點的 nodeName 是屬性名稱
文本節點的 nodeName 永遠是 #text
文檔節點的 nodeName 永遠是 #document

nodeValue / data
對於文本節點,nodeValue 屬性包含文本。可增刪改
對於屬性節點,nodeValue 屬性包含屬性值。
nodeValue 屬性對於文檔節點和元素節點是不可用的。會返回 null
data同樣是文本的內容,這個屬性下同樣可以增刪改。對於文檔節點和元素節點不可用,返回 undefine

nodeType 屬性返回節點的類型。節點類型是:
元素類型 節點類型
ELEMENT_NODE : 1 // 元素
ATTRIBUTE_NODE : 2 // 屬性
TEXT_NODE : 3 // 文本
CDATA_SECTION_NODE : 4
ENTITY_REFERENCE_NODE : 5
ENTITY_NODE : 6
PROCESSING_INSTRUCTION_NODE : 7
COMMENT_NODE : 8 // 注釋
DOCUMENT_NODE : 9 // 文檔,即 document
DOCUMENT_TYPE_NODE : 10
DOCUMENT_FRAGMENT_NODE : 11
NOTATION_NODE : 12

注: 對於屬性節點,可使用 “attr.nodeName”和“attr.nodeValue”來查看或者賦值, 也可以使用“attr.name”和“attr.value”。
只是, attr.nodeValue 會返回真實類型,如 bool,number,string,object 等; 而 attr.value 全是 string 類型(null 則返回"null")

判斷是否 dom 元素,一些特殊節點只有nodeName,沒有tagName,比如document的nodeName為“#document”,tagName為空值。


三、跨瀏覽器
1.瀏覽器判斷:
//如果是火狐等瀏覽器則為“true”
var isNav = (navigator.appName.indexOf("Netscape") != -1);
//如果是IE瀏覽器則為“true”
var isIE = (navigator.appName.indexOf("Microsoft") != -1); // navigator.appName == "Microsoft Internet Explorer"
var isIE = (navigator.appVersion.indexOf("MSIE") != -1);
//判斷IE6
var isIE6 = (navigator.userAgent && navigator.userAgent.split(";")[1].toLowerCase().indexOf("msie 6.0")!="-1");
//如果是Opera瀏覽器則為“true”
var isOpera = (navigator.userAgent.indexOf("Opera") != -1);
//瀏覽器運行的平台,是 windows 則返回 true
var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1);

2.event 事件
在 IE4+ 和 Firefox下的 event
function doEventThing(event)
{
//獲取不同瀏覽器的 event
event = event || window.event; // window.event for IE; 參數event for firefox
//獲取不同瀏覽器的鍵盤輸入記錄
var currentKey = event.keyCode || event.charCode; // keyCode 目前兼容了
//獲取不同瀏覽器的事件源
var eventSource = event.target || event.srcElement; // srcElement for IE; target for firefox
var target = event.relatedTarget || event.toElement; // 將會去到的元素,像 onmouseout 會觸發
//屏蔽Form提交事件
//if ( event.returnValue ) event.returnValue = false; // for IE
//if ( event.preventDefault ) event.preventDefault(); // for firefox
( e.preventDefault ) ? (e.preventDefault()) : (e.returnValue = false);
//添加事件
if ( event.attachEvent ) {
event.attachEvent('onclick', func ); // for IE; 需要加上“on”,如 onmouseover
} else if ( event.addEventListener ) {
event.addEventListener('clcik', func, false); // for firefox; 不需要加上“on”,直接寫“click”
}
//改變事件; 但上面的綁定事件方法並不改變原有的onclick事件,而是添加事件
event.onclick = func;
}
//Firefox 下必須手動輸入參數,調用時如: <input type="button" onclick="doEventThing(event);"/>

3. firefox 的 click() 事件,由於 firefox 不支持 click() 事件,代替方式:
// 獲取需要觸發 onclick() 的元素
var element = document.getElementsByTagName('a')[0];
// For IE
if ( document.all ) {
element.click();
// FOR DOM2
} else if ( document.createEvent ) {
var ev = document.createEvent('MouseEvents'); //'MouseEvents' 改成 'HTMLEvents' 的話,firfox2不通過
ev.initEvent('click', false, true);
element.dispatchEvent(ev);
}

4. 跨瀏覽器技巧:
1) IE不能用setAttribute設定class屬性。
解決方法1: 同時使用 setAttribute("class","newClassName") 和 setAttribute("className","newClassName")
解決方法2: <element>.className = "newClassName"
2) IE中不能使用setAttribute設定style屬性。即 <element>.setAttribute("style","fontweight:bold;") 不相容。
解決方法:使用 <element>.style.cssText = "fontweight:bold;"
3) 使用appendChild將<tr>元素直接增加到<table>中,則在IE中這一行並不出現,但其它瀏覽器卻會出現。
解決方法:在<table>下增加<tbody>元素,再添加<tr>
4) IE不能直接添加按鈕處理事件。如:addButton.setAttribute("onclick","addEmployee('unid');");不適用。
解決方法:addButton.onclick = function() { addEmployee('unid'); };//用匿名函數調用addEmployee()函數。
此外,onmouseover,onmouseout 等事件也要使用此方法。
5) firefox 不支持 document.all
解決方法: 用 document.getElementsByTagName("*") 替代,可以得到得到所有元素的集合
6) 設置元素的id
同時使用 .id 和 setAttribute 來設置
var div = document.createElement('div');
div.id="btc";
div.setAttribute("id","btc");

5.Firefox注冊innerText寫法
if ( (navigator.appName.indexOf("Netscape") != -1) )
{
//注冊 Getter
HTMLElement.prototype.__defineGetter__("innerText", function(){
var anyString = "";
var childS = this.childNodes;
for ( var i=0; i < childS.length; i++ ) {
if ( childS[i].nodeType == 1 )
anyString += childS[i].tagName == "BR" ? '\n' : childS[i].innerText;
else if(childS[i].nodeType == 3 ) {
anyString += childS[i].nodeValue;
}
}
return anyString;
});

//注冊 Setter
HTMLElement.prototype.__defineSetter__("innerText",
function ( sText ) { this.textContent = sText; }
);
}
//在非IE瀏覽器中使用 textContent 代替 innerText

6.長度:FireFox長度必須加“px”,IE無所謂
解決方法:統一使用 obj.style.height = imgObj.height + "px";
7.父控件下的子控件:IE是“children”,FireFox是“childNodes”
8.XmlHttp
在IE中,XmlHttp.send(content)方法的content可以為空,而firefox則不能為空,應該用send(" "),否則會出現411錯誤

9.event.x 與 event.y 問題
問題: 在IE中,event 對象有x,y屬性,FF中沒有
解決方法:
在FF中,與 event.x 等效的是 event.pageX ,但event.pageX IE中沒有
故采用 event.clientX 代替 event.x ,在IE中也有這個變量
event.clientX 與 event.pageX 有微妙的差別,就是滾動條
要完全一樣,可以這樣:
mX = event.x ? event.x : event.pageX;

10.禁止選取網頁內容
問題:FF需要用CSS禁止,IE用JS禁止
解決方法:
IE: obj.onselectstart = function() {return false;}
FF: -moz-user-select:none;

11.各種瀏覽器的特征及其userAgent。
IE
只有IE支持創建ActiveX控件,因此她有一個其他瀏覽器沒有的東西,就是 window.ActiveXObject 函數。
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
Firefox中的DOM元素都有一個getBoxObjectFor函數,用來獲取該DOM元素的位置和大小(IE對應的中是getBoundingClientRect函數)。這是Firefox獨有的,判斷它即可知道是當前瀏覽器是Firefox。
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
Opera提供了專門的瀏覽器標志,就是 window.opera 屬性。
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
Safari瀏覽器中有一個其他瀏覽器沒有的openDatabase函數,可做為判斷Safari的標志。
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
Chrome有一個 window.MessageEvent 函數,但Firefox也有。不過,好在Chrome並沒有Firefox的getBoxObjectFor函數,根據這個條件還是可以准確判斷出Chrome瀏覽器的。
目前,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

下面是判斷瀏覽器的代碼:
var Sys = {};
var ua = navigator.userAgent.toLowerCase();
if (window.ActiveXObject)
Sys.ie = ua.match(/msie ([\d.]+)/i)[1];
else if (document.getBoxObjectFor) // 火狐判斷出錯
Sys.firefox = ua.match(/firefox\/([\d.]+)/i)[1];
else if (window.opera)
Sys.opera = ua.match(/opera.([\d.]+)/i)[1];
else if (window.MessageEvent)
Sys.chrome = ua.match(/chrome\/([\d.]+)/i)[1];
else if (window.openDatabase)
Sys.safari = ua.match(/version\/([\d.]+)/i)[1];

//以下進行測試
if(Sys.ie) alert('IE: '+Sys.ie);
if(Sys.firefox) alert('Firefox: '+Sys.firefox);
if(Sys.chrome) alert('Chrome: '+Sys.chrome);
if(Sys.opera) alert('Opera: '+Sys.opera);
if(Sys.safari) alert('Safari: '+Sys.safari);


四、 摘錄:
1. 省略對象名稱,用 with() 命令。
如: document.write(".....<br/>");
document.write(".....<br/>");
可省略寫為:
with (document) {
write(".....<br/>");
write(".....<br/>");
} //把相同的 document 省略掉。
省略對象名稱,變量。
如: document.myForm.myText.value;
可省略寫為: f = document.myForm; f.myText.value;

2.頁面調試
javascript 加入如下語句,出錯時會提示
注意: chrome、opera 和 safari 等瀏覽器不支持 window.onerror 事件(w3c標准沒有此事件),需另外捕獲出錯信息
<script type="text/javascript">
/**
* 這是出錯調試代碼
* 當頁面發生錯誤時,提示錯誤信息
* @param msg 出錯信息
* @param url 出錯文件的地址
* @param sLine 發生錯誤的行
* @return true 讓出錯時不顯示出錯圖標
*/
window.onerror = function ( msg, url, sLine ) {
var hostUrl = window.location.href;
// 判斷網址,測試時可以提示出錯信息;正式發布時不提示
if ( hostUrl.indexOf("http://localhost") === 0 || hostUrl.indexOf("http://127.0.0.1") === 0 ||
hostUrl.indexOf("http://192.168.") === 0 || hostUrl.indexOf("file://") === 0 )
{
var errorMsg = "當前頁面的腳本發生錯誤.\n\n";
errorMsg += "錯誤: " + msg + "\n";
errorMsg += "URL: " + url + "\n";
errorMsg += "行: " + sLine + "\n\n";
errorMsg += "點擊“確定”消去此錯誤,“取消”保留此錯誤。\n\n";
return window.confirm( errorMsg );
}
// 返回true,會消去 IE下那個惱人的“網頁上有錯誤”的提示
return true;
};
</script>

3.把數值變成 奇 \ 偶數(利用位運算)
n = n | 1 ; //一定得到奇數。如果原本是偶數則加一。
n = (n >> 1) <<1; //一定得到偶數。如果原本是奇數則減一。
n = n ^ 1; //奇偶互換。對偶數加一,對奇數減一。

4.取出數值的整數部分(取整)。
// 以下第一種方法不受瀏覽器和版本的影響,后兩種受版本影響。
n = ( n > 0 ) ? Math.floor(n) : Math.ceil(n);
n = Number ( (String(n).split("."))[0]);
n = parseInt(n,10);
// 下面做法更簡便高效,用位運算來做(右移0位,或者兩次取反),且非數值型的值會轉成0
alert(5>>0); alert(~~5); // 值為 5
alert(5.55>>0); alert(~~5.55); // 值為 5
alert(-98.4>>0); alert(~~-98.4); // 值為 -98
alert('absd'>>0); alert(~~'absd'); // 值為 0
alert(null>>0); alert(~~null); // 值為 0
alert('34.5'>>0); alert(~~'34.5'); // 值為 34

5.取出數值的小數部分。
須先檢查小數點是否存在。但有時會發生運算誤差。
n = Math.abs(n); if(n>0) n = n - Math.floor(n); else n = 0;
n = parseInt(n,10) - parseFloat(n);
if((""+n).indexOf(".") > -1) n = Number("0."+(String(n).split("."))[1]); else n = 0;

6.在任意位置插入一行js(單行程序):
<script type="text/javascript">alert("中斷一下");</script>
<input type="button" onclick="javascript:formName.DataName.value='';formName.DataName.focus();" />

7.設置焦點:
//document.all["DateID"].onfocus;
document.all["DateID"].focus();
formName.DataName.focus();

8.默認參數:
function show() {
alert( arguments[0] );
}
這個函數會alert出第一個參數,如調用時: show("haha"),則alert("haha");

9.禁止 confirm 與 alert
window.confirm = function(str){return true;};
window.alert = function(str){};

10.獲取下拉菜單的內容
<select name="seleName" >
<option value="value1">Text</option>
</select>
獲取選中的下拉菜單的內容:
var seleElement = document.formName.seleName;
var optionText = seleElement.options[seleElement.selectedIndex].text;

11.設置默認值:
edittype = edittype || "text"; //edittype預設為 text
上面一句: 如果 edittype 之前有值,則取之前的值; 之前沒有值,則取默認值

12.數值的截取:
numObj.toFixed([fractionDigits])
//numObj:必選項。一個 Number 對象。
//fractionDigits:可選項。小數點后的數字位數。其值必須在 0 – 20 之間,包括 0 和 20。 預設為0
toFixed 方法返回一個以定點表示法表示的數字的字符串形式。對數值進行四舍五入截取到指定位數的小數
如: 55.3654.toFixed(2) //返回55.37

13.IE上的關閉窗口時不提示
window.opener = null; // 關閉IE6不提示
window.open("","_self"); // 關閉IE7不提示
//關閉窗口
window.close();

14.刷新頁面的幾種方法:
history.go(0);
window.navigate(location);
document.URL = location.href;
document.execCommand('Refresh'); //火狐不能用
location.reload();
location = location;
location.href = location.href;
location.assign(location);
location.replace(location);

15.頁面跳轉:
location.href = "yourURL"
window.location = 'url'
window.location.href = "yourURL"
window.navigate("top.jsp");
self.location = 'top.htm' //令所在框架頁面跳轉,大框架不變
top.location = 'xx.jsp'; //在框架內令整個頁面跳轉

16.頁面跳轉/刷新 的注意:
需要先執行其他代碼,然后再頁面跳轉或者刷新。因為頁面跳轉或者刷新后不再執行下面的代碼。
如:alert('請先登錄'); window.location.href = 'index.jsp';

17.改變標題(即改變<title>標簽的內容)
document.title = "title_content";

18.if 判斷對象是否存在
一般可以用 if 判斷對象是否存在,但直接寫“ if(對象名){...} ”判斷時,如果對象不存在則瀏覽器會拋異常。
這里建議用“ if(window['對象名']){...} ”的寫法來判斷
當確認對象已經存在時,用“對象名.變量名”跟“對象名['變量名']”沒什么區別。
如: var c = new Object(); // 假如這是寫在另一個js文件里的變量,下面用的時候需要判斷這對象是否存在
if (c) {alert('c存在');} // 如果這對象確實存在,則沒有問題。但對象不存在時會拋異常
if (window['c']){alert('c存在');}; if (window.c){alert('c存在');} // 推薦用這兩種寫法之一,不管對象是否存在,都不會拋異常,且存在時可正常使用。


五、JavaScript 技巧
1.獲取表單的內容
<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript">
<!--
function aa(){
//var value=document.all("td1").value; //.innerHTML
var value=document.getElementById("td1").value;//上句也可行
document.all("ta").value=value;
}
//-->
</SCRIPT>
</HEAD>
<BODY>
<input id="td1" name="haha" type="text" onkeydown="if(13==event.keyCode){aa();return false;}"/><br/>
<INPUT TYPE="button" NAME="" value="引用" onclick="aa()"><br/>
<TEXTAREA id="ta" ROWS="15" COLS="20"></TEXTAREA>
</BODY>
</HTML>

2. IE3.0 和 NN2.0(Netscape Navigator)上能同時運作的程序
為照顧不同的瀏覽器和版本,只好多作幾次判斷。看程序中的幾個 if 實現的是同一功能就明白。
<html>
<head>
<title>寫能同時在IE和NN上運行的程序</title>
<script language="JavaScript">
<!--
x = 0;
function moveLayer() {
x = x + 2;
if(document.all) {document.all["myLay"].style.left = x;} //IE4以上版本可用,IE4之前和NN上都沒有 all
if(document.layers) {document.layers["myLay"].left = x;} //僅NN4上運行,NN4外沒有layers對象
/* 下面這句僅NN6以后版本可用。
因為document.getElementById()在IE5.x上有,所以需 " !document.all " */
if(!document.all && document.getElementById) {document.getElementById("myLay").style.left = x;}
}
// -->
</script>
</head>
<body bgcolor = "white" onLoad="setInterval('moveLayer()',1000)">
<div id="myLay" style="position:absolute;left:0px"> <img src="btn1.gif"></div>
</body>
</html>

3. 讀取 Behavior 文檔 (任意標簽都可觸發 onclick 事件) (IE5.0以上可用)
//在 html 文件上寫:
<html>
<head>
<title>讀取 Behavior 文件</title>
<style type="text/css">
<!--
div { behavior:url(a.htc); }
-->
</style>
<script language="JavaScript">
<!--
function testA() { alert("haha"); } //<a>標簽的 onclick事件
function check() { //獲取 id 和 class 名稱
alert("id = "+document.all["myObj"].id+"; className="+document.all["myObj"].className);
}
// -->
</script>
</head>
<body bgcolor = "white"><center>
<div>點擊文字</div><br/><br/>
<a href="JavaScript:testA()">sample</a><br/><br/><br/>
<input id="myObj" class="mz" type=button value="test" onclick="check()" />
</center></body>
</html>

//在此 html 文件的同一目錄下的 a.htc 文件里寫:
<script language="JavaScript">
<!--
attachEvent("onclick",msg);
function msg() { alert("oh!");}
// -->
</script>

4.定時器,每隔一段時間進行處理(IE3.0以上,NN2.0以上可用)
<html>
<head>
<title>定時器</title>
<script language="JavaScript">
<!--
var timerId;
var n = 0;
function timerUpdate(){
window.document.myForm.result.value = n++ ;
//這是個一次性觸發的方法,這里以反復調用來實現周期性觸發
timerId = setTimeout("timerUpdate()",100); //第一個參數是要執行的函數,也可以直接寫匿名函數而不用字符串
}
function timerStart() {
//防止連續多次點擊,導致計數器速度迭加
document.getElementById("StartCount").onclick = "";
setTimeout("timerUpdate()",1);
}
function timerEnd() {
clearTimeout(timerId);
//這兩句的效果一樣。
//clearInterval(timerId);
//還原 "StartTime"按鈕 的點擊能力
document.getElementById("StartCount").onclick = timerStart;
}
// -->
</script>
</head>
<body>
<form name="myForm">
<input type="text" name="result"/><br/><br/>
</form>
<input type="button" id="StartCount" value="StartTime" onclick="timerStart()"/>
<input type="button" value="EndTime" onclick="timerEnd()"/>
</body>
</html>

5.根據 javaScript 的開閉狀態來顯示網頁(適用IE3.0和NN2.0以上版本)
以 <meta> 配合 location.href 來實現。
下面的 <meta> 里的content的5表示當javascript關閉時,5秒后跳轉到closeJavaScript.html 頁面。
location.href="openJavaScript.html"; 表示當javascript可用時,跳轉到 openJavaScript.html 頁面。
在 html 里加入"<noscript>您使用的瀏覽器不支持或者禁止了Javascript</noscript>"則在本頁面提示。

<meta http-equiv="refresh" content="5; url=closeJavaScript.html">
<script language="JavaScript">
<!--
location.href="openJavaScript.html";
// -->
</script>

7.淡入/淡出效果(背景色適用IE3.0和NN2.0以上版本,文字色適用IE4以上版本)
<body bgcolor="black" onLoad="newCount('bgColor'); fade('0123456789ABCDEF')">
<script language="JavaScript">
var count = 0 ;
var obj = null ;
function fade(str){
c = str.charAt(count++);
if (obj=='bgColor') {document.bgColor = "#"+c+c+c+c+c+c+c+c;} //改變背景顏色,顏色碼8位
if (obj=='word') {document.all["strId"].style.color = "#"+c+c+"0000";} //改變文字顏色,顏色碼6位
if(count < str.length) setTimeout("fade('"+str+"')",250);
}
function newCount(object){ count = 0 ; obj = object ; }
</script>
<input type="button" value="toWhite" onclick="newCount('bgColor'); fade('0123456789ABCDEF')"/>
<input type="button" value="toBlack" onclick="newCount('bgColor'); fade('fedcba9876543210')"/><br/><br/>
<span id="strId" onMouseover="newCount('word'); fade('fedcba9876543210')">點擊淡入淡出的文字</span>
</body>

8.窗口的振動效果(適用IE4.0和NN4.0以上版本)
<script language="JavaScript">
//指定窗口的錯位。
x = new Array( 10, 3, -6, 8, -10, -7, 5, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
y = new Array(-12, 6, -3, 10, -9, -2, 8, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
count = 0;
function purupuruWin() {
if(x[count] != 0) moveBy(x[count], y[count]); //窗口的振動
count++;
if(count >= x.length )count = 0;
setTimeout("purupuruWin()",100);
}
</script>
<input type="button" name="" value="StartPuru" onclick="purupuruWin()">

9.檢查電子郵件地址是否正確(適用IE4.0和NN3.0以上版本)
<script language="JavaScript">
function checkMailAddr(dstText){
var data = dstText.match(/^\S+@\S+\.\S+$/); //檢查是否郵件的表達式
if(!data || !dstText ) alert('電子郵件地址不正確!'); else alert('電子郵件地址正確!');
}
</script>
<form>
電子郵件:<input type="text" name="address" />
<input type="button" value="check" onclick="checkMailAddr(this.form.address.value)"/>
</form>

10. cookie 的使用。顯示訪問次數。(適用IE3.0和NN2.0以上版本)
<script language="JavaScript">
if ( !navigator.cookieEnabled ) alert("can not use cookie");
//在 cookie 中存儲訪問次數。
function setCount(n){
var theDay = 30;
var setDay = new Date();
setDay.setTime(setDay.getTime()+(theDay*1000*60*60*24));
document.cookie = "count=" + n + ";expires=" + setDay.toGMTString();
}
function getCount() {
var theName = "count=";
var theCookie = document.cookie + ";" ;
var start = theCookie.indexOf(theName); //沒有cookie時返回“-1”
if (start != -1) { //這是對第2次以后的訪問的處理
var end = theCookie.indexOf(";",start);
var count = eval(unescape(theCookie.substring(start+theName.length,end)));
document.write("這是第 "+count+" 次訪問本頁面");
setCount(count+1);
} else { //這是對第1次訪問的處理
document.write("這是第1次訪問本頁面");
setCount(2);
}
}
getCount();
</script>

11.簡單的預防二次提交 (適用IE3.0和NN3.0以上版本)
<script language="JavaScript">
var flag = false;
function send() {
if (flag) { alert("提交完畢!"); return false; }
flag = true ; return true;
}
function send2(form) {
if ( !flag ){ form.submit(); }
}
</script>
<form name="myForm" method="post" action="send.html" enctype="text/plain" onSubmit="return send()">
<input type="submit" value="提交" />
<!-- onclick里的函數要用雙引號括起來,form表單的名稱不能加引號,字符則須用單引號括起來-->
<input type="button" value="按鈕" onclick="send2(myform);" >
</form>


12.解決中文亂碼問題。
用以下三個方法進行轉碼就行了:
escape('你好') == %u4F60%u597D //轉成 Unicode 編碼
encodeURI('你好/p') == %E4%BD%A0%E5%A5%BD/p //轉換為UTF-8;URL需要傳遞中文時使用
encodeURIComponent('你好/p') == %E4%BD%A0%E5%A5%BD%2Fp

三種方法都能對字符進行過濾。后兩者是將字符串轉換為UTF-8的方式。
escape() 不會編碼的字符有69個: * + - . / @ _ 0-9 a-z A-Z
所有空格、標點符號以及任何其它非 ASCII 字符都用 %xx 編碼替換
其中 xx 表示該字符的16進制數。例如,空格返回為“%20”。
(字符值大於 255 的字符以 %uxxxx 格式存儲。)
注意:escape 方法不能用來對“統一資源標識符”(URI) 進行編碼。
unescape() 從用 escape() 編碼的 String 對象中返回已解碼的字符串。同樣不能用於 URI
encodeURI()返回編碼為有效的 URI 字符串。
不會編碼的字符有82個: ! # $ & ' ( ) * + , - . / : ; = ? @ _ ~ 0-9 a-z A-Z
此方法返回一個已編碼的 URI。將編碼結果傳遞給 decodeURI(),則返回初始的字符串。
decodeURI() 不對下列字符進行編碼: : / ; ?
encodeURIComponent() 返回編碼為 URI 的有效組件的字符串。
不會編碼的字符有71個: ! ' ( ) * - . _ ~ 0-9 a-z A-Z
注意,它會編譯“/”,所以不能包含路徑,否則無效。
decodeURIComponent() 將編碼結果解碼回初始字符串。

//把任意編碼轉成 java 的 ascii 編碼(Unicode native2ascii )
//注意:html的ascii碼是“%”開頭的,但java的卻是“\”開頭,所以這里替換了
function change1( str ) {
var tem = "";
for( var j = 0; j < str.length; j=j+1 ) {
if ( escape(str.charAt(j)).length >= 6) {
tem += escape(str.charAt(j)).replace("%", "\\");
} else { tem += str.charAt(j); }
}
return tem;
}

// ascii2nactive 解碼
function change2( str ) {
for( var j = str.length/3; j > 0; j=j-1 ) {
str = str.replace("\\", "%");
}
return unescape(str);
}

12.1 <a> (A標簽) 傳參時的中文亂碼解決方案
利用js的escape函數,轉碼即可
<script language="javascript" type="text/javascript">
/**
* 打開小視窗
* @param url 需要打開視窗的網址
* @param name 視窗名稱
* @param param 視窗顯示的參數
*/
function openWin(url, name, param) {
var newurl,arrurl;
if ( typeof(url) === "undefined" || url === "" ) {
return ;
}
else {
//沒有參數時
if ( url.indexOf("?") == -1 ) {
newurl = url;
}
//分解參數,並逐個轉碼
else {
newurl = url.substring(0,url.indexOf("?")+1);
arrurl = url.substring(url.indexOf("?")+1).split("&");
for ( var i =0; i<arrurl.length; i++ ) {
newurl += arrurl[i].split("=")[0] + "=" + escape(arrurl[i].split("=")[1]) + "&";
}
newurl = newurl.substring(0,newurl.length-1);
}
}
window.open(newurl, name, param);
}
</script>

//使用如下 (下面第二句會更好,測試火狐時第一句會延遲或者沒反應)
<a href="#" onclick="openWin('test.html','test','width=300,height=400');">Links</a>
<a href="javascript:openWin('test.html','test','width=300,height=400');">Links</a>

A標簽的 href="#" 時,IE瀏覽器會跳轉到頁面頂部, 解決方法是把“<A href="#">”改寫成“<A href="javascript:void(0);">”或者“<A href="javascript:;">”
A標簽的 onclick 事件,如果返回 false, 可以阻止頁面跳轉,如: <A href="/index.html" onclick="alert(8);return false;">test</a>

注意:使用A標簽的 href="javascript:xxx代碼" 時,里面的js代碼不能使用 this, event 對象, 因為這相當於瀏覽器地址欄, this 不代表 A 標簽。
如果需要使用 this 或者 event 來獲取此A標簽,建議改用 onclick 事件。
另外 A 標簽里面的 onclick 事件返回 false,則不會跳轉(即 href 的內容不會觸發, href 里面的js也不會執行)。


13.正則表達式:
產生正則表達式的方式
1. var re = new RegExp("pattern",["flags"]); // 這種方式比較好
pattern :正則表達式字符串 // 注意這是字符串,里面的反斜杠("\")需要連寫兩個來表示一個,因為會轉義,如 new RegExp("\\d") 匹配一個數字
flags: // flags 可以多個一起使用, 如 new RegExp("\\w", 'gm')
g global (全文查找出現的所有 pattern)
i ignoreCase (忽略大小寫)
m multiLine (多行查找)

2. 使用 正斜杠("/") 括起來
var re = /pattern/flags
pattern 和 flags 的含義跟 new RegExp 的一樣。
只不過,這里的 pattern 不是字符串,不會轉義,所以里面的反斜杠("\")不需要連寫兩個。如 /\d/ 表示匹配一個數字
這兩種方式產生的正則表達式都是一樣的,如 new RegExp("(f+)d+(s+)") 也可以寫成: /(f+)d+(s+)/

正則表達式的常用函數:
re.exec(字符串); // 返回匹配數組(下標0是整個匹配到的字符串,下標1是第1個捕獲組,下標2是第2個捕獲組...),沒有匹配時返回 null
re.test(字符串); // 返回 true, 或者 false,表示是否匹配
另外,字符串也有可運用正則表達式的:
字符串.replace(正則表達式, 要替換的字符串); // 要替換的字符串里面,也可以使用 $1, $2 作為捕獲組
字符串.match(正則表達式); // 同 re.exec,返回匹配數組,無法匹配則返回null,[0]是匹配的整個字符串,[1]是匹配的第一個捕獲組,[2]是第二個捕獲組...

RegExp 的屬性
$1, ..., $9 捕獲組,$1是匹配的第一個捕獲組(即第一個用小括號括起來的內容),$2是第二個捕獲組... 如:
if ( new RegExp("(f+)d+(s+)").test("ddfffdddsss") ) {
alert(RegExp.$1 + ", " + RegExp.$2); // 提示出: fff, sss
}
$_, input 返回輸入的內容
如: /^1((3\d)|(5[036789])|(8[89]))\d{8}$/.exec("13595044124"); alert(RegExp.$_); alert(RegExp.input); // 提示出: 13595044124

 

常用的正則表達式 元字符
\ 轉義符
. 匹配除換行符以外的任意字符
| 或符號
\w 匹配字母或數字或下划線 (大寫的通常是小寫的反義)
\W 匹配任意不是字母,數字,下划線的字符
\s 匹配任意的空白符
\S 匹配任意不是空白符的字符
\d 匹配數字
\D 匹配任意非數字的字符
\b 匹配單詞的開始或結束
\B 匹配不是單詞開頭或結束的位置
^ 匹配字符串的開始
$ 匹配字符串的結束
[^x] 匹配除了x以外的任意字符
[^aeiou] 匹配除了aeiou這幾個字母以外的任意字符
\數字 表示捕獲組,要求與第幾個捕獲組相同
常用的限定符
* 重復零次或多次
+ 重復一次或多次
? 重復零次或一次
{n} 重復n次
{n,} 重復n次或更多次
{n,m} 重復n到m次

常用正則表達式
/^[-]?\d+([.]?\d*)$/ //數字
/^[-]?\d+$/ //整數
/^[0-9a-zA-Z]{5,16}$/ //用戶名(區分大小寫,5-16位)
/^[\u4e00-\u9fa5]+$/ //中文
/^(\w){6,20}$/; //校驗密碼:只能輸入6-20個字母、數字、下划線
//電話號碼(手機號碼):像(010)88886666,022-22334455,029 1234-5678,010 3523922轉259,3523922。04-36018188/23051418 等
/^([((]?0\d{1,6}[)) -]?)?(\d{5,30}|((\d{4}[ -]){1,7}\d{1,4}))([ -#((轉轉]?\d{1,6}[))]?)?$/;
/^#?([a-f0-9]{6}|[a-f0-9]{3})$/ //十六進制值
/^([a-zA-Z\d_\.-]+)@([a-zA-Z\d]+\.)+[a-zA-Z\d]{2,6}$/ //電子郵箱
/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/ //URL
//下句是 IP 地址: 1.0.0.1 到 255.255.255.255,每段不能用“0”打頭
/^([1-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.(([\d]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.){2}([1-9]|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))$/
/^<([a-z]+)([^<]+)*(?:>(.*)<\/\1>|\s+\/>)$/ //HTML 標簽

"str".replace(/(^\s*)|(\s*$)/g, ""); // 去除前后空格

//校驗登錄名:只能輸入5-20個以字母開頭、可帶數字、“_”、“.”的字符串
function isRegisterUserName(s) {
var patrn = /^[a-zA-Z]{1}([a-zA-Z0-9]|[._]){4,19}$/;
return !!(patrn.exec(s)); //返回匹配數組,沒有匹配時返回null;所以非兩次以返回boolean值
}
//防止SQL注入,返回true表示通過驗證,返回false表示驗證不通過
function IsValid( oField ) {
re= /select|update|delete|exec|count|'|"|=|;|>|<|%/i;
$sMsg = "請您不要在參數中輸入特殊字符和SQL關鍵字!";
if ( re.test(oField.value) ) {
alert( $sMsg );
return false;
}
return true;
}
// 日期檢查
function strDateTime(str)
{
var r = str.match(/^(\d{1,4})(-|\/)?(\d{1,2})\2(\d{1,2})$/); // 注意里面的“\2”,表示要求與第2個捕獲組“(-|\/)?”的值相同
if ( r == null ) return false;
var d = new Date(r[1], r[3]-1, r[4]);
return (d.getFullYear()==r[1] && (d.getMonth()+1)==r[3] && d.getDate()==r[4]);
}


14.修改表單內容
<html>
<head><title>修改表單內容</title>
<script language="JavaScript" type="text/javascript" >
/**
* 編輯按鈕
* @param form 頁面提交的<form>的name
* @param dataId 要編輯的行的 id
* @param number 要編輯的列的數量
*/
var isedit = false;
function edit ( form, dataId, number )
{
if ( isedit ){ alert("請編輯完再編輯下一筆!");return;}
isedit = true;
//獲取需編輯的對象(<tr>卷標對象)
var data = document.getElementById("data_"+dataId);
//獲取需編輯的各子對象(<td>卷標對象)。注意:各<td>間別換行,換行符也算子元素。
var dataNodes = data.childNodes;
//寫進去的內容。這將是數組對象
var dataInput;
//循環修改須編輯的列的內容
for ( var i=number-1; i >= 1; i=i-1 ) {
var editname = "edit_" + i;
dataInput = "<input type='text' name='" + editname + "' id='" + editname + "' ";
dataInput += " size='10' maxlength='15' value='" + dataNodes[i].innerHTML + "' \/>"
dataNodes[i].innerHTML = dataInput;
}
// 第一欄是學號等 ID字段,不許修改。但提交時需在提交窗體里找到它。
dataInput = "<input type='hidden' name='edit_0' value='";
dataInput += dataNodes[0].innerHTML + "' \/>" + dataNodes[0].innerHTML;
dataNodes[0].innerHTML = dataInput;
//性別欄,下拉菜單
dataInput = "<select name='edit_2'>"
//dataNodes[2].innerHTML.indexOf("男") 如果相同則傳回"0",不同傳回"-1"
if(dataNodes[2].innerHTML.indexOf("男") === 0){
dataInput += "<option value='m' selected>男<\/option>";
dataInput += "<option value='f' >女<\/option><\/select>";
} else {
dataInput += "<option value='m' >男<\/option>";
dataInput += "<option value='f' selected>女<\/option><\/select>";
}
dataNodes[2].innerHTML = dataInput;
//按鈕欄
dataInput = "<input type='button' value='確認' onclick=\"updateValue(";
dataInput += form.name + ", " + number + ", 'edit_' );\"\/>";
dataNodes[ (dataNodes.length -2) ].innerHTML = dataInput;
dataNodes[ (dataNodes.length -1) ].innerHTML = ""; //編輯時不給刪除
form.SQLmethod.value = "modify"; //表單提交信息,與這里無關
form.submitId.value = dataId; //表單提交信息,與這里無關
}
/**
* 編輯后確認,提交
* @param form 頁面提交的<form>的name
* @param number 要編輯的列的數量
* @param str name屬性的開始字段
*/
function updateValue ( form , number , str ) {
var editname;
//循環處理,主要是 alert() 提醒客戶端必須填寫某些內容
for ( var i=1; i < number; i=i+1 ) {
editname = str + i;
if( document.all[editname].value.length === 0) {
document.all[editname].focus();
alert("請填寫各欄目內容!");
return ;
}
}
form.submit();
}
</script>
</head>

<body>
<form name="pageForm" action="" >
<table border="1">
<TR><TH>學號</TH><TH>姓名</TH><TH>性別</TH>
<TH style="BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid"></TH>
<TH style="BORDER-BOTTOM: #000000 1px solid"></TH>
</TR>
<tr id='data_1' ><td>101</td><td>stu1</td><td>男</td><td><INPUT type='button' value='編輯' onclick="edit(pageForm,1,2 ); " ></td><td><INPUT type='button' value='刪除' onclick="del(pageForm,1, 'del');" ></td></tr>
<tr id='data_2' ><td>102</td><td>stu2</td><td>女</td><td><INPUT type='button' value='編輯' onclick="edit(pageForm,'2',2 ); " ></td><td><INPUT type='button' value='刪除' onclick="del(pageForm,2, 'del');" ></td></tr>
</table>
</form>
</body>
</html>


15.可變長參數 的 動態函數:
函數是一個對象,一個Function對象
(函數參數列表及函數主體事實上只是Function對象的構造函數的參數而已)
函數參數是可變的,比如定義函數時的參數列表有3個參數,調用時可以傳2個參數,或者5個參數
arguments.length 是實際參數的個數(被傳遞參數的個數)
方法名.length 期望參數的個數(定義函數時的參數列表的參數個數)

動態函數:
var square = new Function("x", "y", "var sum;sum=x*x+y*y;return sum;");
alert(square(2,3)); //值為13
動態函數的作用:函數體是由一個字符串構成的,故函數體可動態生成。


16.頁面刷新的方法:
history.go(0);
location.reload();
location=location;
location.assign(location);
document.execCommand('Refresh');
window.navigate(location);
location.replace(location);
document.URL=location.href;

自動刷新的方法:
1) <head> 里使用標簽:<meta http-equiv="refresh" content="20"> //其中20指每隔20秒刷新一次頁面
2) 使用javascript:
<script language="JavaScript">
function myrefresh() {
window.location.reload();
}
setTimeout('myrefresh()',1000); //指定1秒刷新一次
</script>

頁面自動跳轉:
<meta http-equiv="refresh" content="20;url=http://www.wyxg.com"> //20秒后跳轉到url指定的頁面

刷新框架的js:
//刷新包含該框架的頁面用
parent.location.reload();
//子窗口刷新父窗口
self.opener.location.reload(); ( 或 <a href="javascript:opener.location.reload()">刷新</a> )
//刷新另一個框架的頁面用
parent.otherFrameID.location.reload();

關閉或者打開窗口時刷新,在<body>中用 onload 或 onUnload 即可。
<body onload="opener.location.reload()"> //打開窗口時刷新
<body onUnload="opener.location.reload()"> //關閉窗口時刷新
window.opener.document.location.reload(); // ?


17.用 javascript 處理 JSON:
JSON 是 javascript 的一個子集,所以,在javascript 中使用JSON是非常簡單的。
JSON的規則很簡單: 對象是一個無序的“‘名稱/值’對”集合。一個對象以“{”(左括號)開始,“}”(右括號)結束。
每個“名稱”后跟一個“:”(冒號);“‘名稱/值’ 對”之間使用“,”(逗號)分隔。
1) 創建 JSON 對象,如下創建了只包含一個成員 "bindings" 的一個對象,bindings 則包含了一個由3個對象組成的數組。
var myJSONObject = {"bindings": [
{"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"},
{"ircEvent": "PRIUUCG", "method": "deleteURI", "regex": "^delete.*"},
{"ircEvent": "PRIIPKD", "method": "randomURI", "regex": "^random.*"}
]
};
2) 獲取對象: 在javascript 中, 成員可以通過“點號”來獲取。
如: myJSONObject.bindings[0].method // 結果: newURI
alert(myJSONObject.bindings[1].method); //alert信息: deleteURI
3) 通過eval() 函數可以將JSON字符串轉化為對象。
如: var myJSONtext = '{"ircEvent": "PRIUUCG", "method": "deleteURI", "regex": "^delete.*"}';
var myObject = eval('(' + myJSONtext + ')');
alert(myObject.ircEvent); //alert信息: PRIUUCG
如: var myObject2 = eval('({ircEvent: "PRIUUCG", method: "delete"})'); //名稱也可以不用引號括起來
alert(myObject2.ircEvent); //alert信息: PRIUUCG
4) 基於安全的考慮的 JSON 解析器。
eval 函數非常快,但是它可以編譯任何 javascirpt 代碼,這樣的話就可能產生安全的問題。
eval 的使用是基於傳入的代碼參數是可靠的假設的,有一些情況下,可能客戶端是不可信任的。
一個 JSON 解析器將只接受 JSON 文本。所以是更安全的。
如: var myObject = JSON.parse(myJSONtext, filter);
可選的 filter 參數將遍歷每一個 value key 值對, 並進行相關的處理。
如: myData = JSON.parse(text, function (key, value) {
return key.indexOf('date') >= 0 ? new Date(value) : value;
});


18.匿名函數與 Module 模式
JavaScript 的任何變量,函數或是對象,除非是在某個函數內部定義,否則,就是全局的。
意味着同一網頁的別的代碼可以訪問並改寫這個變量(ECMA 的 JavaScript 5 已經改變了這一狀況 - 譯者)
使用匿名函數,你可以繞過這一問題。
比如,你有這樣一段代碼,很顯然,變量 name, age, status 將成為全局變量:
var name = 'Chris';
var age = 18;
function createMenber() {
// ...
}
function getMenber() {
// ...
}
為了避免這一問題,你可以使用匿名函數:
var myApp = function() {
var name = 'Chris';
var age = 18;
// 如果在函數里面再定義函數,建議如下寫法,如果寫“function createMenber(){...}”則IE7會報錯
var createMenber = function() {
// ...
}
var getMenber = function() {
// ...
}
}();
如果這個函數不會被再次調用,可以連這個函數的名稱也省了,更直接寫為:
(function() {
var name = 'Chris';
var age = 18;
var createMenber = function() {
// ...
}
var getMenber = function() {
// ...
}
}) ();
如果要訪問其中的對象或函數,可以:
var myApp = function() {
var name = 'Chris';
var age = 18;
return {
createMenber: function() {
// ...
}
getMenber: function () {
// ...
}
}
} ();
// myApp.createMenber() 和 myApp.getMenber() 可以使用
所謂 Module 模式或單例模式(Singleton),假如你想在別的地方調用里面的方法,可以在匿名函數中返回這些方法,甚至用簡稱返回:
var myApp = function() {
var name = 'Chris';
var age = 18;
var createMenber = function () {
// ...
}
var getMenber = function () {
// ...
}
return {
create:createMenber,
get:getMenber
}
} ();
// myApp.create() 和 myApp.get() 可以使用


19.事件委托
事件是JavaScript非常重要的一部分。
我們想給一個列表中的鏈接綁定點擊事件,一般的做法是寫一個循環,給每個鏈接對象綁定事件,HTML代碼如下:

<h2>Great Web resources</h2>
<ul id="resources">
<li><a href="http://opera.com/wsc">Opera Web Standards Curriculum</a></li>
<li><a href="http://sitepoint.com">Sitepoint</a></li>
<li><a href="http://alistapart.com">A List Apart</a></li>
<li><a href="http://yuiblog.com">YUI Blog</a></li>
<li><a href="http://blameitonthevoices.com">Blame it on the voices</a></li>
<li><a href="http://oddlyspecific.com">Oddly specific</a></li>
</ul>

代碼如下:
// 典型事件綁定示例
(function(){
//回調函數
var handler = function (e){
e = e || window.event;
//獲取事件源(被點擊的元素對象)
var x = e.target || e.srcElement;
alert('Event delegation:' + x);
//屏蔽Form提交事件
if ( e.returnValue ) e.returnValue = false; //for IE
if ( e.preventDefault ) e.preventDefault(); //for Firefox
};
var resources = document.getElementById('resources');
var links = resources.getElementsByTagName('a'); // Dom 對象下獲取子對象
var all = links.length;
// 給每個鏈接綁定點擊事件
for(var i=0;i<all;i++){
var link = links[i];
if ( link.attachEvent ) {
link.attachEvent('onclick',handler);
}
else if ( link.addEventListener ) {
link.addEventListener('click',handler,false);
}
};
})();

更合理的寫法是只給列表的父對象綁定事件,代碼如下:
(function(){
var handler = function (e) {
e = e || window.event;
var x = e.target || e.srcElement;
// 確認被點擊的對象是 A標簽
if ( x.nodeName.toLowerCase() === 'a' ) {
alert('Event delegation:' + x);
//屏蔽Form提交事件
( e.preventDefault ) ? (e.preventDefault()) : (e.returnValue = false);
}
};
var resources = document.getElementById('resources');
resources.onclick = handler; //也可以像上面用 addEventListener 和 attachEvent 添加 onclick 事件
})();


20.window.open() 子窗口控制
// 窗口參數,控制位置和大小、顯示等
var param = 'top='+(screen.height-pHeight)/2+',left='+(screen.width-pWidth)/2+',width='+ pWidth +',height=' + pHeight + ',resizable=yes,scrollbars=yes,location=no, status=no';
// 參數解釋:
height=100 窗口高度; // 這里 pHeight 需要先設定參數值
width=400 窗口寬度; // 這里 pWidth 需要先設定參數值
top=0 窗口距離屏幕上方的象素值; //top=(screen.height-pHeight)/2 和 left=(screen.width-pWidth)/2 讓窗口居中顯示
left=0 窗口距離屏幕左側的象素值;
toolbar=no 是否顯示工具欄,yes為顯示;
menubar,scrollbars 表示菜單欄和滾動欄。
resizable=no 是否允許改變窗口大小,yes為允許;
location=no 是否顯示地址欄,yes為允許;
status=no 是否顯示狀態欄內的信息(通常是文件已經打開),yes為允許;
// 子窗口網址
var url = "test.html";
var pName = "windowsName" // 子窗口的名稱: 如果子窗口名稱相同,會覆蓋舊的窗口
// 打開窗口,返回子窗口對象
var win = window.open(url,pName,param);
// 父窗口控制子窗口的對象
win.window.document.getElementById("productName").innerHTML = "<%=prod.Name%>";
// 父窗口調用子窗口的函數
win.testFun();

// 子窗口控制父窗口
window.opener.window.document.getElementById("bnt").value = "重新查看";
// 子窗口調用父窗口的函數
window.opener.testfun();

注意:父窗口剛打開子窗口時馬上對它進行賦值或者調用其函數等操作可能會失敗,因為子窗口未完全加載
需要這樣做時,最好在子窗口寫加載的js,再調用父窗口; 以免操作失敗。


21.URL編程
javascript允許直接在URL地址欄寫程序,這令js做的驗證全部都是不安全,必須后台在驗證一次。
如,在一個頁面的地址欄輸入:“javascript:alert(55);”,那頁面即可執行 alert 函數,同理也可執行任意的js函數。
利用這點,<A>標簽的地址也可以編程,如:“<A href='javascript:alert(5);testFun();'></A>”


22.頁面的script結束符問題
如下寫法,html頁面不會alert,反而會在頁面上顯示“');”的內容
<script>
alert('</script>');
</script>

因為瀏覽器把alert的字符串中的“</script>”解析成結束符了,需要“\”轉換一下,如下寫成能正常:
<script>
alert('<\/script>');
</script>


23.z-index(zIndex)塗層使用
在css里面用 z-index, 而javascript里面用 zIndex, 如:
<div id='fl' style="Z-INDEX: 9999999;">...</div>
<script>
var element = document.getElementById('fl');
element.style.zIndex = 9;
</script>

z-index(zIndex) 默認為0,(其實打印的時候為空),塗層的數值越大越往上,也就是顯示時覆蓋塗層低的。
注意:IE6上,層級會影響塗層,按先后出現的順序來絕定層的堆疊順序,不同層級的元素需要設置祖先元素(上溯到同層級為止)的z-index才生效。

24. iframe 的操作
1) 獲得 iframe 的 window 對象。存在跨域訪問限制。
chrome: iframeElement. contentWindow
firefox: iframeElement.contentWindow
ie6: iframeElement.contentWindow

function getIframeWindow(element){
return element.contentWindow;
//return element.contentWindow || element.contentDocument.parentWindow;
}

2) 獲得 iframe 的 document 對象。存在跨域訪問限制。
chrome: iframeElement.contentDocument
firefox: iframeElement.contentDocument
ie: iframeElement.contentWindow.document // ie沒有 iframeElement.contentDocument 屬性。

function getIframeDocument(element) {
return element.contentDocument || element.contentWindow.document;
}

3) iframe 中獲得父頁面的 window 對象。存在跨域訪問限制。
父頁面:window.parent
頂層頁面:window.top
適用於所有瀏覽器

4) 獲得 iframe 的內容。存在跨域訪問限制。
firefox: iframeElement.contentDocument.documentElement.textContent
ie: iframeElement.contentWindow.document.documentElement.innerText

function getIframeText(element) {
var iframeDocument = element.contentDocument || element.contentWindow.document;
var documentElement = iframeDocument.documentElement || iframeDocument.body;
return documentElement.textContent || documentElement.innerText;
}

5) iframe的 onload 事件
非ie瀏覽器都提供了 onload 事件。例如下面代碼在ie中是不會有彈出框的。
var ifr = document.createElement('iframe');
ifr.src = 'http://www.b.com/index.html';
ifr.onload = function() {
alert('loaded');
};
document.body.appendChild(ifr);

但是ie卻又似乎提供了onload事件,下面兩種方法都會觸發onload
//方法一:
<iframe onload="alert('loaded');" src="http://www.b.com/index.html"></iframe>

//只有ie才支持為createElement傳遞這樣的參數
var ifr = document.createElement('<iframe onload="alert(\'loaded\');" src="http://www.b.com/index.html"></iframe>');
document.body.appendChild(ifr);由於iframe元素包含於父級頁面中,因此以上方法均不存在跨域問題。

實際上IE提供了 onload 事件,但必須使用attachEvent進行綁定。所以最好的 onload事件寫法如下:

var ifr = document.createElement('iframe');
ifr.src = 'http://b.a.com/b.html';
var loaded_fun = function(){ alert('loaded'); }; // 要執行的 onload 事件
if (ifr.attachEvent) {
ifr.attachEvent('onload', loaded_fun );
} else {
ifr.onload = loaded_fun;
}
document.body.appendChild(ifr);

6) frames
window.frames 可以取到頁面中的幀( iframe, frame 等),需要注意的是取到的是 window 對象,而不是 HTMLElement 。
var ifr1 = document.getElementById('ifr1');
var ifr1win = window.frames[0];
ifr1win.frameElement === ifr1; // true
ifr1win === ifr1; // false


25. 反射
在JavaScript中能利用 for in 語句實現反射,如:
// 下面這段語句遍歷obj對象的所有屬性和方法
for (var p in obj) {
if (typeof(obj[p]=="function") {
obj[p](); // 執行函數,也還可以傳參數
} else {
alert(obj[p]);
}
}

obj.函數名(參數列表); // 這樣執行函數,可以使用下面的反射形式來代替
obj["函數名"](參數列表);


26. 過濾數組的重復值
/**
* 返回沒有重復值的新數組,原數組不改變
* @return 返回過濾重復值后的新數組
*
* @example
* var arr = ['a', 'b', 'c', 'd', 'c', null];
* var arr2 = arr.unique(); // arr2 為: ['a', 'b', 'd', 'c', null]
*/
Array.prototype.unique = function() {
var result = [];
// 注意學習此算法
for (var i=0,l=this.length; i<l; i++) {
for (var j=i+1; j<l; j++) {
if (this[i] === this[j]) j = ++i;
}
result.push(this[i]);
}
return result;
};


27. 巧用“||”、“&&”和“!”
松散性語言的特性, if 判斷時可以用任意值, false、 null、 undefine、 ''、 0、 NaN 都會被當成 false
利用js的松散性和沒類型特性, 可簡化一些代碼:

function fun1(name, fun2, obj, add_step) {

// 設預設值
name = name || '匿名';
// 上面一句相當於下面這一句
if ( !name ) name = '匿名';

// 假如傳入的 fun2 是個函數, 當有此值傳入時執行, 沒有則不執行
fun2 && fun2();
// 上面一句相當於下面這一句
if ( fun2 ) fun2();

// 轉成布爾值,不管傳入的 obj 是什么類型的值, 都會返回布爾類型的值
return !!obj;
// 上面一句相當於下面這幾句
if ( obj ) {
return true;
} else {
return false;
}

// && 多重的if判斷,或者swith判斷,可以這樣簡寫
var add_level = (add_step>10 && 3) || (add_step>5 && 2) || (add_step>0 && 1) || 0;
// 上面一句相當於下面這幾句
var add_level;
if (add_step > 10) {
add_level = 3;
} else if (add_step > 5) {
add_level = 2;
} else if (add_step > 0) {
add_level = 1;
} else {
add_level = 0;
}

}
// “||”、“&&”和“!”的特性幫我們精簡了代碼,同時也降低了代碼的可讀性。 這就需要我們自己來權衡了。
// 不一定非得用這些精簡寫法,但得讀得懂,因為很多框架用上了這類寫法。
// 之所以會犧牲可讀性來用這些簡便寫法,是為了壓縮代碼量,減少訪問時間。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM