1. 程式人生 > >一個demo學會js

一個demo學會js

全棧工程師開發手冊 (作者:欒鵬)

這篇demo較長,包含了js基本的內容,若不是出於校驗自己js能力的朋友,建議按照上面的連結分章節學習。本demo包含了js的陣列、物件、物件屬性、字串、正則表示式、函式、引數、容器、演算法、BOM、DOM、事件、表單、cancas繪圖、json、ajax、comet、離線應用、客戶端儲存等方面的知識,可以全面檢驗你的js學習效果。

此demo除了必須的連結檔案外,主要包括檔案:index.html和index.js、index.css、index1.js、index2.js、index3.js、index4.js、index5.js檔案

index.html檔案為一個簡單的演示頁面。包括js程式碼的列印輸出和js與css的嵌入程式碼。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jsdemo</title>
    <meta name="viewport" content="initial-scale=1.0,user-scalable=no">  <!--適應移動螢幕-->

    <link rel="stylesheet" href="index.css" />
    <style type="text/css"
>
.hintclass{ display: inline; float: left; left: 30%; height: 35%; width: 70%;color: white;overflow: auto} /*設定樣式類樣式*/ #hint1{display:inline;float:left;height: 25%;width: 70%;left:30%;background-color: aqua;color: white} /*設定指定id樣式*/ /*background-image:url('chaoxian.jpg');background-size: cover*/
</style> <style type="text/css"> body div{background-color: green} /*設定元素類別樣式,多重限定,使用空格連線,樣式的計算以最新的設定為主*/ div input{width: 200px;height: 40px} </style> </head> <!--當遇到<body>開始呈現內容--> <body> <div style="width: 100%;height: 900px;" id="hintdiv"> <label style="display:inline;float:left;height: 100%;width: 30%;background-color: beige" id="hint" name="tity"></label> <label id="hint1" name="tity"></label> <!--name是元素被包含在集合中時的key--> <label class="hintclass" style="background-color: #654321;" id="hint2" name="tity" title="label text" lang="en" dir="ltr" myatt="age" data-myname="luanpeng"></label> <!--id唯一標識,title元素附件說明,lang語言,dir語言方向,class特性,myatt自定義屬性,data-myname自定義資料屬性--> </div> <div style="background-color: #999999;width: 100%;height: 600px" id="hintdiv1"> <!-- onclick="alert('div接收到事件')"--> <input type="button" id="input1" value="點選1" onclick="alert('點選了')" > <!--可以在事件中直接輸入函式表示式--> <input type="text" id="input2" value="輸入內容" name="mytext" oninput="printf(event.type.toString()+this.value)" ><!--事件中自動具有event時間物件和this表示的元素本身,名稱name的值就代表了當前元素物件的引用--> <br> <!--換行--> <textarea rows="2" cols="25">textare初始化值</textarea> <!--rows行數,cols列數--> <form accept-charset="GBK" action="" method="post" name="hello" id="myform" novalidate><!--novalidate表單不用驗證--> <input name="text1" type="text" size="15" maxlength="20" placeholder="提示字" value="input初始化值" id="text1" autofocus required> <!--autofocus自動聚焦,pattern="\d+"輸入模式,placeholder提示字,size顯示的字元數目,maxlength能存放的字元數目,required必填屬性--> <input type="email" value="[email protected]"> <input type="url" value="http://www.baidu.com"> <input type="number" min="0" max="100" step="5" value="2"> <!--min最小值,max最大值,step步進--> <input type="range"> <input type="file" id="myfile"> <br> <input type="detetime"><input type="date"> <input type="month"><input type="week"><input type="time"> <br> <select id="myselect" name="myselect"> <option id="option1" value="myoption1">第1個選項</option> <option id="option2" value="myoption2">第2個選項</option> </select> <br> <input type="button" value="點選2" onclick="printf(mytext.value.toString())" /> <!--在form元素中通過name值可以訪問其他元素--> <input type="submit" value="提交"> </form> <canvas style="width: 500px;background-color: beige" id = "mycanvas"> </canvas> </div> <!--script指令碼放在body後面為了避免瀏覽器空白,</script>不要省略,否則容容易出錯--> <script src="index.js"></script> <!--引入外部檔案或網路檔案,src表示要包含的檔案,type表示指令碼語言內容型別,預設為text/javascript,charset程式碼所屬字符集,async表示立即下載指令碼,defer指令碼可以延遲到文件完全被解析後再解析--> <!--html檔案中內嵌javascript,到檔案遇到下一個</script>認為指令碼結束,無論他出現在什麼位置,儘量使用外部js檔案實現--> <script type="text/javascript">//相當於一個外部js檔案。一個h5檔案引用的所有js檔案會自動合併成一個js檔案,實現變數函式共享。但每個檔案又有獨立的活動空間,同名函式和變數會先在自己空間查詢,再向前查詢 hint = document.getElementById("hint"); //定義變數,供js函式呼叫。 hint1 = document.getElementById("hint1"); //定義變數,供js函式呼叫。 hint2 = document.getElementById("hint2"); //定義變數,供js函式呼叫。 hintdiv = document.getElementById("hintdiv"); //定義變數 hintdiv1 = document.getElementById("hintdiv1");//定義變數 printf("===========欒鵬除錯==========="); //呼叫在js檔案中定義的函式,先再當前js檔案查詢,再在之前的js檔案查詢,再向之後的js檔案查詢 </script> <script src="index1.js"></script> <script src="index2.js"></script> <script src="index5.js"></script> </body> </html>

index.css檔案為一個簡單的樣式頁面,為了學習js操作外部樣式檔案而存在的

body div{background-color: green}                                                                   /*設定元素類別樣式,多重限定,使用空格連線*/
.hintclass{  display: inline;  float: left;  left: 30%;  height: 35%;  width: 70%;color: white}   /*設定樣式類樣式*/
#hint1{display:inline;float:left;height: 20%;width: 70%;left:30%;background-color: aqua}            /*設定指定id樣式*/

index.js檔案包含js的陣列、物件、字串、正則表示式、函式、容器的知識

var konggestr="&nbsp; &nbsp; &nbsp; &nbsp; ";   //空格
printf(konggestr+"===========陣列===========")
//變數是鬆散型的,可以指向任意型別的資料
var name = "student",age=12;   //underfined、null、boolean、string、number為基本數值型別。逗號一併定義初始化多個變數。基本包裝型別String、Boolean、Number通過valueOf()可以獲取基本數值型別,可以實現自動裝箱和拆箱操作。
var names=[];//定義陣列並初始化為空
names = ["小明","小紅","小剛"];  //賦值,可以在定義時賦值
names=new Array(names.length);   //陣列基類為Array,屬性length為陣列長度
names = new Array('小明','小紅','小剛');   //字串不區分單雙引號,只要配對使用就行
names[4]="小胡";   //通過設定,直接添加了兩項null和“小胡”
printf(names.join(","));   //使用間隔字串連線陣列
names.unshift("小李","小蘭");   //首部新增
names.push("小李","小蘭");   //末尾新增
var item = names.pop();//刪除獲取最後一項
item=names.shift();//刪除獲取第一項
names.reverse();  //陣列取反
printf(names);
names = names.slice(-4,6);  //讀取陣列段,不修改源陣列,複數表示從右向左數,-1表示末尾第一個元素,0表示首部第一個元素。只有一個引數時表示直到末尾。讀取包含第一個引數不包含第二個引數
printf(names);
names.splice(2,1,"小季","小明");  //刪除新增資料,修改源陣列,刪除新增引數第一個引數表示開始刪除的位(包含),第二個引數表示要刪除的位數目,後面引數表示在刪除位置處新增元素
printf(names);
names=names.concat("小王",["小明","小黑"]); //不修改源陣列,所以要賦值
names.sort();  //陣列排序sort(compare),引數可為排序函式,空元素將排到最後
printf(names);
names.indexOf("小明");  //查詢匹配元素的位置,沒有返回-1,lastindexof表示匹配的最後位置。
var boolresult = names.every(function(item,index,array){   //對陣列中元素每一項進行布林運算,返回false和true。every函式,全部元素返回true時返回true。some函式某一元素返回true時返回true
    return (index>2);
});
var nameresult = names.filter(function(item,index,array){   //返回陣列,filter函式獲取滿足條件的項,map獲取每一項計算值的集合,不改變原陣列,forEach函式等價於for語句,對每項處理
    return (index>2);
});
printf(nameresult);
nameresult = names.reduce(function(prev,cur,index,array){   //reduce從前向後迭代,reduceRight從後向前迭代。
    return prev+"+"+cur;   //迭代從第二項開始,prev初始值為第一項,cur初始值為第二項。計算值自動傳給下一函式的prev,返回最後一次迭代產生的值
});
printf(nameresult);
function compare(student1,student2){   //比較函式,返回-1,0,1
    //return student1.age<student2.age?-1:(student1.age==student2.age?0:1);   //-1表示前物件小,1表示後物件小,0表示相等
    return student2.age-student1.age;  //正數自動轉化為1,負數轉化為-1
}
ages=[];
for(var i=0;i<7;i++){   //js沒有塊級作用域,for  if塊內定義的變數,在塊外可以訪問,函式內定義的區域性變數外部不可以訪問。可以使用let i定義臨時作用域,定義的變數和對外部變數的修改均不保留,
  ages.push(Math.floor(Math.random()*10+1));  //floor向下取整,random()生成0-1之間的隨機數
}
printf(i);
printf(Math.max.apply(Math,ages));  //max取最大值,min取最小值。還有很多數學運算



printf("===========物件===========")
var student1 = new Object();   //定義物件引用,或者var student1 = {},new Object()。所有的包裝類都派生於Object。Object基類包含hasOwnProperty、isPrototypeOf、propertyIsEnumerable、toLocaleString、toString、valueOf方法
student1.name = "student1";   //直接設定同時新增物件屬性
student1["age"]=12;  //直接設定同時新增物件屬性
student1.getname = function(){   //設定新增物件方法。函式表示式,只有在執行到本行才解析
   return this.name;  //this表示作用物件,這裡為student1
};
//var {name:personname, age:personage} = student1;  //解構賦值,對應項使用副本賦值,如[value1,value2]=[value2,value1];可實現兩個基本資料交換
printf(JSON.stringify(student1));   //JSON.stringify把物件轉化為JSON字串表示

student1 = {
    name:"student1",
    _age:12,  //前面有下滑線是一種常用的標記,用於表示只能通過物件方法訪問的屬性,只是對開發者的一種標記習慣,並不是真的私有變數
    getname:function(){
        return this.name;
    }
};
Object.defineProperty(student1,"name1",{  //可以用於定義新資料屬性,也可以修改原有資料屬性。也可以不使用defineProperty可以直接定義資料屬性。也可以使用defineProperties同時定義多個數據或訪問器屬性
    writable:true,  //物件屬性的資料屬性,是否可修改
    enumerable:true,//物件屬性的資料屬性,通過for-in遍歷到
    configurable:true,  //物件屬性的資料屬性,能否通過delete刪除屬性,configurable屬性在定義為false以後,就不能再被設定
    value:"sst"  //物件屬性的值屬性,預設為underfined
});
Object.defineProperty(student1,"age",{   //訪問器屬性,不能直接定義,必須通過defineProperty定義,不包含資料值,設定時呼叫set函式,讀取時呼叫get函式。訪問器屬性名稱不要和資料屬性名稱相同
     get:function(){return this._age},
    set:function(newvalue){this._age=newvalue;this.name="xxt";}
});
student1.age=22;   //age不是資料屬性,而是訪問屬性。這裡是呼叫了set函式,
Object.preventExtensions(student1);  //設定物件不可被擴充套件,以後再新增屬性都是underfined,防止被篡改
Object.seal(student1);  //密封物件,物件不能新增刪除屬性。
Object.freeze(student1);  //凍結物件,屬性不可修改。只能通過set訪問器修改
printf(JSON.stringify(student1));   //將JSON格式轉化為字串。JSON格式即KEY-VALUE格式
for(var myproperty in student1){   //for in遍歷物件屬性
    console.log(myproperty,":",student1[myproperty]);
}




function Student(name,age){   //自定義函式,建構函式,等同於java中的自定義類。所有的型別派生於Object
    var sex="男";   //函式內部為私有屬性
    this.name=name;  //通過this建立的是可以被例項物件訪問的
    this.age=age;
    this.getName=function(){
        return this.name;  //函式內部this表示此函式引用的擁有者,不是傳入引數。當作為全域性函式時,this表示window
    };
    this.setName= function(name){  //函式不關心傳入或者定義的引數數量和型別,因此所有函式沒有過載
        if(typeof name=="string")   //基本資料型別,做型別檢驗,避免參數傳遞錯誤
            this.name = name;      //沒有指定返回值,實際返回的是undefined
    };
    this.getAge =function (){
        if(this.age.toFixed(2)<<2)  //轉化為false的值:"",0,NaN,null,underfined。其他轉化為true,型別首字母大寫,變數首字母小寫,<<按位移動,<<<無符號按位移動,toFixed(2)表示保留2位小數
            return -~this.age;  //~按位取非,&按位取與,|按位取或 ^按位取異或,一元減號,表示取負
        return this.age;  //保證所有路徑都有返回值,雖然不加也不會出錯,因為有預設返回值undefined
    };
    this.setAge= function(age){  //函式引數總是按值傳遞,無論基本型別還是引用型別,引用型別傳遞引用的值,不傳遞指向物件的值
        if(age instanceof Number){  //包裝型別,做型別檢驗,避免參數傳遞錯誤
            this.age = parseInt(age.toString(16),16);//parseInt將字串化為整數,支援識別多進位制和轉化為多進位制,toString()轉化為字串,支援多進位制轉化
        }
        //typeof判斷基本型別,underfined宣告未定義(underfined型別只有一個值),boolean布林型,string字串,number數值,object物件或null(null類也只有一個值),function函式
        //instanceof判斷包裝型別,基本型別物件的包裝型別為Underfined,Boolean,String,Number,Object,
        typestr = typeof("getAge");  //省略var的變數為全域性變數
    }
}
student1=new Student("小明",12);  //new是建立了一個新物件,建構函式將屬性和方法繫結到這個新物件上
Student("小紅",13);  //作為全域性函式。通過建構函式將屬性繫結到window上
var student2 = new Object();
Student.call(student2,"小剛",14);//call和apply通過建構函式,將屬性繫結到以存在物件student2上
if(student2 instanceof Student)  //instanceof判斷變數是否是某個型別或其派生型別例項的,student1是Student類,同時也是Object
     printf(student2.name);


//js的繼承有多重方式。每種方式的記憶體操作都是不同。下面展示其中一種。
// js的型別繼承原理和java、c#相同。派生類繼承基類時,會例項化(淺複製)一個基類物件和保留引用在派生類空間。派生類內的例項的基類和派生類自定義的函式分別操控各自的屬性。在函式和屬性操作中時,會自動先派生後基類的順序查詢,不用手動查詢
//關於例項化:只複製且全部複製在建構函式中開闢了記憶體的變數,包括引用變數。派生類例項化時基類物件進行淺複製。
function Monitor(){   //自定義函式,相當於自定義一個類,類名Monitor。在檔案中多稱為建構函式,相當於c++和java中的自定義類。每個函式類,都有基類Object
    this.task=["學習"];
}
Monitor.prototype.data = "原型資料";  //prototype獲取派生類的基類物件引用,通過基類物件引用直接為基類新增屬性。系統會為派生類提供預設原型,也可以通過繼承自定義原型
person1 = new Monitor();//通過函式類例項化物件
person2 = new Monitor();  //例項化物件
Object.getPrototypeOf(person1).data="原型資料1";  //通過例項修改原型。Object.getPrototypeOf()獲取物件原型。例項物件包含對原型的引用,但需要使用getPrototypeOf函式獲取
person1.data="派生資料";  //修改派生類屬性,這樣當查詢data資料會先自動搜尋派生類,再自動搜素基類。

printf(person1.hasOwnProperty("data")); //是否擁有指定屬性(不算基類屬性)。true因為自定義了該屬性
printf(person1.data);//讀取自定義屬性

var keys = Object.keys(Monitor.prototype);  //獲取物件所擁有(不包括繼承的)的可列舉例項,Monitor是類,Monitor.prototype是基類例項。如果換成person1,則只能獲取派生類的自定義屬性。getOwnPropertyNames可獲取物件擁有的所有屬性
printf(keys);
delete person1.data;//刪除派生類自定義的屬性
printf(person1.hasOwnProperty("data"));     //是否擁有指定屬性。false,因為該屬性在派生類中被刪除了,只有基類中存在,雖然可以訪問,但是是繼承過來的,不是自己擁有的
printf("data" in person1);     //是否包含指定屬性。true包含,只是不擁有
printf(person1.data);//基類屬性
Monitor.prototype.sex=["男"];  //通過派生類向基類新增陣列引用變數
person1.sex.push("女");  //在例項物件中保留了基類的引用和淺複製了基類物件。這裡的sex是經過了一次從派生類到基類的向上查詢。
printf("基類中的引用:"+person2.sex);  //例項物件連帶更新。所以建構函式用於指定專屬屬性,原型用於存放共享屬性
person1.task.push("工作");  //修改建構函式中引用指向的物件
printf("派生類中的引用:"+person2.task);  //例項物件不連帶更新建構函式中的資料。因為例項化時會深複製建構函式中的所有資料,在例項化時為每個物件都建立

Monitor.prototype=new Student("組長",12);  //繼承,派生類Person設定基類為Student。在繼承中會為淺複製一個基類例項放在派生類空間中,同時將引用儲存為prototype,放在派生類Person中


//student1=null;   //通過設定引用的值為空,切斷引用於物件之間的關聯,便於垃圾回收器收回記憶體
//constructor建構函式
//isprototypeof(object)   檢測傳入物件是否是當前物件的原型




printf("===========字串、正則表示式===========");
name = " Muaneng Tuanpeng ".trim().toLowerCase().replace("eng","ing");  //trim()刪除字串前後空格。toLowerCase轉化為小寫。replace替換第一個eng,
name1 = name.substring(name.indexOf("t",3),name.lastIndexOf("g",0));//slice、substring引數為首尾下標,substr為起點下標和長度。都不改變源字串。indexOf和lastindexOf查詢子字串的位置,第二個引數表示從哪個字元開始向對面搜尋
name1 = name.substr(-4);//傳入負值時,slice將負值加上字串長度,substr將第一個負值加上字串長度,第二個負值轉為0,substring將負值都轉為0
name1="muaneng tuanpeng".replace(/eng/g,"ing").split(" ",2)[0];   //replace接收正則表示式,/g替換全部,split分割字串,並限定返回的陣列個數。[0]讀取返回陣列的第一個元素。
//正則表示式 = /pattern/flags    其中flags中g表示匹配全部,i表示不區分大小寫,m表示匹配多行
//pattern包含 ([{\^$|)?*+.]}元字元,若匹配的字串中包含元字元,使用\轉義。     .表示任一字元,()表示捕捉字元
var patter1 = /(.)u/gi;   //正則表示式,標誌沒有可為空,也可以使用var patter1 = new RegExp("pattern","flags");使用new是建立物件
if(patter1.test(name)){   //test查詢符合要求的子串是否存在,返回true
    printf(RegExp.input);  //原始字串
    printf(RegExp.leftContext);//捕捉到的位置的左邊字串
    printf(RegExp.rightContext);//捕捉到的位置的右邊字串
    printf(RegExp.lastMatch);//返回最近一次與整個正則表示式匹配的字串 mu
    printf(RegExp.lastParen);  //返回最近一次捕捉的字元
    printf(patter1.global);//返回正則是否包含全域性標誌g
}
var matches = patter1.exec(name);  //查詢符合要求的子串。matches.index表示查詢到的起始下標,matches.input表示輸入字串。patter1.lastIndex表示查詢到的結束下標,matches[0]表示查詢到的第一個匹配項,若匹配項為全域性模式,則每次呼叫返回下一個匹配項。
printf(matches.index);printf(patter1.lastIndex);printf(matches[0]);
String.prototype.startwith = function(text){  //設定字串引用的原型,為String、Object、Array等新增方法
    return this.indexOf(text)==0;
};
printf(name.startwith("mu"));





printf("===========函式===========");
//自定義函式,函式宣告,會優先載入。呼叫函式時會先在本機活動物件中查詢,即當前js檔案中查詢,如果沒有才會向上查詢,所以在兩個js檔案中定義相同函式名,js檔案內呼叫各自的函式,其他檔案中呼叫最後宣告的函式
function printf(str){
    //var hint =  document.getElementById("hint");  //根據id獲取元素
    hint.innerText += str.toString()+"\n";  //設定label顯示的文字,也可以自動呼叫其他js檔案中的hint變數。hint會先在當前檔案中查詢,然後向之前引用的js檔案查詢,再向之後引用的js檔案查詢
}

function callfunction(myfunction,myargument){    //向函式傳輸函式引用
    return myfunction(myargument);  //呼叫回撥函式
}
callfunction(printf,new Date().toDateString());//Date無引數,表示獲取當前時間。toDateString()顯示星期年月日,toTimeString顯示時分秒,toLocaleDateString以特定地區的格式顯示星期年月日。還可以分別獲取時間的各種引數。

function getproperty(propertyname){   //
    printf("外層函式");
    return function (object1){   //內部函式,返回函式引用,一個函式可以訪問另一個函式的變數,叫做閉包。函式的this和arguments變數只搜尋到活動物件中(活動上下文),不會一直向外層搜尋
        printf("內層函式");
        var getnamefun = getproperty("name");   //執行外部函式,getnamefun是一個函式引用變數
        printf(getnamefun.length);  //函式希望的引數個數
        return object1[propertyname];   //內部函式返回值,內部函式可以讀取外部函式的變數,包括外層函式的arguments物件
    }
}
var getnamefun = getproperty("name");//獲取內部函式引用。外層函式的作用域鏈沒有銷燬,因為有內部函式的引用存在。有引用指向物件,所以物件不會被銷燬,這也是垃圾回收的機制
printf(getnamefun(student1));   //執行內部函式

//函式引數
function printname() {   //定義引數和傳入引數可以不一致,所以函式沒有過載,為了使用明確,最好設定成一致模式。
    var name="內部變數"; //函式內定義變數為私有變數
    //arguments.callee.caller.toString();  //arguments.callee.caller、getname.caller表示呼叫當前函式的函式的引用
    if(arguments.length>0 && arguments[0]=="曉明")   //函式內部arguments表示引數陣列
        printf(this.name);
        //arguments.callee("小明");  //函式內部arguments.callee表示arguments的擁有者函式的引用,也就是當前函式的引用。實現遞迴呼叫
}
printname("曉明");
printname.apply(this,["曉明"]);   //函式相當於一個類,函式名相當於類的一個引用,函式類擁有引數apply,傳入呼叫者和引數陣列。全域性this相當於window
printname.call(student1,"曉明");  //call屬性傳入呼叫者和逐個引數。是將函式繫結到物件上,然後在通過物件呼叫此函式。
printname.bind(student1)("曉明");  //printname.bind(student1)返回函式繫結到物件上的函式引用,通過引用()呼叫此函式


//內建物件 Object,Array,String。。。Global(其他零散函式的合集),Math
var url = "http://www.baidu.com";
printf(encodeURI(url));  //網址編碼,對應decodeURL驛碼,
var diftime = new Date()-new Date(Date.UTC(2005,4,5,17,55,55));   //UTC引數,年月日,小時分鐘秒毫秒,其中月和小時從0開始,年月引數必須有。Date沒有引數表示當前時間,時間相減獲取時間相差時間毫秒數
eval("printf(diftime)");   //eval翻譯執行js程式碼字串



//===========================容器======================================
var map = new Map();  //對映,不重複的鍵,以鍵值對的形式存在
map.set("name","mapluanpeng");  //新增設定對映
if(map.has("name"))  //判斷對映是否存在
    printf(map.get("name"));  //讀取對映
map.delete("name");  //刪除對映

var set = new Set(); //集合。不重複的元素集合,不存在鍵值對
set.add("name"); //新增集合
if(set.has("name")){  //檢測集合是否存在指定元素
    set.delete("name");  //刪除集合元素
    printf("刪除集合元素name");
}

index1.js檔案包含BOM的知識

function printf(str){
    var hint =  document.getElementById("hint1");  //根據id獲取元素
    hint.innerText += str.toString()+"\n";  //設定label顯示的文字,也可以自動呼叫其他js檔案中的hint變數
}

//=======================================BOM========================================
printf("===========BOM(window視窗資訊)===========");
//window物件,視窗資訊
var windowinfo = {};
windowinfo["screenLeft"]=(window.screenLeft);
windowinfo["screenTop"]=(window.screenTop);  //瀏覽器位置
windowinfo["innerWidth"]=(window.innerWidth);
windowinfo["innerHeight"]=(window.innerHeight);//瀏覽器大小
windowinfo["clientWidth"]=(document.documentElement.clientWidth);
windowinfo["clientHeight"]=(document.documentElement.clientHeight);//瀏覽器大小
windowinfo["clientWidth"]=(document.body.clientWidth);
windowinfo["clientHeight"]=(document.body.clientHeight);//頁面大小
printf(JSON.stringify(windowinfo));
window.moveTo(20,20);  //moveTo移動到絕對位置,moveBy移動相對距離。好像並沒有效果
window.resizeTo(200,200); //resizeTo調整大小到指定大小,resizeBy縮放視窗大小
var wroxwin=window.open("http://www.baidu.com","_blank","height=400,width=400");  //開啟視窗,引數地址、視窗名或框架名、視窗屬性。返回視窗引用,進而可控制視窗。window就是一個視窗引用。不過有可能彈窗會被遮蔽

//彈框和超時設定
if(wroxwin==null)
    alert("彈出視窗被遮蔽");  //彈出系統提示框,只有字串和確定按鈕
else
    var timeoutid = setTimeout(function(){  //setTimeout設定超時呼叫。js是單執行緒語言。但可以設定超時呼叫和間歇呼叫
        wroxwin.close();  //關閉指定視窗
    },500);  //設定延遲時間為500ms,這裡相當於建立了新的執行緒,後面程式不會等待此函式執行完畢。若當前視窗關閉這此執行緒不會再執行
i=0;

/*result = prompt("設定迴圈執行的毫秒數?","2000"); //prompt帶有輸入框的系統彈出框,第一個引數為提示字串,第二個引數為預設輸入內容。返回使用者輸入內容。
var intervalid=setInterval(function(){ //setInterval間歇執行,設定間隔時間
    printf("迴圈執行"+(i++).toString()+"    "+new Date().toTimeString());
    if(i==4) {
        if(!confirm("是否繼續迴圈"))  //confirm帶有確定和取消按鈕的系統對話方塊。點選ok返回true,點選關閉或取消返回false
            clearInterval(intervalid);  //取消超時呼叫或間歇呼叫
    }
},parseInt(result));*/

printf("===========BOM(location網址資訊)===========");
var locationinfo = {};
locationinfo["href"]=(location.href);  //開啟新網址。location包含關於網址的資訊和操作。可以讀取也可以設定,設定及代表操作。
locationinfo["hostname"]=(location.hostname);//hostname主機名
locationinfo["hash"]=(location.hash);//網址尾部的#後字串
locationinfo["pathname"]=(location.pathname);//路徑
locationinfo["port"]=(location.port);//埠
locationinfo["search"]=(location.search);//網址尾部?後字串
printf(JSON.stringify(locationinfo));
printf("===========BOM(navigator瀏覽器資訊)===========");
printf("瀏覽器名稱:"+navigator.appName); //瀏覽器名稱,很多屬性,自己查詢
printf("瀏覽器版本:"+navigator.appVersion); //瀏覽器版本


printf("===========BOM(history上網記錄)===========");
try{   //try嘗試執行
    //history.go(-1);//後退或前進n頁,
    //history.go("525heart");//跳轉到最近的 網址包含指定字元號的網址上
    //history.back();  //後退一頁
    //history.forward();  //前進一頁
    throw "hello world";  //程式碼遇到異常會報錯,停止執行,除非try,catch捕獲異常
}catch (err){  //catch錯誤提示
    //if(err instanceof TypeError)     //異常型別,基型別Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError
    printf("異常:"+err);
    console.log("log將訊息記錄到控制檯");  //將訊息列印到控制檯,在工具開發者選項中。Console選單下。error列印錯誤訊息,info列印資訊訊息,log列印一般訊息,warn列印警告訊息
}
finally {
    printf("始終要執行的語句");
}

index2.js檔案包含DOM的知識,包括DOM文件資訊,DOM元素節點資訊、DOM元素節點操作、DOM擴充套件、DOM2\DOM3、遍歷

function printf(str){
    //var hint =  document.getElementById("hint2");  //根據id獲取元素,document是一個檔案節點,因此document可以替換成某個節點,
    //var hint =  documen