1. 程式人生 > 實用技巧 >JavaScript 的基礎學習(一)

JavaScript 的基礎學習(一)

JavaScript 的基礎學習(一)

知識預覽

JavaScript概述

JavaScript的歷史

  • 1992年Nombas開發出C-minus-minus(C--)的嵌入式指令碼語言(最初繫結在CEnvi軟體中).後將其改名ScriptEase.(客戶端執行的語言)
  • Netscape(網景)接收Nombas的理念,(Brendan Eich)在其Netscape Navigator 2.0產品中開發出一套livescript的指令碼語言.Sun和Netscape共同完成.後改名叫Javascript
  • 微軟隨後模仿在其IE3.0的產品中搭載了一個JavaScript的克隆版叫Jscript.
  • 為了統一三家,ECMA(歐洲計算機制造協會)定義了ECMA-262規範.國際標準化組織及國際電工委員會(ISO/IEC)也採納 ECMAScript 作為標準(ISO/IEC-16262)。從此,Web 瀏覽器就開始努力(雖然有著不同的程度的成功和失敗)將 ECMAScript 作為 JavaScript 實現的基礎。EcmaScript是規範.

ECMAScript

儘管 ECMAScript 是一個重要的標準,但它並不是 JavaScript 唯一的部分,當然,也不是唯一被標準化的部分。實際上,一個完整的 JavaScript 實現是由以下 3 個不同部分組成的:

  • 核心(ECMAScript)
  • 文件物件模型(DOM) Document object model (整合js,css,html)
  • 瀏覽器物件模型(BOM) Broswer object model(整合js和瀏覽器)
  • Javascript 在開發中絕大多數情況是基於物件的.也是面向物件的.

簡單地說,ECMAScript 描述了以下內容:

  • 語法
  • 型別
  • 語句
  • 關鍵字
  • 保留字
  • 運算子
  • 物件 (封裝 繼承 多型) 基於物件的語言.使用物件.

JavaScript的引入方式

1 2 3 4 5 6 {#1 直接編寫#} <script> alert('hello yuan') <
/script> {#2 匯入檔案#} <script src="hello.js"></script>  

二 JavaScript的基礎

2.1 變數

x=5
y=6
z=x+y

在代數中,我們使用字母(比如 x)來儲存值(比如 5)。

通過上面的表示式 z=x+y,我們能夠計算出 z 的值為 11。

在 JavaScript 中,這些字母被稱為變數。

0 變數是弱型別的(很隨便);

1 宣告變數時不用宣告變數型別. 全都使用var關鍵字;

1 var a;

2一行可以宣告多個變數.並且可以是不同型別.

1 var name="yuan", age=20, job="lecturer";

3(瞭解) 宣告變數時 可以不用var. 如果不用var 那麼它是全域性變數.

4變數命名,首字元只能是字母,下劃線,$美元符 三選一,且區分大小寫,x與X是兩個變數

5變數還應遵守以下某條著名的命名規則:

Camel 標記法
首字母是小寫的,接下來的字母都以大寫字元開頭。例如:
var myTestValue = 0, mySecondValue = "hi";
Pascal 標記法
首字母是大寫的,接下來的字母都以大寫字元開頭。例如:
Var MyTestValue = 0, MySecondValue = "hi";
匈牙利型別標記法
在以 Pascal 標記法命名的變數前附加一個小寫字母(或小寫字母序列),說明該變數的型別。例如,i 表示整數,s 表示字串,如下所示“
Var iMyTestValue = 0, sMySecondValue = "hi";

注意:

    function func1(){
        
        var a = 123;
        b=456
    }

    func1();
    
//    alert(a);
//    alert(b);
// 不推薦

2.2 基礎規範

1每行結束可以不加分號. 沒有分號會以換行符作為每行的結束

a=1;b=2;
a=1 b=2;------錯誤

a=1
b=2

//推薦
a=1;
b=2;

{
 a=1;
 b=2;
    //推薦加tab
    a=1;
    b=2;
}

2註釋 支援多行註釋和單行註釋. /* */ //

3使用{}來封裝程式碼塊

2.3 常量和識別符號

常量直接在程式中出現的資料值

識別符號

  1. 不以數字開頭的字母、數字、下劃線(_)、美元符號($)組成
  2. 用於表示函式、變數等的名稱
  3. 例如:_abc,$abc,abc,abc123是識別符號,而1abc不是
  4. JavaScript語言中代表特定含義的詞稱為保留字,不允許程式再定義為識別符號

2.4 資料型別

數字型別(Number)

簡介
最基本的資料型別
不區分整型數值和浮點型數值
所有數字都採用64位浮點格式儲存,相當於Java和C語言中的double格式
能表示的最大值是±1.7976931348623157 x 10308 
能表示的最小值是±5 x 10 -324 

整數:
在JavaScript中10進位制的整數由數字的序列組成
精確表達的範圍是
-9007199254740992 (-253) 到 9007199254740992 (253)
超出範圍的整數,精確度將受影響
浮點數:
使用小數點記錄資料
例如:3.4,5.6
使用指數記錄資料
例如:4.3e23 = 4.3 x 1023

16進位制和8進位制數的表達
16進位制資料前面加上0x,八進位制前面加0
16進位制數是由0-9,A-F等16個字元組成
8進位制數由0-7等8個數字組成
16進位制和8進位制與2進位制的換算

# 2進位制: 1111 0011 1101 0100   <-----> 16進位制:0xF3D4 <-----> 10進位制:62420
# 2進位制: 1 111 001 111 010 100 <-----> 8進位制:0171724

字串(String)

簡介
是由Unicode字元、數字、標點符號組成的序列
字串常量首尾由單引號或雙引號括起
JavaScript中沒有字元型別
常用特殊字元在字串中的表達
字串中部分特殊字元必須加上右劃線\
常用的轉義字元 \n:換行  \':單引號   \":雙引號  \\:右劃線

String資料型別的使用

  • 特殊字元的使用方法和效果
  • Unicode的插入方法
1 2 3 4 <script> varstr="\u4f60\u597d\n歡迎來到\"JavaScript世界\""; alert(str); </script>

布林型(Boolean)

簡介
Boolean型別僅有兩個值:true和false,也代表1和0,實際運算中true=1,false=0
布林值也可以看作on/off、yes/no、1/0對應true/false
Boolean值主要用於JavaScript的控制語句,例如
    if (x==1){
    y=y+1;
    }else    {
    y=y-1;
    }

Null & Undefined

Undefined 型別

Undefined 型別只有一個值,即 undefined。當宣告的變數未初始化時,該變數的預設值是 undefined。

當函式無明確返回值時,返回的也是值 "undefined";

Null 型別

另一種只有一個值的型別是 Null,它只有一個專用值 null,即它的字面量。值 undefined 實際上是從值 null 派生來的,因此 ECMAScript 把它們定義為相等的。

儘管這兩個值相等,但它們的含義不同。undefined 是聲明瞭變數但未對其初始化時賦予該變數的值,null 則用於表示尚未存在的物件(在討論 typeof 運算子時,簡單地介紹過這一點)。如果函式或方法要返回的是物件,那麼找不到該物件時,返回的通常是 null。

var person=new Person()

var person=null

資料型別轉換

JavaScript屬於鬆散型別的程式語言
變數在宣告的時候並不需要指定資料型別
變數只有在賦值的時候才會確定資料型別
表示式中包含不同型別資料則在計算過程中會強制進行類別轉換

數字 +字串:數字轉換為字串

數字+ 布林值:true轉換為1,false轉換為0

字串 +布林值:布林值轉換為字串true或false

強制型別轉換函式

函式parseInt:   強制轉換成整數   例如parseInt("6.12")=6  ; parseInt(“12a")=12 ; parseInt(“a12")=NaN  ;parseInt(“1a2")=1

函式parseFloat: 強制轉換成浮點數  parseFloat("6.12")=6.12

函式eval:       將字串強制轉換為表示式並返回結果 eval("1+1")=2 ; eval("1<2")=true

型別查詢函式(typeof)

ECMAScript 提供了 typeof 運算子來判斷一個值是否在某種型別的範圍內。可以用這種運算子判斷一個值是否表示一種原始型別:如果它是原始型別,還可以判斷它表示哪種原始型別。

函式typeof :查詢數值當前型別
 (string / number / boolean / object )
例如typeof("test"+3) "string" 例如typeof(null) "object " 例如typeof(true+1) "number" 例如typeof(true-false) "number"

ECMAScript 運算子

ECMAScript算數運算子

加(+)、 減(-)、 乘(*) 、除(/) 、餘數(% )  加、減、乘、除、餘數和數學中的運算方法一樣  例如:9/2=4.5,4*5=20,9%2=1
-除了可以表示減號還可以表示負號 例如:x=-y
+除了可以表示加法運算還可以用於字串的連線 例如:"abc"+"def"="abcdef"

遞增(++) 、遞減(--)

假如x=2,那麼x++表示式執行後的值為3,x--表示式執行後的值為1
i++相當於i=i+1,i--相當於i=i-1
遞增和遞減運算子可以放在變數前也可以放在變數後:--i

var i=1;
console.log(i++);
console.log(++i);
console.log(i--);
console.log(--i);

一元加減法:

    var a=1;
var b=1;
a=-a; //a=-1

var c="10";
alert(typeof (c));
c=+c; //型別轉換
alert(typeof (c));
// -------------------
var d="yuan";
d=+d;
alert(d);//NaN:屬於Number型別的一個特殊值,當遇到將字串轉成數字無效時,就會得到一個NaN資料
alert(typeof(d));//Number

//NaN特點:

var n=NaN;

alert(n>3);
alert(n<3);
alert(n==3);
alert(n==NaN);

alert(n!=NaN);//NaN參與的所有的運算都是false,除了!=

ECMAScript邏輯運算子

等於 ( == )  、不等於( != ) 、 大於( > ) 、 小於( < ) 
大於等於(>=) 、小於等於(<=)
與 (&&) 、或(||) 、非(!)
1 && 1 = 1  1 || 1 = 1
1 && 0 = 0 1 || 0 = 1
0 && 0 = 0 0 || 0 = 0

!0=1
!1=0

邏輯 AND 運算子(&&)

邏輯 AND 運算的運算數可以是任何型別的,不止是 Boolean 值。

如果某個運算數不是原始的 Boolean 型值,邏輯 AND 運算並不一定返回 Boolean 值:

  • 如果某個運算數是 null,返回 null。
  • 如果某個運算數是 NaN,返回 NaN。
  • 如果某個運算數是 undefined,返回undefined。

邏輯 OR 運算子(||)

與邏輯 AND 運算子相似,如果某個運算數不是 Boolean 值,邏輯 OR 運算並不一定返回 Boolean 值

ECMAScript賦值運算子

賦值 = 
JavaScript中=代表賦值,兩個等號==表示判斷是否相等
例如,x=1表示給x賦值為1
if (x==1){...}程式表示當x與1相等時
if(x==“on”){…}程式表示當x與“on”相等時
 配合其他運算子形成的簡化表示式
例如i+=1相當於i=i+1,x&=y相當於x=x&y

例項:

2 == “2”        
2 === “2”        
4 != “4”            
4 !== “4”        

var a = 2; var b = 4;
var c = a<b | --b>--a;
var c = a<b || --b>--a; 
 var c = a<b &&--b>--a;
var c = a<b & --b>--a; 

ECMAScript等性運算子

執行型別轉換的規則如下:

  • 如果一個運算數是 Boolean 值,在檢查相等性之前,把它轉換成數字值。false 轉換成 0,true 為 1。
  • 如果一個運算數是字串,另一個是數字,在檢查相等性之前,要嘗試把字串轉換成數字。
  • 如果一個運算數是物件,另一個是字串,在檢查相等性之前,要嘗試把物件轉換成字串。
  • 如果一個運算數是物件,另一個是數字,在檢查相等性之前,要嘗試把物件轉換成數字。

在比較時,該運算子還遵守下列規則:

  • 值 null 和 undefined 相等。
  • 在檢查相等性時,不能把 null 和 undefined 轉換成其他值。
  • 如果某個運算數是 NaN,等號將返回 false,非等號將返回 true。
  • 如果兩個運算數都是物件,那麼比較的是它們的引用值。如果兩個運算數指向同一物件,那麼等號返回 true,否則兩個運算數不等。

ECMAScript 關係運算符(重要)

1 2 varbResult ="Blue"<"alpha"; alert(bResult);//輸出 true  

在上面的例子中,字串 "Blue" 小於 "alpha",因為字母 B 的字元程式碼是 66,字母 a 的字元程式碼是 97。

比較數字和字串

另一種棘手的狀況發生在比較兩個字串形式的數字時,比如:

1 2 varbResult ="25"<"3"; alert(bResult);//輸出 "true"

上面這段程式碼比較的是字串 "25" 和 "3"。兩個運算數都是字串,所以比較的是它們的字元程式碼("2" 的字元程式碼是 50,"3" 的字元程式碼是 51)。

不過,如果把某個運算數該為數字,那麼結果就有趣了:

1 2 varbResult ="25"< 3; alert(bResult);//輸出 "false"

這裡,字串 "25" 將被轉換成數字 25,然後與數字 3 進行比較,結果不出所料。

總結:

1 2 比較運算子兩側如果一個是數字型別,一個是其他型別,會將其型別轉換成數字型別. 比較運算子兩側如果都是字串型別,比較的是最高位的asc碼,如果最高位相等,繼續取第二位比較.

Boolean運算子(重要)

var temp=new Object();// false;[];0; null; undefined;object(new Object();)

    if(temp){
        console.log("yuan")
    }else {
        console.log("alex")
    }

全等號和非全等號

等號和非等號的同類運算子是全等號和非全等號。這兩個運算子所做的與等號和非等號相同,只是它們在檢查相等性前,不執行型別轉換。

控制語句

if 控制語句

if-else基本格式
if (表示式){
語句1;
......
}else{
語句2;
.....
}
功能說明
如果表示式的值為true則執行語句1,
否則執行語句2

var x= (new Date()).getDay();
//獲取今天的星期值,0為星期天
var y;

if ( (x==6) || (x==0) ) {
y="週末";
}else{
y="工作日";
}

alert(y);

//等價於

y="工作日";
if ( (x==6) || (x==0) ) {
y="週末";
}

if 可以單獨使用

if語句巢狀格式
if (表示式1) {
    語句1;
}else if (表示式2){
    語句2;
}else if (表示式3){
    語句3;
} else{
    語句4;
}

View Code

switch 選擇控制語句

switch基本格式
switch (表示式) {
    case 值1:語句1;break;
    case 值2:語句2;break;
    case 值3:語句3;break;
    default:語句4;
}

switch(x){
case 1:y="星期一";    break;
case 2:y="星期二";    break;
case 3:y="星期三";    break;
case 4:y="星期四";    break;
case 5:y="星期五";    break;
case 6:y="星期六";    break;
case 7:y="星期日";    break;
default: y="未定義";
}

switchelse if結構更加簡潔清晰,使程式可讀性更強,效率更高。

首先要看一個問題,if 語句適用範圍比較廣,只要是 boolean 表示式都可以用 if 判斷;而 switch 只能對基本型別進行數值比較。兩者的可比性就僅限在兩個基本型別比較的範圍內。
說到基本型別的數值比較,那當然要有兩個數。然後重點來了——
if 語句每一句都是獨立的,看下面的語句:
if (a == 1) ...
else if (a == 2) ...
這樣 a 要被讀入暫存器兩次,1 和 2 分別被讀入暫存器一次。於是你是否發現其實 a 讀兩次是有點多餘的,在你全部比較完之前只需要一次讀入暫存器就行了,其餘都是額外開銷。但是 if 語句必須每次都把裡面的兩個數從記憶體拿出來讀到暫存器,它不知道你其實比較的是同一個 a。
於是 switch case 就出來了,把上面的改成 switch case 版本:
switch (a) {
        case 0:
                break;
        case 1:
}
                
總結:

1.switch用來根據一個整型值進行多路分支,並且編譯器可以對多路分支進行優化
2.switch-case只將表示式計算一次,然後將表示式的值與每個case的值比較,進而選
  擇執行哪一個case的語句塊
3.if..else 的判斷條件範圍較廣,每條語句基本上獨立的,每次判斷時都要條件載入
  一次。
所以在多路分支時用switch比if..else if .. else結構要效率高。

for 迴圈控制語句

for迴圈基本格式
for (初始化;條件;增量){
    語句1;
    ...
}
功能說明
實現條件迴圈,當條件成立時,執行語句1,否則跳出迴圈體

for (var i=1;i<=7;i++){
    document.write("<H"+i+">hello</H "+i+"> ");
    document.write("<br>");
}
----------------------------------------------
    var arr=[1,"hello",true]//var dic={"1":"111"}
    for (var i in arr){
        console.log(i)
        console.log(arr[i])
    }

注意:

    doms=document.getElementsByTagName("p");

    for (var i in doms){
       console.log(i); // 0 1 2 length item namedItem
       //console.log(doms[i])
    }

//迴圈的是你獲取的th一個DOM元素集,for in用來迴圈物件的所有屬性,dom元素集包含了你上面輸出的屬性。
//如果你只要迴圈dom物件的話,可以用for迴圈:

    for (var i=0;i<doms.length;i++){
        console.log(i) ; // 0 1 2
        //console.log(doms[i])
    }

結論:for i in 不推薦使用.

while 迴圈控制語句

while迴圈基本格式
while (條件){
語句1;
...
}
功能說明
執行功能和for類似,當條件成立迴圈執行語句花括號{}內的語句,否則跳出迴圈

var i=1;
while (i<=7) {
    document.write("<H"+i+">hello</H "+i+"> ");
    document.write("<br>");
    i++;
}
//迴圈輸出H1到H7的字型大小
View Code

練習:分別用for迴圈和while迴圈計算出1-100的和?

異常處理

1 2 3 4 5 6 7 8 9 10 try{ //這段程式碼從上往下執行,其中任何一個語句丟擲異常該程式碼塊就結束執行 } catch(e) { // 如果try程式碼塊中丟擲了異常,catch程式碼塊中的程式碼就會被執行。 //e是一個區域性變數,用來指向Error物件或者其他丟擲的物件 } finally { //無論try中程式碼是否有異常丟擲(甚至是try程式碼塊中有return語句),finally程式碼塊中始終會被執行。 }

注:主動丟擲異常 throw Error('xxxx')  

ECMA物件

從傳統意義上來說,ECMAScript 並不真正具有類。事實上,除了說明不存在類,在 ECMA-262 中根本沒有出現“類”這個詞。ECMAScript 定義了“物件定義”,邏輯上等價於其他程式設計語言中的類。

var o = new Object();

物件的概念與分類:

  • 由ECMAScript定義的本地物件.獨立於宿主環境的 ECMAScript 實現提供的物件.(native object)
  • ECMAScript 實現提供的、獨立於宿主環境的所有物件,在 ECMAScript 程式開始執行時出現.這意味著開發者不必明確例項化內建物件,它已被例項化了。ECMA-262 只定義了兩個內建物件,即 Global 和 Math (它們也是本地物件,根據定義,每個內建物件都是本地物件)。(built-in object)
  • 所有非本地物件都是宿主物件(host object),即由 ECMAScript 實現的宿主環境提供的物件。所有 BOM 和 DOM 物件都是宿主物件。

object物件ECMAScript 中的所有物件都由這個物件繼承而來;Object 物件中的所有屬性和方法都會出現在其他物件中

ToString() :  返回物件的原始字串表示。
ValueOf() : 返回最適合該物件的原始值。對於許多物件,該方法返回的值都與 ToString() 的返回值相同。

11種內建物件

包括:

Array ,String , Date, Math, Boolean, Number Function, Global, Error, RegExp , Object

簡介:

JavaScript中除了nullundefined以外其他的資料型別都被定義成了物件,也可以用建立物件的方法定義變數,StringMathArrayDateRegExp都是JavaScript中重要的內建物件,在JavaScript程式大多數功能都是通過物件實現的

<script language="javascript">
var aa=Number.MAX_VALUE; 
//利用數字物件獲取可表示最大數
var bb=new String("hello JavaScript"); 
//建立字串物件
var cc=new Date();
//建立日期物件
var dd=new Array("星期一","星期二","星期三","星期四"); 
//陣列物件
</script>

String物件

自動建立字串物件:

1 2 3 var str1="hello world"; alert(str1.length); alert(str1.substr(1,5));

呼叫字串的物件屬性或方法時自動建立物件,用完就丟棄

手工建立字串物件

1 2 3 var str1=new String("hello word"); alert(str1.length); alert(str1.substr(1,3));

採用new建立字串物件str1,全域性有效

String物件的屬性

1 2 獲取字串長度 length

var str1="String物件";

var str2="";

alert("str1長度"+str1.length);

alert("str2長度"+str2.length);

 

String物件的方法(1) —— 格式編排方法

格式編排方法返回值列表

書寫格式:

String物件提供了一組針對HTML格式的方法,如x.anchor()返回錨定義字串<a>x</a>,
x.bold()返回粗體表示字串<b>x</b>,x.sup()返回上標格式字串<sup>x</sup>。
-----------------------------------------

var x="yuan";
var y="x.italics():"+x.italics();
document.write(y.fontsize(10));//<font size="10">x.italics():<i>yuan</i></font>

String物件的方法(2)—— 大小寫轉換

var str1="AbcdEfgh"; 

var str2=str1.toLowerCase();
var str3=str1.toUpperCase();
alert(str2);
//結果為"abcdefgh"
alert(str3);
//結果為"ABCDEFGH"

String物件的方法(3) —— 獲取指定字元

書寫格式

x.charAt(index)

x.charCodeAt(index)

使用註解

x代表字串物件
index代表字元位置
index從0開始編號
charAt返回index位置的字元
charCodeAt返回index位置的Unicode編碼
----------------------
var str1="welcome to the world of JS! 苑昊";

var str2=str1.charAt(28);
var str3=str1.charCodeAt(28);
alert(str2);
//結果為"苑"
alert(str3);
//結果為33489

String物件的方法(4)—— 查詢字串

//書寫格式
//
//x.indexOf(findstr,index)
//x.lastIndexOf(findstr)
//-------------------------------------
var str1="welcome to the world of JS!";

var str2=str1.indexOf("l");
var str3=str1.lastIndexOf("l");
alert(str2);
//結果為2
alert(str3);
//結果為18

//-------*********************************************************-------

//書寫格式
//
//x.match(regexp)
//
//x.search(regexp)
//
//使用註解
//
//x代表字串物件
//
//regexp代表正則表示式或字串
//
//match返回匹配字串的陣列,如果沒有匹配則返回null
//
//search返回匹配字串的首字元位置索引
//-------------------------------------
var str1="welcome to the world of JS!";

var str2=str1.match("world");
var str3=str1.search("world");
alert(str2[0]);
//結果為"world"
alert(str3);
//結果為15

String物件的方法(5) ——子字串處理

擷取子字串

//擷取子字串
//
//書寫格式
//
//x.substr(start, length)
//
//x.substring(start, end)
//
//使用註解
//
//x代表字串物件
//
//start表示開始位置
//
//length表示擷取長度
//
//end是結束位置加1
//
//第一個字元位置為0


var str1="abcdefgh";
var str2=str1.substr(2,4);
var str3=str1.substring(2,4);
alert(str2);
//結果為"cdef"
alert(str3);
//結果為"cd"

//-------*********************************************************-------
//x.slice(start, end)


var str1="abcdefgh";
var str2=str1.slice(2,4);
var str3=str1.slice(4);
var str4=str1.slice(2,-1);
var str5=str1.slice(-3,-1);
alert(str2);
//結果為"cd"
alert(str3);
//結果為"efgh"
alert(str4);
//結果為"cdefg"
alert(str5);
//結果為"fg"

替換子字串

//x.replace(findstr,tostr)

var str1="abcdefgh";
var str2=str1.replace("cd","aaa");
alert(str2);
//結果為"abaaaefgh"

分割字串

var str1="一,二,三,四,五,六,日"; 

var strArray=str1.split(",");

alert(strArray[1]);
//結果為"二"

連線字串

//y=x.concat(addstr)
//
//使用註解
//
//x代表字串物件
//addstr為新增字串
//返回x+addstr字串
    
var str1="abcd"; 
var str2=str1.concat("efgh");

alert(str2);
//結果為"abcdefgh" 

Array物件

建立陣列物件

Array 物件用於在單個的變數中儲存多個值。
語法:

建立方式1:
var a=[1,2,3];

建立方式2:
new Array();     //  建立陣列時允許指定元素個數也可以不指定元素個數。
new Array(size);//if 1個引數且為數字,即代表size,not content
    初始化陣列物件:
    var cnweek=new Array(7);
        cnweek[0]="星期日";
        cnweek[1]="星期一";
        ...
        cnweek[6]="星期六";

new Array(element0, element1, ..., elementn)//也可以直接在建立物件時初始化陣列元素,元素型別允許不同

var test=new Array(100,"a",true);

建立二維陣列

var cnweek=new Array(7);
for (var i=0;i<=6;i++){
    cnweek[i]=new Array(2);
}
cnweek[0][0]="星期日";
cnweek[0][1]="Sunday";
cnweek[1][0]="星期一";
cnweek[1][1]="Monday";
...
cnweek[6][0]="星期六";
cnweek[6][1]="Saturday";

Array物件的屬性

獲取陣列元素的個數:length

var cnweek=new Array(7);
cnweek[0]="星期日";
cnweek[1]="星期一";
cnweek[2]="星期二";
cnweek[3]="星期三";
cnweek[4]="星期四";
cnweek[5]="星期五";
cnweek[6]="星期六";
for (var i=0;i<cnweek.length;i++){
  document.write(cnweek[i]+" | ");
}

Array物件的方法

連線陣列-join方法

//書寫格式
//x.join(bystr)
//使用註解
//
//x代表陣列物件
//bystr作為連線陣列中元素的字串
//返回連線後的字串
//與字串的split功能剛好相反
    
var arr1=[1, 2, 3, 4, 5, 6, 7];

var str1=arr1.join("-");

alert(str1);
//結果為"1-2-3-4-5-6-7" 

連線陣列-concat方法

//連線陣列-concat方法
//
//x.concat(value,...)


var a = [1,2,3];
var a = new Array(1,2,3);
var b=a.concat(4,5) ;


alert(a.toString());
//返回結果為1,2,3
alert(b.toString());
//返回結果為1,2,3,4,5

陣列排序-reverse sort

//x.reverse()
//x.sort()

var arr1=[32, 12, 111, 444];
//var arr1=["a","d","f","c"];

arr1.reverse(); //顛倒陣列元素
alert(arr1.toString());
//結果為444,111,12,32

arr1.sort();    //排序陣列元素
alert(arr1.toString());
//結果為111,12,32,444

//------------------------------
arr=[1,5,2,100];

//arr.sort();
//alert(arr);
//如果就想按著數字比較呢?

function intSort(a,b){
    if (a>b){
        return 1;//-1
    }
    else if(a<b){
        return -1;//1
    }
    else {
        return 0
    }
}

arr.sort(intSort);

alert(arr);

function IntSort(a,b){
    return a-b;
}

陣列切片-slice

//x.slice(start, end)
//
//使用註解
//
//x代表陣列物件
//start表示開始位置索引
//end是結束位置下一陣列元素索引編號
//第一個陣列元素索引為0
//start、end可為負數,-1代表最後一個數組元素
//end省略則相當於從start位置擷取以後所有陣列元素

var arr1=['a','b','c','d','e','f','g','h'];
var arr2=arr1.slice(2,4);
var arr3=arr1.slice(4);
var arr4=arr1.slice(2,-1);

alert(arr2.toString());
//結果為"c,d" 
alert(arr3.toString());
//結果為"e,f,g,h"
alert(arr4.toString());
//結果為"c,d,e,f,g"

刪除子陣列

//x. splice(start, deleteCount, value, ...)
//
//使用註解
//
//x代表陣列物件
//splice的主要用途是對陣列指定位置進行刪除和插入
//start表示開始位置索引
//deleteCount刪除陣列元素的個數
//value表示在刪除位置插入的陣列元素
//value引數可以省略


var a = [1,2,3,4,5,6,7,8];
a.splice(1,2);
//a變為 [1,4,5,6,7,8]
alert(a.toString());
a.splice(1,1);
 //a變為[1,5,6,7,8]
alert(a.toString());
a.splice(1,0,2,3);
 //a變為[1,2,3,5,6,7,8]
alert(a.toString());

陣列的進出棧操作(1)

//push pop這兩個方法模擬的是一個棧操作

//x.push(value, ...)  壓棧
//x.pop()             彈棧      
//使用註解
//
//x代表陣列物件
//value可以為字串、數字、陣列等任何值
//push是將value值新增到陣列x的結尾
//pop是將陣列x的最後一個元素刪除


var arr1=[1,2,3];
arr1.push(4,5);
alert(arr1);
//結果為"1,2,3,4,5"
arr1.push([6,7]);
alert(arr1)
//結果為"1,2,3,4,5,6,7"
arr1.pop();
alert(arr1);
//結果為"1,2,3,4,5"

陣列的進出棧操作(2)

// unshift shift 
//x.unshift(value,...)
//x.shift()
//使用註解
//
//x代表陣列物件
//value可以為字串、數字、陣列等任何值
//unshift是將value值插入到陣列x的開始
//shift是將陣列x的第一個元素刪除

var arr1=[1,2,3];
arr1.unshift(4,5);
alert(arr1);
//結果為"4,5,1,2,3"
arr1. unshift([6,7]);
alert(arr1);
//結果為"6,7,4,5,1,2,3"
arr1.shift();
alert(arr1);
//結果為"4,5,1,2,3"

總結js的陣列特性:

//  js中陣列的特性
         //java中陣列的特性,  規定是什麼型別的陣列,就只能裝什麼型別.只有一種型別.
         //js中的陣列特性1: js中的陣列可以裝任意型別,沒有任何限制.
         //js中的陣列特性2: js中的陣列,長度是隨著下標變化的.用到多長就有多長.
         var arr5 = ['abc',123,1.14,true,null,undefined,new String('1213'),new Function('a','b','alert(a+b)')];
        /*  alert(arr5.length);//8
         arr5[10] = "hahaha";
         alert(arr5.length); //11
         alert(arr5[9]);// undefined */

Date物件

建立Date物件

//方法1:不指定引數
var nowd1=new Date();
alert(nowd1.toLocaleString( ));
//方法2:引數為日期字串
var nowd2=new Date("2004/3/20 11:12");
alert(nowd2.toLocaleString( ));
var nowd3=new Date("04/03/20 11:12");
alert(nowd3.toLocaleString( ));
//方法3:引數為毫秒數
var nowd3=new Date(5000);
alert(nowd3.toLocaleString( ));
alert(nowd3.toUTCString());

//方法4:引數為年月日小時分鐘秒毫秒
var nowd4=new Date(2004,2,20,11,12,0,300);
alert(nowd4.toLocaleString( ));
//毫秒並不直接顯示

Date物件的方法—獲取日期和時間

獲取日期和時間
getDate()                 獲取日
getDay ()                 獲取星期
getMonth ()               獲取月(0-11)
getFullYear ()            獲取完整年份
getYear ()                獲取年
getHours ()               獲取小時
getMinutes ()             獲取分鐘
getSeconds ()             獲取秒
getMilliseconds ()        獲取毫秒
getTime ()                返回累計毫秒數(從1970/1/1午夜)

練習例項:

function getCurrentDate(){
        //1. 建立Date物件
        var date = new Date(); //沒有填入任何引數那麼就是當前時間
        //2. 獲得當前年份
        var year = date.getFullYear();
        //3. 獲得當前月份 js中月份是從0到11.
        var month = date.getMonth()+1;
        //4. 獲得當前日
        var day = date.getDate();
        //5. 獲得當前小時
        var hour = date.getHours();
        //6. 獲得當前分鐘
        var min = date.getMinutes();
        //7. 獲得當前秒
        var sec = date.getSeconds();
        //8. 獲得當前星期
        var week = date.getDay(); //沒有getWeek
        // 2014年06月18日 15:40:30 星期三
        return year+"年"+changeNum(month)+"月"+day+"日 "+hour+":"+min+":"+sec+" "+parseWeek(week);
    }

alert(getCurrentDate());

//解決 自動補齊成兩位數字的方法
    function changeNum(num){
    if(num < 10){
        return "0"+num;
    }else{
        return num;
    }

}
//將數字 0~6 轉換成 星期日到星期六
    function parseWeek(week){
    var arr = ["星期日","星期一","星期二","星期三","星期四","星期五","星期六"];
    //             0      1      2      3 .............
    return arr[week];
}

Date物件的方法—設定日期和時間

//設定日期和時間
//setDate(day_of_month)       設定日
//setMonth (month)                 設定月
//setFullYear (year)               設定年
//setHours (hour)         設定小時
//setMinutes (minute)     設定分鐘
//setSeconds (second)     設定秒
//setMillliseconds (ms)       設定毫秒(0-999)
//setTime (allms)     設定累計毫秒(從1970/1/1午夜)
    
var x=new Date();
x.setFullYear (1997);    //設定年1997
x.setMonth(7);        //設定月7
x.setDate(1);        //設定日1
x.setHours(5);        //設定小時5
x.setMinutes(12);    //設定分鐘12
x.setSeconds(54);    //設定秒54
x.setMilliseconds(230);        //設定毫秒230
document.write(x.toLocaleString( )+"<br>");
//返回1997年8月1日5點12分54秒

x.setTime(870409430000); //設定累計毫秒數
document.write(x.toLocaleString( )+"<br>");
//返回1997年8月1日12點23分50秒  

Date物件的方法—日期和時間的轉換

日期和時間的轉換:

getTimezoneOffset():8個時區×15度×4分/度=480;
返回本地時間與GMT的時間差,以分鐘為單位
toUTCString()
返回國際標準時間字串
toLocalString()
返回本地格式時間字串
Date.parse(x)
返回累計毫秒數(從1970/1/1午夜到本地時間)
Date.UTC(x)
返回累計毫秒數(從1970/1/1午夜到國際時間)

RegExp物件

//RegExp物件
    // 在表單驗證時使用該物件驗證使用者填入的字串是否符合規則.
    //建立正則物件方式1  引數1 正則表示式  引數2 驗證模式  g global / i 忽略大小寫. //引數2一般填寫g就可以,也有“gi”.
    // 使用者名稱 首字母必須是英文, 除了第一位其他只能是英文數字和_ . 長度最短不能少於6位 最長不能超過12位
    //----------------------------建立方式1
    /* var reg1 = new RegExp("^[a-zA-Z][a-zA-Z0-9_]{5,11}$","g");
    //
    //驗證字串
    var str = "bc123";
    alert(reg1.test(str));// true
    
    //----------------------------建立方式2  /填寫正則表示式/匹配模式;
    var reg2 = /^[a-zA-Z][a-zA-Z0-9_]{5,11}$/g;
    
    alert(reg2.test(str));// true
     */
    //-------------------------------正則物件的方法-------------------
        //test方法  ==>  測試一個字串是否複合 正則規則. 返回值是true 和false.
    
    //-------------------------String 中與正則結合的4個方法------------------.
    // macth search split replace
    var str = "hello world";
    
    //alert(str.match(/o/g)); //查詢字串中 複合正則的 內容.
    //alert(str.search(/h/g));// 0  查詢字串中符合正則表示式的內容位置
    //alert(str.split(/o/g)); // 按照正則表示式對字串進行切割. 返回陣列;
    alert(str.replace(/o/g, "s")); // hells wsrld  對字串按照正則進行替換.

Math物件

    //Math物件
    //該物件中的屬性方法 和數學有關.
    //Math是內建物件 , 與Global的不同之處是, 在呼叫時 需要打出 "Math."字首.
    //屬性學習:
    //alert(Math.PI);
    //方法學習:
        //alert(Math.random()); // 獲得隨機數 0~1 不包括1.
        //alert(Math.round(1.5)); // 四捨五入
        //練習:獲取1-100的隨機整數,包括1和100
             //var num=Math.random();
            //num=num*10;
            //num=Math.round(num);
            // alert(num)
        //============max  min=========================
        /* alert(Math.max(1,2));// 2
        alert(Math.min(1,2));// 1 */
        //-------------pow--------------------------------
        alert(Math.pow(2,4));// pow 計算引數1 的引數2 次方.
        



abs(x)    返回數的絕對值。
exp(x)    返回 e 的指數。
floor(x)對數進行下舍入。
log(x)    返回數的自然對數(底為e)。
max(x,y)    返回 x 和 y 中的最高值。
min(x,y)    返回 x 和 y 中的最低值。
pow(x,y)    返回 x 的 y 次冪。
random()    返回 0 ~ 1 之間的隨機數。
round(x)    把數四捨五入為最接近的整數。
sin(x)    返回數的正弦。
sqrt(x)    返回數的平方根。
tan(x)    返回角的正切。

Function 物件(重點)

函式的定義:

1 2 3 function 函式名 (引數){
函式體; return返回值; }

功能說明:

  • 可以使用變數、常量或表示式作為函式呼叫的引數
  • 函式由關鍵字function定義
  • 函式名的定義規則與識別符號一致,大小寫是敏感的
  • 返回值必須使用return

Function類可以表示開發者定義的任何函式。

Function類直接建立函式的語法如下:

function 函式名 (引數){

函式體;
return 返回值;
}
//another way:
var 函式名 = new Function("引數1","引數n","function_body");

雖然由於字串的關係,第二種形式寫起來有些困難,但有助於理解函式只不過是一種引用型別,它們的行為與用Function類明確建立的函式行為是相同的。

例項:

1 2 3 4 5 6 7 8 9 10 11 12 alert(1); functionfunc1(){ alert('hello yuan!'); return8 } ret=func1(); alert(ret) ---------------- varfunc1=newFunction("name","alert(\"hello\"+name);") func1("yuan")

注意:js的函式載入執行與python不同,它是整體載入完才會執行,所以執行函式放在函式宣告上面或下面都可以:

<script>
    //f(); --->OK

    function f(){
        console.log("hello")

    }

    f() //----->OK
</script>

Function 物件的 length 屬性

如前所述,函式屬於引用型別,所以它們也有屬性和方法。

比如,ECMAScript定義的屬性length聲明瞭函式期望的引數個數。

1 alert(func1.length)

Function 物件的方法

Function物件也有與所有物件共享的valueOf()方法和toString()方法。這兩個方法返回的都是函式的原始碼,在除錯時尤其有用。

1 alert(void(fun1(1,2)))

運算子void()作用:攔截方法的返回值 

函式的呼叫

function func1(a,b){

    alert(a+b);
}

    func1(1,2);  //3
    func1(1,2,3);//3
    func1(1);    //NaN
    func1();     //NaN

    //只要函式名寫對即可,引數怎麼填都不報錯.

-------------------面試題-----------
 function a(a,b){
    alert(a+b);
}

   var a=1;
   var b=2;
   a(a,b)

函式的內建物件arguments

function add(a,b){

        console.log(a+b);//3
        console.log(arguments.length);//2
        console.log(arguments);//[1,2]

    }
    add(1,2)

    ------------------arguments的用處1 ------------------
    function nxAdd(){
        var result=0;
        for (var num in arguments){
            result+=arguments[num]
        }
        alert(result)

    }

    nxAdd(1,2,3,4,5)

//     ------------------arguments的用處2 ------------------

    function f(a,b,c){
        if (arguments.length!=3){
            throw new Error("function f called with "+arguments.length+" arguments,but it just need 3 arguments")
        }
        else {
            alert("success!")
        }
    }

    f(1,2,3,4,5)

匿名函式

// 匿名函式
    var func = function(arg){
        return "tony";
    }

// 匿名函式的應用
    (function(){
        alert("tony");
    } )()

    (function(arg){
        console.log(arg);
    })('123')

函式的作用域鏈和閉包

作用域

js的作用域和py相似,if while等控制語句並沒有自己作用域;而函式是有自己的作用域的;

if(1==1){
var s=12; } console.log(s);//12 // ---------------------- function f(){ var temp=666; } f(); console.log(temp);//Uncaught ReferenceError: temp is not defined

巢狀函式的作用域:

例1:

var city = 'beijing';

    function func(){
        var city = 'shanghai';
        function inner(){
            var city = 'shenzhen';
            console.log(city);
        }
        inner();
    }
    func();

例2:

var city = 'beijing';
function Bar(){
    console.log(city);
}
function func(){

    var city = 'shanghai';
    return Bar;
}
var ret = func();
ret();    //beijing

閉包:

var city = 'beijing';

function func(){
    var city = "shanghai";
    function inner(){
        // var city = "langfang";
        console.log(city);
    }
    return inner;
}
var ret = func();
ret();

思考題1:

var city = 'beijing';

function func(){
    var city = "shanghai";

    function inner(){
        // var city = "langfang";
        console.log(city);
    }

    return inner;
}

var ret = func();
ret();


var city = 'beijing';

function Bar(){
    console.log(city);
}

function func(){

    var city = 'shanghai';
    return Bar;
}

var ret = func();
ret();    //beijing

作用域鏈(Scope Chain):

在JavaScript中,函式也是物件,實際上,JavaScript裡一切都是物件。函式物件和其它物件一樣,擁有可以通過程式碼訪問的屬性和一系列僅供JavaScript引擎訪問的內部屬性。其中一個內部屬性是[[Scope]],由ECMA-262標準第三版定義,該內部屬性包含了函式被建立的作用域中物件的集合,這個集合被稱為函式的作用域鏈,它決定了哪些資料能被函式訪問。

var x=1;
function foo() {
    var y = 2;
    
    function bar() {
        var z = 3;
    }
}

#bar的作用域鏈: barScopeChain=[bar.AO, foo.AO, global.VO];
#foo的作用域鏈: fooScopeChain=[foo.Ao, global.VO];
什麼是AO,VO?
       在函式建立時,每個函式都會建立一個活動物件Active Object(AO),全域性物件為Global Object(VO),建立函式的過程也就是為這個物件新增屬性的過程,作用域鏈就是由這些綁定了屬性的活動物件構成的。
        例如:找x變數;bar函式在搜尋變數x的過程中,先從自身AO物件上找,如果bar.AO存在這個屬性,那麼會直接使用這個屬性的值,如果不存在,則會轉到父級函式的AO物件,也就是foo.AO
        如果找到x屬性則使用,找不到繼續 在global.VO物件查詢,找到x的屬性,返回屬性值。如果在global.VO中沒有找到,則會丟擲異常ReferenceError

執行上下文。
       函式在執行時會建立一個稱為“執行上下文(execution context)”的內部物件,執行上下文定義了函式
       執行時的環境。每個執行上下文都有自己的作用域鏈,用於識別符號解析,當執行上下文被建立時,而它的作用
       域鏈初始化為當前執行函式的[[Scope]]所包含的物件。
函式執行
       在函式執行過程中,每遇到一個變數,都會檢索從哪裡獲取和儲存資料,該過程從作用域鏈頭部,也就是從活
       動物件開始搜尋,查詢同名的識別符號,如果找到了就使用這個識別符號對應的變數,如果沒有則繼續搜尋作用域
       鏈中的下一個物件,如果搜尋完所有物件都未找到,則認為該識別符號未定義,函式執行過程中,每個識別符號都
       要經歷這樣的搜尋過程。
建立作用域鏈的過程
      函式進入全域性,建立VO物件,繫結x屬性<入棧>
        global.VO={x=underfind; foo:reference of function}(這裡只是預解析,為AO物件繫結宣告的屬性,函式執行時才會執行賦值語句,所以值是underfind)
     遇到foo函式,建立foo.AO,繫結y屬性<入棧>
     foo.AO={y=underfind, bar:reference of function}
     遇到bar函式,建立bar.AO,繫結z屬性<入棧>
      bar.AO={z:underfind}
    作用域鏈和執行上下文都會儲存在堆疊中,所以:
    bar函式的scope chain為:[0]bar.AO-->[1]foo.AO-->[2]global.VO

          foo函式的scope chain為:[0]foo.AO-->[1]global.Vo
    //建議:少定義全域性變數
    //理由:因為作用域鏈是棧的結構,全域性變數在棧底,每次訪問全域性變數都會遍歷一次棧,//這樣會影響效率

函式的scope等於自身的AO物件加上父級的scope,也可以理解為一個函式的作用域等於自身活動物件加上父級作用域.

函式執行前後的作用域鏈:

注意:作用域鏈的非自己部分在函式物件被建立(函式宣告、函式表示式)的時候建立,而不需要等到執行

思考題2:

 for (var i=1; i<=9; i++) {
     setTimeout( function timer(){
     console.log( i );
     },1000 );
 }

//==================

for (var i=1; i<=9; i++) {
    (function(){
      var j = i;
      setTimeout( function timer(){
           console.log( j );
      }, 1000 );
     })();
回到頂部

BOM物件

BOM(瀏覽器物件模型),可以對瀏覽器視窗進行訪問和操作。使用 BOM,開發者可以移動視窗、改變狀態列中的文字以及執行其他與頁面內容不直接相關的動作。

使 JavaScript 有能力與瀏覽器“對話”。

window物件

window物件
    所有瀏覽器都支援 window 物件。
    概念上講.一個html文件對應一個window物件.
    功能上講: 控制瀏覽器視窗的.
    使用上講: window物件不需要建立物件,直接使用即可.

Window 物件方法

alert()            顯示帶有一段訊息和一個確認按鈕的警告框。
confirm()          顯示帶有一段訊息以及確認按鈕和取消按鈕的對話方塊。
prompt()           顯示可提示使用者輸入的對話方塊。

open()             開啟一個新的瀏覽器視窗或查詢一個已命名的視窗。
close()            關閉瀏覽器視窗。
setInterval()      按照指定的週期(以毫秒計)來呼叫函式或計算表示式。
clearInterval()    取消由 setInterval() 設定的 timeout。
setTimeout()       在指定的毫秒數後呼叫函式或計算表示式。
clearTimeout()     取消由 setTimeout() 方法設定的 timeout。
scrollTo()         把內容滾動到指定的座標。

互動方法:

方法講解:    
        //----------alert confirm prompt----------------------------
    //alert('aaa');
    
    
    /* var result = confirm("您確定要刪除嗎?");
    alert(result); */

    //prompt 引數1 : 提示資訊.   引數2:輸入框的預設值. 返回值是使用者輸入的內容.

    // var result = prompt("請輸入一個數字!","haha");
    // alert(result);



    方法講解:    
        //open方法 開啟和一個新的視窗 並 進入指定網址.引數1 : 網址.
        //呼叫方式1
            //open("http://www.baidu.com");
        //引數1 什麼都不填 就是開啟一個新視窗.  引數2.填入新視窗的名字(一般可以不填). 引數3: 新開啟視窗的引數.
            open('','','width=200,resizable=no,height=100'); // 新開啟一個寬為200 高為100的視窗
        //close方法  將當前文件視窗關閉.
            //close();

練習:

var num = Math.round(Math.random()*100);
function acceptInput(){
//2.讓使用者輸入(prompt)    並接受 使用者輸入結果
var userNum = prompt("請輸入一個0~100之間的數字!","0");
//3.將使用者輸入的值與 隨機數進行比較
        if(isNaN(+userNum)){
            //使用者輸入的無效(重複2,3步驟)
            alert("請輸入有效數字!");
            acceptInput();
        }
        else if(userNum > num){
        //大了==> 提示使用者大了,讓使用者重新輸入(重複2,3步驟)
            alert("您輸入的大了!");
            acceptInput();
        }else if(userNum < num){
        //小了==> 提示使用者小了,讓使用者重新輸入(重複2,3步驟)
            alert("您輸入的小了!");
            acceptInput();
        }else{
        //答對了==>提示使用者答對了 , 詢問使用者是否繼續遊戲(confirm).
            var result = confirm("恭喜您!答對了,是否繼續遊戲?");
            if(result){
                //是 ==> 重複123步驟.
                num = Math.round(Math.random()*100);
                acceptInput();
            }else{
                //否==> 關閉視窗(close方法).
                close();
            }
        }
        

setInterval clearInterval

<input id="ID1" type="text" onclick="begin()">
<button onclick="end()">停止</button>

<script>


    function showTime(){
           var nowd2=new Date().toLocaleString();
           var temp=document.getElementById("ID1");
           temp.value=nowd2;

    }

    var clock;

    function begin(){

        if (clock==undefined){

             showTime();
             clock=setInterval(showTime,1000);

        }

    }

    function end(){

        clearInterval(clock);
    }

</script>

setTimeout clearTimeout

var ID = setTimeout(abc,2000); // 只調用一次對應函式.
            clearTimeout(ID);
    function abc(){
        alert('aaa');
    }

History 物件

History 物件屬性

History 物件包含使用者(在瀏覽器視窗中)訪問過的 URL。

History 物件是 window 物件的一部分,可通過 window.history 屬性對其進行訪問。

1 length 返回瀏覽器歷史列表中的 URL 數量。

History 物件方法

back()    載入 history 列表中的前一個 URL。
forward()    載入 history 列表中的下一個 URL。
go()    載入 history 列表中的某個具體頁面。
<a href="rrr.html">click</a>
<button onclick=" history.forward()">>>></button>
<button onclick="history.back()">back</button>
<button onclick="history.go()">back</button>

Location 物件

Location 物件包含有關當前 URL 的資訊。

Location 物件是 Window 物件的一個部分,可通過 window.location 屬性來訪問。

Location 物件方法

location.assign(URL)
location.reload()
location.replace(newURL)//注意與assign的區別
回到頂部

DOM物件(DHTML)

7.1 什麼是 DOM?

DOM 是 W3C(全球資訊網聯盟)的標準。DOM 定義了訪問 HTML 和 XML 文件的標準:

"W3C 文件物件模型(DOM)是中立於平臺和語言的介面,它允許程式和指令碼動態地訪問和更新文件的內容、結構和樣式。"

W3C DOM 標準被分為 3 個不同的部分:

  • 核心 DOM - 針對任何結構化文件的標準模型
  • XML DOM - 針對 XML 文件的標準模型
  • HTML DOM - 針對 HTML 文件的標準模型

  • 什麼是 XML DOM? ---->XML DOM 定義了所有 XML 元素的物件和屬性,以及訪問它們的方法。
  • 什麼是 HTML DOM?---->HTML DOM 定義了所有 HTML 元素的物件和屬性,以及訪問它們的方法。

7.2 DOM 節點

根據 W3C 的 HTML DOM 標準,HTML 文件中的所有內容都是節點(NODE):

  • 整個文件是一個文件節點(document物件)
  • 每個 HTML 元素是元素節點(element 物件)
  • HTML 元素內的文字是文字節點(text物件)
  • 每個 HTML 屬性是屬性節點(attribute物件)
  • 註釋是註釋節點(comment物件)

畫dom樹是為了展示文件中各個物件之間的關係,用於物件的導航。

節點(自身)屬性:

  • attributes - 節點(元素)的屬性節點
  • nodeType – 節點型別
  • nodeValue – 節點值
  • nodeName – 節點名稱
  • innerHTML - 節點(元素)的文字值

導航屬性:

  • parentNode- 節點(元素)的父節點 (推薦)
  • firstChild – 節點下第一個子元素
  • lastChild – 節點下最後一個子元素
  • childNodes - 節點(元素)的子節點

注意:

<div id="div1">
    <div id="div2"></div>
    <p>hello yuan</p>
</div>

<script>
    var div=document.getElementById("div2");

    console.log(div.nextSibling.nodeName);  //思考:為什麼不是P?
</script>

推薦導航屬性:

parentElement              // 父節點標籤元素

children                        // 所有子標籤
  
firstElementChild          // 第一個子標籤元素

lastElementChild           // 最後一個子標籤元素

nextElementtSibling       // 下一個兄弟標籤元素

previousElementSibling  // 上一個兄弟標籤元素

節點樹中的節點彼此擁有層級關係。

父(parent),子(child)和同胞(sibling)等術語用於描述這些關係。父節點擁有子節點。同級的子節點被稱為同胞(兄弟或姐妹)。

  • 在節點樹中,頂端節點被稱為根(root)
  • 每個節點都有父節點、除了根(它沒有父節點)
  • 一個節點可擁有任意數量的子
  • 同胞是擁有相同父節點的節點

下面的圖片展示了節點樹的一部分,以及節點之間的關係:

訪問 HTML 元素(節點),訪問 HTML 元素等同於訪問節點,我們能夠以不同的方式來訪問 HTML 元素:

頁面查詢:

  • 通過使用 getElementById() 方法
  • 通過使用 getElementsByTagName() 方法
  • 通過使用 getElementsByClassName() 方法
  • 通過使用 getElementsByName() 方法

區域性查詢:

<div id="div1">

    <div class="div2">i am div2</div>
    <div name="yuan">i am div2</div>
    <div id="div3">i am div2</div>
    <p>hello p</p>
</div>

<script>

   var div1=document.getElementById("div1");

////支援;
//   var ele= div1.getElementsByTagName("p");
//   alert(ele.length);
////支援
//   var ele2=div1.getElementsByClassName("div2");
//   alert(ele2.length);
////不支援
//   var ele3=div1.getElementById("div3");
//   alert(ele3.length);
////不支援
//   var ele4=div1.getElementsByName("yuan");
//   alert(ele4.length)

</script>

7.3 HTML DOM Event(事件)

HTML 4.0 的新特性之一是有能力使 HTML 事件觸發瀏覽器中的動作(action),比如當用戶點選某個 HTML 元素時啟動一段 JavaScript。下面是一個屬性列表,這些屬性可插入 HTML 標籤來定義事件動作。

onclick        當用戶點選某個物件時呼叫的事件控制代碼。
ondblclick     當用戶雙擊某個物件時呼叫的事件控制代碼。

onfocus        元素獲得焦點。               //練習:輸入框
onblur         元素失去焦點。               應用場景:用於表單驗證,使用者離開某個輸入框時,代表已經輸入完了,我們可以對它進行驗證.
onchange       域的內容被改變。            應用場景:通常用於表單元素,當元素內容被改變時觸發.(三級聯動)

onkeydown      某個鍵盤按鍵被按下。          應用場景: 當用戶在最後一個輸入框按下回車按鍵時,表單提交.
onkeypress     某個鍵盤按鍵被按下並鬆開。
onkeyup        某個鍵盤按鍵被鬆開。
onload         一張頁面或一幅影象完成載入。
onmousedown    滑鼠按鈕被按下。
onmousemove    滑鼠被移動。
onmouseout     滑鼠從某元素移開。
onmouseover    滑鼠移到某元素之上。
onmouseleave 滑鼠從元素離開 onselect 文字被選中。 onsubmit 確認按鈕被點選。

兩種為元素附加事件屬性的方式

<div onclick="alert(123)">點我呀</div>
<p id="abc">試一試!</p>

<script>
    var ele=document.getElementById("abc");


    ele.onclick=function(){
        alert("hi");
    };

</script>

注意:

<div id="abc" onclick="func1(this)">事件繫結方式1</div>
<div id="id123">事件繫結方式2</div>
<script>
    function func1(self){
        console.log(self.id)
    }

    //jquery下是$(self), 這種方式this引數必須填寫;

//------------------------------------------
    var ele=document.getElementById("id123").onclick=function(){
         console.log(this.id);
        //jquery下是$(this), 這種方式不需要this引數;
    }
    
</script>

onload:

onload 屬性開發中 只給 body元素加.
這個屬性的觸發 標誌著 頁面內容被載入完成.
應用場景: 當有些事情我們希望頁面載入完立刻執行,那麼可以使用該事件屬性.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <script>
//          window.onload=function(){
//               var ele=document.getElementById("ppp");
//               ele.onclick=function(){
//                alert(123)
//            };
//          };



          function fun1() {
              var ele=document.getElementById("ppp");
               ele.onclick=function(){
                alert(123)
            };
          }

    </script>
</head>
<body onload="fun1()">

<p id="ppp">hello p</p>

</body>
</html>

onsubmit:

是當表單在提交時觸發. 該屬性也只能給form元素使用.應用場景: 在表單提交前驗證使用者輸入是否正確.如果驗證失敗.在該方法中我們應該阻止表單的提交.

<form id="form">
            <input type="text"/>
            <input type="submit" value="點我!" />
</form>

<script type="text/javascript">
            //阻止表單提交方式1().
            //onsubmit 命名的事件函式,可以接受返回值. 其中返回false表示攔截表單提交.其他為放行.

            var ele=document.getElementById("form");
            ele.onsubmit=function(event) {
//                alert("驗證失敗 表單不會提交!");
//                return false;
                
            // 阻止表單提交方式2 event.preventDefault(); ==>通知瀏覽器不要執行與事件關聯的預設動作。
             alert("驗證失敗 表單不會提交!");
             event.preventDefault();

    }

Event 物件

Event 物件代表事件的狀態,比如事件在其中發生的元素、鍵盤按鍵的狀態、滑鼠的位置、滑鼠按鈕的狀態。

事件通常與函式結合使用,函式不會在事件發生前被執行!event物件在事件發生時系統已經建立好了,並且會在事件函式被呼叫時傳給事件函式.我們獲得僅僅需要接收一下即可.

比如onkeydown,我們想知道哪個鍵被按下了,需要問下event物件的屬性,這裡就時KeyCode;

思考:onclick=function(event){};這個方法是誰呼叫的?

事件傳播:

<div id="abc_1" style="border:1px solid red;width:300px;height:300px;">
        <div id="abc_2" style="border:1px solid red;width:200px;height:200px;">
        
        </div>
    </div>
    <script type="text/javascript">
    document.getElementById("abc_1").onclick=function(){
        alert('111');
    }
    document.getElementById("abc_2").onclick=function(event){
        alert('222');
        event.stopPropagation(); //阻止事件向外層div傳播.
    }
    
</script>

7.4 增刪改查演示

7.4.1 node的CURD:

增:

1 2 createElement(name)建立元素 appendChild();將元素新增

:

1 2 3 獲得要刪除的元素 獲得它的父元素 使用removeChild()方法刪除

:

第一種方式:

使用上面增和刪結合完成修改

第二中方式:

使用setAttribute();方法修改屬性

使用innerHTML屬性修改元素的內容

: 使用之前介紹的方法.

<script type="text/javascript">
//在第一個div中動態增加一個a標籤. 該a標籤點選之後跳轉到百度首頁.
    function addNode(){
        //1.獲得 第一個div
        var div = document.getElementById("div_1");
        //2.建立a標籤  createElement==>建立一個a標籤   <a></a>
        var eleA =  document.createElement("a");
        //3.為a標籤新增屬性 <a href="http://www.baidu.com"></a>
        eleA.setAttribute("href", "http://www.baidu.com");
        //4.為a標籤新增內容 <a href="http://www.baidu.com">百度</a>
        eleA.innerHTML = "百度";    
        //5.將a標籤新增到div中
        div.appendChild(eleA);
    }
    //點選後 刪除div區域2
    function deleteNode(){
        //1 獲得要刪除的div區域
            var div = document.getElementById("div_2");
        //2.獲得父親
            var parent = div.parentNode;
        //3 由父親操刀 
            parent.removeChild(div);
    }
    //點選後 替換div區域3 為一個美女
    function updateNode(){
        //1 獲得要替換的div區域3
        var div = document.getElementById("div_3");
        //2建立img標籤物件 <img />
        var img = document.createElement("img");
        //3新增屬性 <img src="001.jpg" />
        img.setAttribute("src", "001.JPG");
        //4.獲得父節點
        var parent = div.parentNode;
        //5.替換
        parent.replaceChild(img, div);
    }
    //點選後 將div區域4 克隆一份 新增到頁面底部
    
    function copyNode(){
        //1.獲取要克隆的div
        var div = document.getElementById("div_4");
        //2.克隆 引數為true 那麼克隆時克隆所有子元素. false 只克隆自己
        var div_copy = div.cloneNode(true);
        //3.獲得父親
        var parent = div.parentNode;
        //4.新增
        parent.appendChild(div_copy);
    }
    
    
</script>

7.4.2 修改 HTML DOM

  • 改變 HTML 內容

改變元素內容的最簡答的方法是使用 innerHTML ,innerText。

  • 改變 CSS 樣式
1 2 <p id="p2">Hello world!</p> document.getElementById("p2").style.color="blue";<br> .style.fontSize=48px
  • 改變 HTML 屬性

elementNode.setAttribute(name,value)

elementNode.getAttribute(name)<-------------->elementNode.value(DHTML)

  • 建立新的 HTML 元素

createElement(name)

  • 刪除已有的 HTML 元素

elementNode.removeChild(node)

  • 關於class的操作

elementNode.className

elementNode.classList.add

elementNode.classList.remove

回到頂部

8 例項練習

1 搜尋框

<input id="ID1" type="text" value="請輸入使用者名稱" onblur="Blurs()" onfocus="Focus()">


<script>

function Focus(){

    var input=document.getElementById("ID1");
    if (input.value=="請輸入使用者名稱"){
        input.value="";
    }

};

function Blurs(){

    var ele=document.getElementById("ID1");
    var val=ele.value;
    if(!val.trim()){

        ele.value="請輸入使用者名稱";
    }
}

</script>

2 模態對話方塊

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .back{
            background-color: rebeccapurple;
            height: 2000px;
        }

        .shade{
            position: fixed;
            top: 0;
            bottom: 0;
            left:0;
            right: 0;
            background-color: coral;
            opacity: 0.4;
        }

        .hide{
            display: none;
        }

        .models{
            position: fixed;
            top: 50%;
            left: 50%;
            margin-left: -100px;
            margin-top: -100px;
            height: 200px;
            width: 200px;
            background-color: gold;

        }
    </style>
</head>
<body>
<div class="back">
    <input id="ID1" type="button" value="click" onclick="action('show')">
</div>

<div class="shade hide"></div>
<div class="models hide">
    <input id="ID2" type="button" value="cancel" onclick="action('hide')">
</div>

<script>

    function action(act){
        var ele=document.getElementsByClassName("shade")[0];
        var ele2=document.getElementsByClassName("models")[0];
        if(act=="show"){
              ele.classList.remove("hide");
              ele2.classList.remove("hide");
        }else {
              ele.classList.add("hide");
              ele2.classList.add("hide");
        }

    }
</script>
</body>
</html>

3 全選反選取消

 <button onclick="select('all');">全選</button>
     <button onclick="select('cancel');">取消</button>
     <button onclick="select('reverse');">反選</button>

     <table border="1" id="Table">
         <tr>
             <td><input type="checkbox"></td>
             <td>111</td>
         </tr>
         <tr>
             <td><input type="checkbox"></td>
             <td>222</td>
         </tr>
         <tr>
             <td><input type="checkbox"></td>
             <td>333</td>
         </tr>
         <tr>
             <td><input type="checkbox"></td>
             <td>444</td>
         </tr>
     </table>


<script>
    function select(choice){
        var ele=document.getElementById("Table");

        var inputs=ele.getElementsByTagName("input");
        for (var i=0;i<inputs.length;i=i+1){

                   var ele2=inputs[i];
            if (choice=="all"){
                ele2.checked=true;

            }else if(choice=="cancel"){
                ele2.checked=false;
            }
            else {

                if (ele2.checked){
                    ele2.checked=false;
                }else {
                    ele2.checked=true;
                }
            }

            }
    }
</script>

4 兩級聯動

<select id="province">
    <option>請選擇省:</option>
</select>

<select id="city">
    <option>請選擇市:</option>
</select>


<script>
    data={"河北省":["廊坊","邯鄲"],"北京":["朝陽區","海淀區"]};


      var p=document.getElementById("province");
      var c=document.getElementById("city");
    
    for(var i in data){
        var option_pro=document.createElement("option");

        option_pro.innerHTML=i;

        p.appendChild(option_pro);
    }
     p.onchange=function(){

            pro=(this.options[this.selectedIndex]).innerHTML;
            citys=data[pro];

         c.options.length=0;

         for (var i in citys){
             var option_city=document.createElement("option");
             option_city.innerHTML=citys[i];
             c.appendChild(option_city);
         }

        }
</script>

5 select左右移

<div id="box1">
    <select multiple="multiple" size="10" id="left">
        <option>book</option>
        <option>book2</option>
        <option>book3</option>
        <option>book4</option>
        <option>book5</option>
        <option>book6</option>
    </select>
</div>


<div id="choice">
    <input class="add"     type="button" value="--->" onclick="add()"><br>
    <input class="remove"  type="button" value="<---" onclick="remove();"><br>
    <input class="add-all" type="button" value="====>" onclick="ADDall()"><br>
    <input class="remove-all" type="button" value="<===" onclick="remall()">
</div>


<div>
    <select multiple="multiple" size="10" id="right">
        <option>book9</option>
    </select>
</div>

<script>

     function add(){
         var right=document.getElementById("right");
         var options=document.getElementById("left").getElementsByTagName("option");

         for (var i=0; i<options.length;i++){

             var option=options[i];

             if(option.selected==true){
                   right.appendChild(option);
                 i--;
             }

         }

     }

    function ADDall(){
         var right=document.getElementById("right");
         var options=document.getElementById("left").getElementsByTagName("option");
         for (var i=0; i<options.length;i++){
             var option=options[i];
             right.appendChild(option);
             i--;

         }

     }

</script>