JavaScript 是一種面向對象的動態語言,它的語法來源於 Java 和 C,所以這兩種語言的許多語法特性同樣適
用於 JavaScript。需要注意的一個主要區別是 JavaScript 不支持類,類這一概念在 JavaScript 通過對象原型
(object prototype)得到延續(有關 ES6 類的內容參考這里Classes)。另一個主要區別是 JavaScript 中的
函數也是對象,JavaScript 允許函數在包含可執行代碼的同時,能像其他對象一樣被傳遞。
1,script標簽可放在head或body中,因為瀏覽器解釋html文件是按先后順序的,若是記錄用來初始化頁面的
css代碼的js應放在head中,若是通過時間調用執行的function函數則對位置沒有要求
js代碼最好放在頁面的底部,引用外部script文件格式:<script src="script.js"></script>
2,script標簽中可不寫type=text/javascript,
3,document.write("");直接在網頁寫內容,//要寫雙引號,輸出的是雙引號內的內容
三種方式:
第一種:輸出內容用“”括起,直接輸出""號內的內容
第二種:通過變量,輸出內容
第三種:輸出多項內容,內容之間用+號連接。
<script type="text/javascript">
var mystr="hello";
document.write(mystr+"I love JavaScript"); //多項內容之間用+號連接
</script>
第四種:輸出HTML標簽,並起作用,標簽使用“”括起來。
<script type="text/javascript">
var mystr="hello";
document.write(mystr+"<br>");//輸出hello后,輸出一個換行符
document.write("JavaScript");
</script>
4,document.getElementById("id名");通過指定的id屬性來操作html元素
例如:
<body>
<p id="con">JavaScript</p>
<script type="text/javascript">
var mychar= document.getElementById("con") ;
document.write("結果:"+mychar); //輸出獲取的P標簽。
</script>
</body>
5,單行注釋://,多行注釋用/**/
6,定義變量規則:
變量名可以任意取名,但要遵循命名規則:
1.變量必須使用字母、下划線(_)或者美元符($)開始。
2.然后可以使用任意多個英文字母、數字、下划線(_)或者美元符($)組成。
3.不能使用JavaScript關鍵詞與JavaScript保留字
變量要先聲明再賦值:
var mychar="hello";
變量可重復賦值:
var mychar;
mychar="javascript";
mychar="hello";
7,form表單有時用到提交事件后有跳轉,或是一個窗口或是一個頁面都用form表單來封裝
<form action="" method="get/post"></form>//不用跳轉頁面時action和method可省略
8,警告(alert 消息對話框):有一個確定按鈕
alert(字符串或變量);
<script type="text/javascript">
var mynum = 30;
alert("hello!");
alert(mynum);
</script>
結果按順序彈出消息框
9,確認(confirm 消息對話框)
confirm 消息對話框通常用於允許用戶做選擇的動作,如:“你對嗎?”等。彈出對話框(包括一個確定按鈕和
一個取消按鈕)。
語法:
confirm(str);
參數說明:
str:在消息對話框中要顯示的文本
返回值: Boolean值
返回值:
當用戶點擊"確定"按鈕時,返回true
當用戶點擊"取消"按鈕時,返回false
注: 通過返回值可以判斷用戶點擊了什么按鈕
看下面的代碼:
<script type="text/javascript">
var mymessage=confirm("你喜歡JavaScript嗎?");
if(mymessage==true)
{ document.write("很好,加油!"); }
else
{ document.write("JS功能強大,要學習噢!"); }
</script>
10,提問(prompt 消息對話框)
prompt彈出消息對話框,通常用於詢問一些需要與用戶交互的信息。彈出消息對話框(包含一個確定按鈕、取
消按鈕與一個文本輸入框)。
語法:
prompt(str1, str2);
參數說明:
str1: 要顯示在消息對話框中的文本,不可修改
str2:文本框中的內容,可以修改
返回值:
1. 點擊確定按鈕,文本框中的內容將作為函數返回值
2. 點擊取消按鈕,將返回null
看看下面代碼:
var myname=prompt("請輸入你的姓名:");
if(myname!=null)
{ alert("你好"+myname); }
else
{ alert("你好 my friend."); }
11,打開新窗口(window.open)
open() 方法可以查找一個已經存在或者新建的瀏覽器窗口。
語法:
window.open([URL], [窗口名稱], [參數字符串])
參數說明:
URL:可選參數,在窗口中要顯示網頁的網址或路徑。如果省略這個參數,或者它的值是空字符串,那么窗口
就不顯示任何文檔。
窗口名稱:可選參數,被打開窗口的名稱。
1.該名稱由字母、數字和下划線字符組成。
2."_top"、"_blank"、"_self"具有特殊意義的名稱。
_blank:在新窗口顯示目標網頁
_self:在當前窗口顯示目標網頁
_top:框架網頁中在上部窗口中顯示目標網頁
3.相同 name 的窗口只能創建一個,要想創建多個窗口則 name 不能相同。
4.name 不能包含有空格。
參數字符串:可選參數,設置窗口參數,各參數用逗號隔開。
參數表:
top :窗口頂部離開屏幕頂部的像素數 ,值:數字
left:窗口左部離開屏幕左端的像素數 ,值:數字
width:窗口的寬度 ,值:數字
height:窗口的高度,值:數字
menubar:有沒有菜單,值:yes,no 或者1,0
toolbar:有沒有工具欄,,值:yes,no 或者1,0
scrollbars(兩個滾動條,所以是復數):有沒有滾動條,,值:yes,no 或者1,0
status:有么有狀態欄,值:yes,no 或者1,0
resize:是否可以重新設置大小,值:yes,no或者1,0
fullscreen:全屏,值:yes,no或者1,0
例如:在新窗體中打開http://www.imooc.com網站,大小為300px * 200px,無菜單,無工具欄,無狀態欄,
有滾動條窗口,距屏頂100像素,屏左0像素。:
<script type="text/javascript">
window.open
('http://www.imooc.com','_blank','width=300,height=200,top=100,left=0,menubar=no,toolbar=no,
status=no,scrollbars=yes')//用雙引號括起來也可,
</script>
注意:運行結果考慮瀏覽器兼容問題。
12,關閉窗口(window.close)
close()關閉窗口
用法:
window.close(); //關閉本窗口
或
<窗口對象>.close(); //關閉指定的窗口
例如:關閉新建的窗口。
<script type="text/javascript">
var mywin=window.open('http://www.imooc.com'); //將新打的窗口對象,存儲在變量mywin中
mywin.close();
</script>
注意:上面代碼在打開新窗口的同時,關閉該窗口,看不到被打開的窗口。
13,認識DOM
文檔對象模型DOM(Document Object Model)定義訪問和處理HTML文檔的標准方法。DOM 將HTML文
檔呈現為帶有元素、屬性和文本的樹結構(節點樹)。
HTML文檔可以說由節點構成的集合,三種常見的DOM節點:
1,元素節點
2,文本節點
3,屬性節點
例如:
<a href="http://www.imooc.com">JavaScript DOM</a>
元素節點:a
文本節點:JavaScript DOM
屬性節點:href="http://www.imooc.com"
14,innerHTML 屬性
innerHTML 屬性用於獲取或替換 HTML 元素的內容。
語法:
Object.innerHTML
注意:
1.Object是獲取的元素對象,如通過document.getElementById("ID")獲取的元素。
2.注意書寫,innerHTML區分大小寫。
例如:
<body>
<h2 id="con">javascript</H2>
<script type="text/javascript">
var mychar=document.getElementById("con"); ;
document.write("原標題:"+mychar.innerHTML+"<br>"); //輸出原h2標簽內容
mychar.innerHTML="Hello world!";
document.write("修改后的標題:"+mychar.innerHTML); //輸出修改后h2標簽內容
</script></body>
15,改變 HTML 樣式
HTML DOM 允許 JavaScript 改變 HTML 元素的樣式。如何改變 HTML 元素的樣式呢?
語法:
Object.style.property=new style;
注意:Object是獲取的元素對象,如通過document.getElementById("id")獲取的元素。
基本屬性表(property):
backgroundColor:背景顏色
height:高度
width:寬度
color:文本顏色
font:在一行設置字體屬性
fontFamily:設置元素的字體系列
fontSize:字體大小
例如:
<script type="text/javascript">
var mychar= document.getElementById("con");//注意要使用document.getElementById("con")
mychar.style.color="red";
mychar.style.backgroundColor="#ccc";
mychar.style.width="300px";
</script>
16,顯示和隱藏(display屬性)
網頁中經常會看到顯示和隱藏的效果,可通過display屬性來設置。
另一種顯示和隱藏的屬性是:visibility,值為visible和hidden,但是不同於display屬性的是,visibility隱藏時圖
片的位置不隱藏,display隱藏時圖片的位置也隱藏了。
語法:
Object.style.display = value
注意:Object是獲取的元素對象,如通過document.getElementById("id")獲取的元素。
value取值:
none:不顯示(隱藏)
block:顯示為塊級元素
例如:<script>
function show(){
var mychar = document.getElementById("con");
//或document.getElementById("con").style.display="block";
mychar.style.display="block";
}
function hide(){
var mychar = document.getElementById("con");
mychar.style.display="none";
}
</script>
16,控制類名(className 屬性)
className 屬性設置或返回元素的class 屬性。
語法:
object.className = classname
作用:
1.獲取元素的class 屬性
2. 為網頁內的某個元素指定一個css樣式來更改該元素的外觀
例如:
<style>
.one{
border:1px solid #ccc;
width:230px;
height:50px;
background:#9CF;
color:blue;
}
</style>
<script>
function add(){
var p1 = document.getElementById("p1");
p1.className = "one";//將屬性為p1的文字的樣式改為one的樣式
}
</script>
19,操作符優先級:
算術操作符>比較操作符>邏輯操作符>“=”賦值操作符
20,數組:
myarray.length; //獲得數組myarray的長度,因為數組的索引總是由0開始,所以一個數組的上下限分別是:
0和length-1。
數組隨元素的增加,長度也會改變,
二維數組:元素用中括號括起來
20,switch語句中:最后一個default后邊不必加break
21,訪問字符串對象的方法:
使用 String 對象的 toUpperCase() 方法來將字符串小寫字母轉換為大寫:
var mystr="Hello world!";
var mynum=mystr.toUpperCase();
以上代碼執行后,mynum 的值是:HELLO WORLD!
使用toLowerCase()方法,將字符串所有大寫字母都變成小寫的字符串。
22,Date 日期對象
日期對象可以儲存任意一個日期,並且可以精確到毫秒數(1/1000 秒)。
定義一個時間對象 :
var Udate=new Date();
注意:使用關鍵字new,Date()的首字母必須大寫。
使 Udate 成為日期對象,並且已有初始值:當前時間(當前電腦系統時間)。
如果要自定義初始值,可以用以下方法:
var d = new Date(2012, 10, 1); //2012年10月1日
var d = new Date('Oct 1, 2012'); //2012年10月1日
訪問方法語法:“<日期對象>.<方法>”
Date對象中處理時間和日期的常用方法:
get/setDate() //返回/設置日期
get/setFullYear() //返回/設置年份,用四位數表示
get/setYear()//返回/設置年份
get/setMonth()//返回/設置月份,0:一月。。。。11:十二月,所以加一
get/setHours()//返回/設置小時,24小時制
get/setMinutes()//返回/設置分鍾數
get/setSeconds()//返回/設置秒鍾數
get/setTime()//返回/設置時間(毫秒為單位)
24,返回指定位置的字符
charAt() 方法可返回指定位置的字符。返回的字符是長度為 1 的字符串。
語法:
stringObject.charAt(index)
參數說明
index:必須的,表示字符串中某個位置的數字,即字符在字符串中的下標
注意:1.字符串中第一個字符的下標是 0。最后一個字符的下標為字符串長度減一(string.length-1)。
2.如果參數 index 不在 0 與 string.length-1 之間,該方法將返回一個空字符串。
24,返回指定的字符串首次出現的位置
indexOf() 方法可返回某個指定的字符串值在字符串中首次出現的位置。
語法
stringObject.indexOf(substring, startpos)
參數說明:
substring:必須的,規定要檢索的字符串值,.該方法將從頭到尾地檢索字符串 stringObject,看它是否含有子
串 substring。
startpos:可選的整數參數,規定在字符串中開始檢索的位置,他的合法取值是0到stringObjectLength-1,若
省略該參數,將從字符串的首字付開始檢索,從stringObject的startpos位置開始查找substring,如果沒有此
參數將從stringObject的開始位置查找。
注意:1.indexOf() 方法區分大小寫。
2.如果要檢索的字符串值沒有出現,則該方法返回 -1。
25,字符串分割split()
知識講解:
split() 方法將字符串分割為字符串數組,並返回此數組。
語法:
stringObject.split(separator,limit)
參數說明:
separator:必須的,從該參數指定的地方分割stringObject,從而分成兩個數組,參數左側為一類,右側為一
類。
limit:可選參數,分割的次數,返回的子串不會多於這個參數指定的個數,如果無此參數將不限制次數
注意:如果把空字符串 ("") 用作 separator,那么 stringObject 中的每個字符之間都會被分割。
26,提取字符串substring()
substring() 方法用於提取字符串中介於兩個指定下標之間的字符。
語法:
stringObject.substring(starPos,stopPos)
參數說明:
startPos:必須的,一個非負的整數,開始位置
stopPos:可選,一個非負的整數,結束位置,如果省略該參數,那么返回的子串會一直到字符串對象的結尾
注意:
1. 返回的內容是從 start開始(包含start位置的字符)到 stop-1 處的所有字符,其長度為 stop 減start。
2. 如果參數 start 與 stop 相等,那么該方法返回的就是一個空串(即長度為 0 的字符串)。
3. 如果 start 比 stop 大,那么該方法在提取子串之前會先交換這兩個參數。
27,提取指定數目的字符substr()
substr() 方法從字符串中提取從 startPos位置開始的指定數目的字符串。
語法:
stringObject.substr(startPos,length)
參數說明:
startPos:必須的,要提取的子串的起始位置,必須是數值
length:可選,提取字符串的長度,如果省略,返回從startPos開始一直到結尾的字符
注意:如果參數startPos是負數,從字符串的尾部開始算起的位置。也就是說,-1 指字符串中最后一個字符,
-2 指倒數第二個字符,以此類推。
如果startPos為負數且絕對值大於字符串長度,startPos為0。
28,Math對象
Math對象,提供對數據的數學計算。
使用 Math 的屬性和方法,代碼如下:
<script type="text/javascript">
var mypi=Math.PI;
var myabs=Math.abs(-15);
document.write(mypi);
document.write(myabs);
</script>
運行結果:
3.141592653589793
15
注意:Math 對象是一個固有的對象,無需創建它,直接把 Math 作為對象使用就可以調用其所有屬性和方法
。這是它與Date,String對象的區別。
Math 對象屬性:
E:返回算術常量e,即自然對數的底數(約等於2.718)
LN2:返回2的自然對數(約等於0.693)
LN10:返回10的自然對數(約等於2.302)
LOG2E:返回以2為底的e的對數(1.442)
LOG10E:返回以10為底的e的對數(0.434)
PI:返回圓周率(3.141519)
SQRT1_2:返回2的平方根的倒數(0.707)
SQRT2:返回2 的平方根(1.414)
Math 對象方法:
abs(x):返回x的絕對值
acos(x):返回x的反余弦值
asin(x):返回x的反正弦值
atan(x):返回x的反正切值
29,向上取整ceil()
ceil() 方法可對一個數進行向上取整。
語法:
Math.ceil(x)
參數說明:
x:必須說明的值
注意:它返回的是大於或等於x,並且與x最接近的整數。
例如: document.write(Math.ceil(-5.9)) 結果是:-5
30,向下取整floor()
floor() 方法可對一個數進行向下取整。
語法:
Math.floor(x)
參數說明:
x:必須說明的值
注意:返回的是小於或等於x,並且與 x 最接近的整數。
31,四舍五入round()
round() 方法可把一個數字四舍五入為最接近的整數。
語法:
Math.round(x)
注意:
1. 返回與 x 最接近的整數。
2. 對於 0.5,該方法將進行上舍入。(5.5 將舍入為 6)
3. 如果 x 與兩側整數同等接近,則結果接近 +∞方向的數字值 。(如 -5.5 將舍入為 -5; -5.52 將舍入為 -6),
31,隨機數 random()
random() 方法可返回介於 0 ~ 1(大於或等於 0 但小於 1 )之間的一個隨機數。
語法:
Math.random();
注意:返回一個大於或等於 0 但小於 1 的符號為正的數字值。
獲得0 ~ 10之間的隨機數:(Math.random())*10
32,Array 數組對象
數組對象是一個對象的集合,里邊的對象可以是不同類型的。數組的每一個成員對象都有一個“下標”,用來
表示它在數組中的位置,是從零開始的
數組定義的方法:
1. 定義了一個空數組:
var 數組名= new Array();
2. 定義時指定有n個空元素的數組:
var 數組名 =new Array(n);
3.定義數組的時候,直接初始化數據:
var 數組名 = [<元素1>, <元素2>, <元素3>...];
我們定義myArray數組,並賦值,代碼如下:
var myArray = [2, 8, 6];
說明:定義了一個數組 myArray,里邊的元素是:myArray[0] = 2; myArray[1] = 8; myArray[2] = 6。
數組元素使用:
數組名[下標] = 值;
注意: 數組的下標用方括號括起來,從0開始。
數組屬性:
length 用法:<數組對象>.length;返回:數組的長度,即數組里有多少個元素。它等於數組里最后一個元素
的下標加一。
數組方法:
數組連接concat()
concat() 方法用於連接兩個或多個數組。此方法返回一個新數組,不改變原來的數組。
語法
arrayObject.concat(array1,array2,...,arrayN)
參數說明:
array1:要鏈接的第一個數組
。。。
arrayn:要連接的第n個數組
注意: 該方法不會改變現有的數組,而僅僅會返回被連接數組的一個副本。
例如:
<script type="text/javascript">
var myarr1= new Array("010")
var myarr2= new Array("-","84697581");
document.write(myarr1.concat(myarr2));//不是 document.write(concat(myarr1,myarr2));
</script>
指定分隔符連接數組元素join()
join()方法用於把數組中的所有元素放入一個字符串。元素是通過指定的分隔符進行分隔的。
語法:
arrayObject.join(分隔符separator)
參數說明:
separator:可選,指定要使用的分隔符,如果省略,則使用逗號分隔
例如:
<script type="text/javascript">
var myarr1= new Array("86","010")
var myarr2= new Array("84697581");
var myarr3= myarr1.concat(myarr2);
document.write(myarr3.join("-"));
</script> //結果是86-010-84697581
32,顛倒數組元素順序reverse()
reverse() 方法用於顛倒數組中元素的順序。
語法:
arrayObject.reverse()
注意:該方法會改變原來的數組,而不會創建新的數組。
33,選定元素slice()
slice() 方法可從已有的數組中返回選定的元素。
語法
arrayObject.slice(start,end)
參數說明:
start:必須的,規定從何處開始選取,若是負數,它是從數組尾部開始算起的位置,-1就是最后一個元素,-2
是倒數第二個元素
end:可選,規定從何處結束,若不指定該參數,則切分的數組從start一直到數組結束 的所有元素,若他是負
數,則它規定的是從數組尾部開始算起的元素
1.返回一個新的數組,包含從 start 到 end (不包括該元素)的 arrayObject 中的元素。
2. 該方法並不會修改數組,而是返回一個子數組。
注意:
1. 可使用負值從數組的尾部選取元素。
2.如果 end 未被規定,那么 slice() 方法會選取從 start 到數組結尾的所有元素。
3. String.slice() 與 Array.slice() 相似。
數組排序sort()
sort()方法使數組中的元素按照一定的順序排列。
語法:
arrayObject.sort(方法函數)
參數說明:
方法函數:可選,規定排序順序,必須是函數
1.如果不指定<方法函數>,則按unicode碼順序排列。
2.如果指定<方法函數>,則按<方法函數>所指定的排序方法排序。
myArray.sort(sortMethod);
注意: 該函數要比較兩個值,然后返回一個用於說明這兩個值的相對順序的數字。比較函數應該具有兩個參數 a
和 b,其返回值如下:
若返回值<=-1,則表示 A 在排序后的序列中出現在 B 之前。
若返回值>-1 && <1,則表示 A 和 B 具有相同的排序順序。
若返回值>=1,則表示 A 在排序后的序列中出現在 B 之后。
排序函數:sortNuM(a,b)
<script type="text/javascript">
function sortNum(a,b) {
return a - b;
//升序,如降序,把“a - b”該成“b - a”
}
var myarr = new Array("80","16","50","6","100","1");
document.write(myarr + "<br>");
document.write(myarr.sort(sortNum));
</script> //結果是80,16,50,6,100,1 和 1,6,16,50,80,100
JavaScript 計時器
在JavaScript中,我們可以在設定的時間間隔之后來執行代碼,而不是在函數被調用后立即執行。
計時器類型:
一次性計時器:僅在指定的延遲時間之后觸發一次。setTimeout
間隔性觸發計時器:每隔一定的時間間隔就觸發一次。setInterval
setTimeout和setInterval可以相互轉換,在setTimeout里再調用一個setTimeout可以產生與setInterval相同的
作用
例如:
function display(){
。。。。。。。。
setTimeout("display()",1000);
}
計時器方法:
setTimeout()//指定的延遲時間之后來執行代碼
clearTimeout()//取消setTimeout設置
setinterval()//每隔指定時間執行代碼
Clearinterval()//取消setinterval()設置
計時器setInterval()
在執行時,從載入頁面后每隔指定的時間執行代碼。
語法:
setInterval(代碼,交互時間);
參數說明:
參數說明:
1. 代碼:要調用的函數或要執行的代碼串。
2. 交互時間:周期性執行或調用表達式之間的時間間隔,以毫秒計(1s=1000ms)。
返回值:
一個可以傳遞給 clearInterval() 從而取消對"代碼"的周期性執行的值。
調用函數格式(假設有一個clock()函數):
setInterval("clock()",1000)
或
setInterval(clock,1000)
取消計時器clearInterval()
clearInterval() 方法可取消由 setInterval() 設置的交互時間。
語法:
clearInterval(id_of_setInterval)
參數說明:
id_of_setInterval:由 setInterval() 返回的 ID 值。
每隔 100 毫秒調用 clock() 函數,並顯示時間。
例如:
<script type="text/javascript">
function clock(){
var time=new Date();
document.getElementById("clock").value = time;
}
var i= setInterval("clock()",100);
</script>
<body>
<form>
<input type="text" id="clock" size="50" />
<input type="button" value="Stop" onclick="clearInterval(i)"/>
//點擊Stop按鈕后,取消計時器。
</form>
</body>
34,計時器setTimeout()
setTimeout()計時器,在載入后延遲指定時間后,去執行一次表達式,僅執行一次。
語法:
setTimeout(代碼,延遲時間);
參數說明:
1. 要調用的函數或要執行的代碼串。
2. 延時時間:在執行代碼前需等待的時間,以毫秒為單位(1s=1000ms)。
35,取消計時器clearTimeout()
setTimeout()和clearTimeout()一起使用,停止計時器。
語法:
clearTimeout(id_of_setTimeout)
參數說明:
id_of_setTimeout:由 setTimeout() 返回的 ID 值。該值標識要取消的延遲執行代碼塊。
例如:
<script type="text/javascript">
var num=0;
var i;
function startCount(){
document.getElementById('count').value=num;
num=num+1;
i=setTimeout("startCount()",1000);
}
function stopCount(){
clearTimeout(i);
}
</script>
<form>
<input type="text" id="count" />
<input type="button" value="Start" onclick="startCount()" />
<input type="button" value="Stop" onclick="stopCount()" />
</form>
35,History 對象
history對象記錄了用戶曾經瀏覽過的頁面(URL),並可以實現瀏覽器前進與后退相似導航的功能。
注意:從窗口被打開的那一刻開始記錄,每個瀏覽器窗口、每個標簽頁乃至每個框架,都有自己的history對象與
特定的window對象關聯。
語法:
window.history.[屬性|方法]
注意:window可以省略。
history對象屬性
length:返回瀏覽器歷史列表中的url數量
history對象方法
back():加載history列表中的前一個url//window.history.back()相當於window.history.go(-1)
forward():加載history列表中的后一個url//window.history.forward()相當於window.history.go(1)
go():加載history列表中的某個具體頁面
36,返回瀏覽歷史中的其他頁面
go()方法,根據當前所處的頁面,加載 history 列表中的某個具體的頁面。
語法:
window.history.go(number);
參數:
1:下一個頁面,go(1)等價於forward()
0:當前頁面,
-1:前一個頁面,go(-1)等價於back()
其他數值:要訪問的url在history的url列表中的相對位置
瀏覽器中,返回當前頁面之前瀏覽過的第二個歷史頁面,代碼如下:
window.history.go(-2);
注意:和在瀏覽器中單擊兩次后退按鈕操作一樣。
同理,返回當前頁面之后瀏覽過的第三個歷史頁面,代碼如下:
window.history.go(3);
36,Location對象
location用於獲取或設置窗體的URL,並且可以用於解析URL。
語法:
location.[屬性|方法]
location對象屬性圖示:
http://www.imooc.com:8080/list.php?courseid=8&chapterid=86#mediaid118
protocol:http://
host:www.imooc.com:8080
hostname:www.imooc.com
port:8080
pathname:/list.php?
search:courseid=&chapterid=86#
hash:mediaid118
hash:設置或返回從#號開始的url(錨)
host:設置或返回主機名和當前的端口號
hostname:設置或返回當前url的主機名
href:設置或返回完整的url
pathname:設置或返回當前url的路徑名
port:設置或返回當前url的路徑部分
protocol:設置或返回當前url的協議
search:設置或返回從?開始的url(查詢部分)
location 對象方法:
assign():加載新文檔
reload():重新加載當前文檔
replace():用新文檔替換當前文檔
36,Navigator對象
Navigator 對象包含有關瀏覽器的信息,通常用於檢測瀏覽器與操作系統的版本。
對象屬性:
appcodeName:瀏覽器代碼名的字符串表示
appName:瀏覽器名稱
appVersion:瀏覽器的平台和版本信息
platform:運行瀏覽器的操作系統平台
userAgent:返回由客戶機發送服務器的useragent頭部的值
37,userAgent
返回用戶代理頭的字符串表示(就是包括瀏覽器版本信息等的字符串)
語法
navigator.userAgent
幾種瀏覽的user_agent.,像360的兼容模式用的是IE、極速模式用的是chrom的內核。
38,screen對象
screen對象用於獲取用戶的屏幕信息。
語法:
window.screen.屬性
對象屬性:
availHeight:窗口可以使用的屏幕高度,單位像素
availWidth:窗口可以使用的屏幕寬度,單位像素
colorDepth:用戶瀏覽器表示的顏色位數,通常為32位(每像素的位數)
pixelDepth:用戶瀏覽器表示的顏色位數,也為32位(每像素的位數)(IE不支持此屬性)
height:屏幕的高度,單位像素
width:屏幕的寬度,單位像素
39,屏幕分辨率的高和寬
window.screen 對象包含有關用戶屏幕的信息。
1. screen.height 返回屏幕分辨率的高
2. screen.width 返回屏幕分辨率的寬
注意:
1.單位以像素計。
2. window.screen 對象在編寫時可以不使用 window 這個前綴。
40,DOM:文檔對象模型
DOM包括三種:Core DOM (核心dom),XML DOM, HTML DOM
現在主要講解html dom
DOM節點操作主要有四部分:
增:
createElement(),
appendChild(),
insertBefore(),
cloneNode()
刪:
removeChild();
改:
更改屬性:setAttribute()/對象名.屬性名
更改內容:innerHTML,innerText
查:getElementById(),getElementsByName(),getElementsByTagName(),parentNode,firstChild,lastChild,
getElementsByName()方法
返回帶有指定名稱的節點對象的集合。
語法:
document.getElementsByName(name)
與getElementById() 方法不同的是,通過元素的 name 屬性查詢元素,而不是通過 id 屬性。
注意:
1. 因為文檔中的 name 屬性可能不唯一,所有 getElementsByName() 方法返回的是元素的數組,而不是一個
元素。
2. 和數組類似也有length屬性,可以和訪問數組一樣的方法來訪問,從0開始。
41,getElementsByTagName()方法
返回帶有指定標簽名的節點對象的集合。返回元素的順序是它們在文檔中的順序。
語法:
getElementsByTagName(Tagname)
說明:
1. Tagname是標簽的名稱,如p、a、img等標簽名。
2. 和數組類似也有length屬性,可以和訪問數組一樣的方法來訪問,所以從0開始。
例如:
function getTagElements()
{
var myI=document.getElementsByTagName("input");
alert(myI.length);
}
41,區別getElementByID,getElementsByName,getElementsByTagName
以人來舉例說明,人有能標識身份的身份證,有姓名,有類別(大人、小孩、老人)等。
1. ID 是一個人的身份證號碼,是唯一的。所以通過getElementById獲取的是指定的一個人。
2. Name 是他的名字,可以重復。所以通過getElementsByName獲取名字相同的人集合。
3. TagName可看似某類,getElementsByTagName獲取相同類的人集合。如獲取小孩這類人,
getElementsByTagName("小孩")。
把上面的例子轉換到HTML中,如下:
<input type="checkbox" name="hobby" id="hobby1"> 音樂
input標簽就像人的類別。
name屬性就像人的姓名。
id屬性就像人的身份證。
方法:
getElementById:只能獲得一個
getElementsByName:獲得一組
getElementsByTagName:獲得一組
注意:方法區分大小寫
例如: <body>
<form>
請選擇你愛好:<br>
<input type="checkbox" name="hobby" id="hobby1"> 音樂
<input type="checkbox" name="hobby" id="hobby2"> 登山
<input type="checkbox" name="hobby" id="hobby3"> 游泳
<input type="checkbox" name="hobby" id="hobby4"> 閱讀
<input type="checkbox" name="hobby" id="hobby5"> 打球
<input type="checkbox" name="hobby" id="hobby6"> 跑步 <br>
<input type="button" value = "全選" onclick = "checkall();">
<input type="button" value = "全不選" onclick = "clearall();">
<p>請輸入您要選擇愛好的序號,序號為1-6:</p>
<input id="wb" name="wb" type="text" >
<input name="ok" type="button" value="確定" onclick = "checkone();">
</form>
<script type="text/javascript">
function checkall(){
var hobby = document.getElementsByTagName("input");
for(i = 0;i < hobby.length;i++){
if(hobby[i].type == "checkbox"){
hobby[i].checked = true; }
}
}
function clearall(){
var hobby = document.getElementsByName("hobby");
for(i = 0;i < hobby.length;i++){
hobby[i].checked = false;}
}
function checkone(){
var j=document.getElementById("wb").value;
var hobby = document.getElementById("hobby"+j);
hobby.checked = true; }
</script>
</body>
42,指定的值。
語法:
elementNode.setAttribute(name,value)
有時改變某個節點的屬性時,也可以用elementNode.attributeName="xxxx",即對象名.屬性名
說明:
1.name: 要設置的屬性名。
2.value: 要設置的屬性值。
注意:
1.把指定的屬性設置為指定的值。如果不存在具有指定名稱的屬性,該方法將創建一個新屬性。
2.類似於getAttribute()方法,setAttribute()方法只能通過元素節點對象調用的函數。
節點屬性
在文檔對象模型 (DOM) 中,每個節點都是一個對象。DOM 節點有三個重要的屬性 :
1. nodeName : 節點的名稱
2. nodeValue :節點的值
3. nodeType :節點的類型
一、nodeName 屬性: 節點的名稱,是只讀的。
1. 元素節點的 nodeName 與標簽名相同
2. 屬性節點的 nodeName 是屬性的名稱
3. 文本節點的 nodeName 永遠是 #text
4. 文檔節點的 nodeName 永遠是 #document
二、nodeValue 屬性:節點的值
1. 元素節點的 nodeValue 是 undefined 或 null
2. 文本節點的 nodeValue 是文本自身
3. 屬性節點的 nodeValue 是屬性的值
三、nodeType 屬性: 節點的類型,是只讀的。以下常用的幾種結點類型:
元素類型 節點類型
元素 1
屬性 2
文本 3
注釋 8
文檔 9
43,訪問子結點childNodes
訪問選定元素節點下的所有子節點的列表,返回的值可以看作是一個數組,他具有length屬性。
語法:
elementNode.childNodes
注意:
如果選定的節點沒有子節點,則該屬性返回不包含節點的 NodeList。
訪問子結點的第一和最后項
firstChild是第一個出現的子節點,lastChild是最后一個出現的子節點
一、firstChild 屬性返回‘childNodes’數組的第一個子節點。如果選定的節點沒有子節點,則該屬性返回
NULL。
語法:
node.firstChild
說明:與elementNode.childNodes[0]是同樣的效果。
二、 lastChild 屬性返回‘childNodes’數組的最后一個子節點。如果選定的節點沒有子節點,則該屬性返回
NULL。
語法:
node.lastChild
說明:與elementNode.childNodes[elementNode.childNodes.length-1]是同樣的效果。
注意: 上一節中,我們知道Internet Explorer 會忽略節點之間生成的空白文本節點,而其它瀏覽器不會。我們
可以通過檢測節點類型,過濾子節點。 (以后章節講解)
44,訪問父節點parentNode
獲取指定節點的父節點
語法:
elementNode.parentNode
注意:父節點只能有一個。
看看下面的例子,獲取 P 節點的父節點,代碼如下:
<div id="text">
<p id="con"> parentNode 獲取指點節點的父節點</p>
</div>
<script type="text/javascript">
var mynode= document.getElementById("con");
document.write(mynode.parentNode.nodeName);
</script>
運行結果:
parentNode 獲取指點節點的父節點
DIV
訪問祖節點:
elementNode.parentNode.parentNode
44,訪問兄弟節點
1. nextSibling 屬性可返回某個節點之后緊跟的節點(處於同一樹層級中)。
語法:
nodeObject.nextSibling
說明:如果無此節點,則該屬性返回 null。
2. previousSibling 屬性可返回某個節點之前緊跟的節點(處於同一樹層級中)。
語法:
nodeObject.previousSibling
說明:如果無此節點,則該屬性返回 null。
注意: 兩個屬性獲取的是節點。Internet Explorer 會忽略節點間生成的空白文本節點(例如,換行符號),而
其它瀏覽器不會忽略。
45,插入節點appendChild()
在指定節點的最后一個子節點列表之后添加一個新的子節點。
語法:
appendChild(newnode)
參數:
newnode:指定追加的節點。
例如:
var otest = document.getElementById("test");
var newnode=document.createElement("li");
newnode.innerHTML="PHP";
otest.appendChild(newnode);
46,插入節點insertBefore()
insertBefore() 方法可在已有的子節點前插入一個新的子節點。
語法:
insertBefore(newnode,node);
參數:
newnode: 要插入的新節點。
node: 指定此節點前插入節點。
注意: otest.insertBefore(newnode,node); 也可以改為: otest.insertBefore(newnode,otest.childNodes[0]);
46,刪除節點removeChild()
removeChild() 方法從子節點列表中刪除某個節點。如刪除成功,此方法可返回被刪除的節點,如失敗,則返
回 NULL。
語法:
nodeObject.removeChild(node)
參數:
node :必需,指定需要刪除的節點。
例如:
function clearText() {
var content=document.getElementById("content");
for(var i=content.childNodes.length-1;i>=0;i--){
var childNode = content.childNodes[i];
content.removeChild(childNode);
}
}
47,替換元素節點replaceChild()
replaceChild 實現子節點(對象)的替換。返回被替換對象的引用。
語法:
node.replaceChild (newnode,oldnew )
參數:
newnode : 必需,用於替換 oldnew 的對象。
oldnew : 必需,被 newnode 替換的對象。
<script type="text/javascript">
function replaceMessage(){
var newnode=document.createElement("i");
var newnodeTest=document.createTextNode("JavaScript");
newnode.appendChild(newnodeTest);
var oldNode=document.getElementById("oldnode");
oldNode.parentNode.replaceChild(newnode,oldNode);
}
47,創建元素節點createElement
createElement()方法可創建元素節點。此方法可返回一個 Element 對象。
語法:
document.createElement(tagName)
參數:
tagName:字符串值,這個字符串用來指明創建元素的類型。
注意:要與appendChild() 或 insertBefore()方法聯合使用,將元素顯示在頁面中。
48,創建文本節點createTextNode
createTextNode() 方法創建新的文本節點,返回新創建的 Text 節點。
語法:
document.createTextNode(data)
參數:
data : 字符串值,可規定此節點的文本。
50,瀏覽器窗口可視區域大小
獲得瀏覽器窗口的尺寸(瀏覽器的視口,不包括工具欄和滾動條)的方法:
一、對於IE9+、Chrome、Firefox、Opera 以及 Safari:
• window.innerHeight - 瀏覽器窗口的內部高度
• window.innerWidth - 瀏覽器窗口的內部寬度
二、對於 Internet Explorer 8、7、6、5:
• document.documentElement.clientHeight表示HTML文檔所在窗口的當前高度。
• document.documentElement.clientWidth表示HTML文檔所在窗口的當前寬度。
或者
Document對象的body屬性對應HTML文檔的<body>標簽
• document.body.clientHeight
• document.body.clientWidth
在不同瀏覽器都實用的 JavaScript 方案:
var w= document.documentElement.clientWidth
|| document.body.clientWidth;
var h= document.documentElement.clientHeight
|| document.body.clientHeight;
49,頁面滾動時使用的函數是window.onscroll=function(){}
50,網頁尺寸scrollHeight
scrollHeight和scrollWidth,獲取網頁內容高度和寬度。
如果oDiv 位於可視區內部:則有以下:
可視區距離頁面頂部的坐標,頁面頂部到可視區的距離:
var scrollTop=document.documentElement.scrollTop || document.body.scrollTop;
oDiv到頂部的距離:scrollTop+oDiv到可視區頂部的距離,即:
scrollTop+(document.documentElement.clientHeight-oDiv.offsetHeight)/2
var sw=document.documentElement.scrollWidth || document.body.scrollWidth;
一、針對IE、Opera:
scrollHeight 是網頁內容實際高度,可以小於 clientHeight。
二、針對NS、FF:
scrollHeight 是網頁內容高度,不過最小值是 clientHeight。也就是說網頁內容實際高度小於 clientHeight 時
,scrollHeight 返回 clientHeight 。
三、瀏覽器兼容性
var w=document.documentElement.scrollWidth
|| document.body.scrollWidth;
var h=document.documentElement.scrollHeight
|| document.body.scrollHeight;
注意:區分大小寫
scrollHeight和scrollWidth還可獲取Dom元素中內容實際占用的高度和寬度。
51,網頁尺寸offsetHeight
offsetHeight和offsetWidth,獲取網頁內容高度和寬度(包括滾動條等邊線,會隨窗口的顯示大小改變)。
一、值
offsetHeight = clientHeight + 滾動條 + 邊框。
二、瀏覽器兼容性
var w= document.documentElement.offsetWidth
|| document.body.offsetWidth;
var h= document.documentElement.offsetHeight
|| document.body.offsetHeight;
//10的編程挑戰待完成:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>實踐題 - 選項卡</title>
<style type="text/css">
/* CSS樣式制作 */
ul{
float:left;
}
#chose1{
margin-top:30px;
margin-left:30px;
display:block;
height:50px;
width:280px;
border:1px d black;
}
#chose2{
margin-top:30px;
margin-left:30px;
display:none;
height:50px;
width:280px;
}
#chose3{
margin-top:30px;
margin-left:30px;
display:none;
height:50px;
width:280px;
}
#btn1{
height:40px;
width:60px;
}
#btn2{
height:40px;
width:60px;
}
#btn3{
height:40px;
width:60px;
}
</style>
<script type="text/javascript">
// JS實現選項卡切換
</script>
</head>
<body>
<!-- HTML頁面布局 -->
<ul><button id="btn1">房產</button></ul>
<ul><button id="btn2">家居</button></ul>
<ul><button id="btn3">二手房</button></ul>
<div id="chose1">
275萬購昌平鄰鐵三居 總價20萬買一居
200萬內購五環三居 140萬安家東三環
北京首現零首付樓盤 53萬購東5環50平
京樓盤直降5000 中信府 公園樓王現房</div>
<div id="chose2">
40平出租屋大改造 美少女的混搭小窩
經典清新簡歐愛家 90平老房煥發新生
新中式的酷色溫情 66平撞色活潑家居
瓷磚就像選好老婆 衛生間煙道的設計
</div>
<div id="chose3">
通州豪華3居260萬 二環稀缺2居250w甩
西3環通透2居290萬 130萬2居限量搶購
黃城根小學學區僅260萬 121平70萬拋!
獨家別墅280萬 蘇州橋2居優惠價248萬
</div>
</body>
</html>
使用javascript制作網頁特效:
BOM:瀏覽器對象模型,包括window對象(就是窗口),location對象(網頁的地址欄),history對象(歷
史記錄),document對象(瀏覽器內的網頁內容),location,history,document三個對象又是window對象
的屬性
history:是有關瀏覽過的url信息
location:是有關當前的url信息,寫法:window.location或者location=“http://www.sohu.com”
跳轉鏈接:location.href=.......
刷新頁面:location.reload()
<a href="javascript:location.href=‘flower.html ' ; ">查看詳情</a>//此處是點擊鏈接跳轉到另一個頁面,
再來連接里寫javascript代碼,需要先寫上javascript:
<a href="javascript:location.reload();"></a>
document對象的屬性:
referrer:連接來源即點出當前網頁的原始網頁,document.referrer
URL:獲取當前網頁的url地址,document.URL
onload:是加載完后,
<script>
function display(){
}
</script>
<body onload=“display()”></body>//加載完頁面后執行display()函數
或者在script里加載函數:
<script>
function display(){
}
window.onload=display;//注意此處不是display(),若display(a)有參數,則另當別論,可以使用匿名函數
</script>
使用匿名函數:window.onload=function(){ display(); }
Table表格對象:
Table對象的屬性:
rows[]:所有的行,形成一個數組,
常用方法:增加行:insertRow(index),刪除行:deleteRow(index)
TableRow:一行
TableRow對象有兩個屬性,分別是ceils[]和rowIndex
ceils[]:某一行的所有單元格,形成一個數組
rowIndex表示返回該行在表中的位置,從0開始
常用方法:
insertCeil(index):在一行中的指定位置插入單元格
deleteCeil(index):刪除行中指定的單元格
TableCeil:一個單元格
有三個屬性:
ceilIndex:返回單元格的位置
innerHTML:設置或返回單元格的html
className:設置或返回元素的class屬性
對於TableCeil對象,主要使用它的屬性
級聯菜單:
例如,當選擇省份時,右邊顯示該省份的城市
數組:
讀取數組的兩種方法:
1,for循環
2,for ,,,in
var fruit=new Array("apple","orange","peach","banana");
for(var x in fruit){//其中var x 可以省略
document.write(fruit[x]+"<br/>");
}
下拉菜單:
select標簽,它包含三個屬性,
1)options屬性,是一個選項數組options[],用來返回該下拉菜單中的所有選項。
創建選項:var option=new Option(顯示文本,值)
2)length:選項總數
3)selectedIndex:被選中選項的索引號
常用方法 :
add(Option對象,添加位置),//添加位置可以為null,表示添加在末尾
常用事件:
onchange:表示改變選項時觸發
鼠標變成手型:
cursor:pointer;
li選項前邊的圓點隱藏:list-style:none;
<a></a>點擊鏈接即a標簽時觸發函數的形式:
<a href="javascript:show()">。。。</a>
圖片設置為絕對定位時:
向右是正,向下是正;
設置頁面中某個位置的圖片,隨着滾動條的滾動而一直浮動:
1)將image放入div中,設置絕對定位浮在頁面上
2)鼠標滾動時,圖片的top,left坐標跟隨改變
3)獲取鼠標滾動距離,scrollTop(滾動條向上滾動的距或x軸到滾動輪的縱向距離),scrollLeft(滾動條向
左滾動的距離或y軸到滾動輪的橫向距離)
4)利用鼠標滾動事件onScroll事件調用函數移動div位置:onscroll()
style對象定位方面的樣式:
left,top:左上角
right,bottom:右下角
position:absolute,relative,static(fix)//只有將position設置為absolute或relative時,定位才生效
z-index:疊放順序
要使用表示元素位置的像素值時,要使用parseInt轉化整型:
parseInt(x):將x轉化成整型,如var c=parseInt(a)+parseInt(b)+“px”;
獲取或設置元素的坐標:
IE瀏覽器:只能用currentStyle對象
firefox:用getComputedStyle();
document.defaultView.getComputedStyle(元素對象,null).屬性
獲取到文檔對象(根節點):即html標簽
var a=document.documentElement,/不用body,/因為因為有些瀏覽器不兼容
窗體加載時觸發函數:window.onload=函數名;//注意函數不加括號
窗體滾動時觸發函數:window.onscroll=函數名;
????下拉菜單中的選項停留問題??????
1,類:javascript是一種基於原型的語言,沒有類的聲明語句,比如c++和java,javascript可用方法作類,定
義一個類和定義一個函數一樣簡單,如
function Person(){}或者var Person=function(){}
2,對象(類的實例):
function Person(){}
var person1=new Person();
var person2=new Person();
構造器:
在實例化時構造器被調用 (也就是對象實例被創建時)。構造器是對象中的一個方法。 在JavaScript,中函數就可
以作為構造器使用,因此不需要特別地定義一個構造器方法. 每個聲明的函數都可以在實例化后被調用執行
構造器常用於給對象的屬性賦值或者為調用函數做准備。
3,屬性 (對象屬性)
屬性就是 類中包含的變量;每一個對象實例有若干個屬性. 為了正確的繼承,屬性應該被定義在類的原型屬性 (
函數)中。
可以使用 關鍵字 this調用類中的屬性, this是對當前對象的引用。 從外部存取(讀/寫)其屬性的語法是:
InstanceName.Property; 這與C++,Java或者許多其他語言中的語法是一樣的 (在類中語法 this.Property 常
用於set和get屬性值)
4,方法(對象屬性)
方法與屬性很相似, 不同的是:一個是函數,另一個可以被定義為函數。 調用方法很像存取一個屬性, 不同的
是add () 在方法名后面很可能帶着參數. 為定義一個方法, 需要將一個函數賦值給類的 prototype 屬性; 這個賦
值給函數的名稱就是用來給對象在外部調用它使用的。
function Person(firstName) {
this.firstName = firstName;
}
Person.prototype.sayHello = function() {
alert("Hello, I'm " + this.firstName);
};
var person1 = new Person("Alice");
var person2 = new Person("Bob");
// call the Person sayHello method.
person1.sayHello(); // alerts "Hello, I'm Alice"
person2.sayHello(); // alerts "Hello, I'm Bob"
繼承
創建一個或多個類的專門版本類方式稱為繼承(Javascript只支持單繼承)。 創建的專門版本的類通常叫做子
類,另外的類通常叫做父類。 在Javascript中,繼承通過賦予子類一個父類的實例並專門化子類來實現。在現
代瀏覽器中你可以使用 Object.create 實現繼承.
在下面的例子中, 我們定義了 Student類作為 Person類的子類. 之后我們重定義了sayHello() 方法並添加了
sayGoodBye() 方法.
// 定義Person構造器
function Person(firstName) {
this.firstName = firstName;
}
// 在Person.prototype中加入方法
Person.prototype.walk = function(){
alert("I am walking!");
};
Person.prototype.sayHello = function(){
alert("Hello, I'm " + this.firstName);
};
// 定義Student構造器
function Student(firstName, subject) {
// 調用父類構造器, 確保(使用Function#call)"this" 在調用過程中設置正確
Person.call(this, firstName);
// 初始化Student類特有屬性
this.subject = subject;
};
// 建立一個由Person.prototype繼承而來的Student.prototype對象.
// 注意: 常見的錯誤是使用 "new Person()"來建立Student.prototype.
// 這樣做的錯誤之處有很多, 最重要的一點是我們在實例化時
// 不能賦予Person類任何的FirstName參數
// 調用Person的正確位置如下,我們從Student中來調用它
Student.prototype = Object.create(Person.prototype); // See note below
// 設置"constructor" 屬性指向Student
Student.prototype.constructor = Student;
// 更換"sayHello" 方法
Student.prototype.sayHello = function(){
console.log("Hello, I'm " + this.firstName + ". I'm studying " + this.subject + ".");
};
// 加入"sayGoodBye" 方法
Student.prototype.sayGoodBye = function(){
console.log("Goodbye!");
};
// 測試實例:
var student1 = new Student("Janet", "Applied Physics");
student1.sayHello(); // "Hello, I'm Janet. I'm studying Applied Physics."
student1.walk(); // "I am walking!"
student1.sayGoodBye(); // "Goodbye!"
// Check that instanceof works correctly
console.log(student1 instanceof Person); // true
console.log(student1 instanceof Student); // true
對於“Student.prototype = Object.create(Person.prototype);”這一行,在不支持 Object.create方法的老
JavaScript引擎中,可以使用一個"polyfill"(又名"shim",查看文章鏈接),或者使用一個function來獲得相
同的返回值,就像下面:
function createObject(proto) {
function ctor() { }
ctor.prototype = proto;
return new ctor();
}
// Usage:
Student.prototype = createObject(Person.prototype);
封裝
在上一個例子中,Student類雖然不需要知道Person類的walk()方法是如何實現的,但是仍然可以使用這個方
法;Student類不需要明確地定義這個方法,除非我們想改變它。 這就叫做封裝,對於所有繼承自父類的方法
,只需要在子類中定義那些你想改變的即可。
抽象
抽象是允許模擬工作問題中通用部分的一種機制。這可以通過繼承(具體化)或組合來實現。
JavaScript通過繼承實現具體化,通過讓類的實例是其他對象的屬性值來實現組合。
JavaScript Function 類繼承自Object類(這是典型的具體化) 。Function.prototype的屬性是一個Object實
例(這是典型的組合)。
多態
就像所有定義在原型屬性內部的方法和屬性一樣,不同的類可以定義具有相同名稱的方法;方法是作用於所在的
類中。並且這僅在兩個類不是父子關系時成立(繼承鏈中,一個類不是繼承自其他類)。
1,JavaScript 中的類型應該包括這些:
Number(數字)
String(字符串)
Boolean(布爾)
Symbol(符號)(第六版新增)
Object(對象)包括:
1,Function(函數),2,Array(數組),3,Date(日期),4,RegExp(正則表達式)
Null(空)
Undefined(未定義)
JavaScript 還有一種內置Error(錯誤)類型,這個會在之后的介紹中提到;現在我們先討論下上面這些類型。
1,數字:
和其他編程語言(如 C 和 Java)不同,JavaScript 不區分整數值和浮點數值,所有數字在 JavaScript 中均用
浮點數值表示,所以在進行數字運算的時候要特別注意。如:
0.1 + 0.2 = 0.30000000000000004
2,JavaScript 支持標准的算術運算符,包括加法、減法、取模(或取余)等等。還有一個之前沒有提及的內
置對象 Math(數學對象),用以處理更多的高級數學函數和常數:
Math.sin(3.5);
var d = Math.PI * (r + r);
你可以使用內置函數 parseInt() 將字符串轉換為整型。該函數的第二個參數表示字符串所表示數字的基(進制
):
parseInt("123", 10); // 123
parseInt("010", 10); //10
如果調用時沒有提供第二個參數(字符串所表示數字的基),2013 年以前的 JavaScript 實現會返回一個意外
的結果:
parseInt("010"); // 8
parseInt("0x10"); // 16
這是因為字符串以數字 0 開頭,parseInt()函數會把這樣的字符串視作八進制數字;同理,0x開頭的字符串則
視為十六進制數字。
如果想把一個二進制數字字符串轉換成整數值,只要把第二個參數設置為 2 就可以了:
parseInt("11", 2); // 3
JavaScript 還有一個類似的內置函數 parseFloat(),用以解析浮點數字符串,與parseInt()不同的地方是,
parseFloat()只應用於解析十進制數字。
單元運算符 + 也可以把數字字符串轉換成數值:
+ "42"; // 42
+ "010"; // 10
+ "0x10"; // 16
如果給定的字符串不存在數值形式,函數會返回一個特殊的值 NaN(Not a Number 的縮寫):
parseInt("hello", 10); // NaN
要小心NaN:如果把 NaN 作為參數進行任何數學運算,結果也會是 NaN:
NaN + 5; //NaN
JavaScript 還有兩個特殊值:Infinity(正無窮)和 -Infinity(負無窮):
1 / 0; // Infinity
-1 / 0; // -Infinity
可以使用內置函數 isFinite() 來判斷一個變量是否為 Infinity, -Infinity 或 NaN:
isFinite(1/0); // false
isFinite(-Infinity); // false
isFinite(NaN); // false
可以使用內置函數 isNaN() 來判斷一個變量是否為 NaN:
isNaN(NaN); // true
JavaScript 還有兩個特殊值:Infinity(正無窮)和 -Infinity(負無窮):
1 / 0; // Infinity
-1 / 0; // -Infinity
可以使用內置函數 isFinite() 來判斷一個變量是否為 Infinity, -Infinity 或 NaN:
isFinite(1/0); // false
isFinite(-Infinity); //
false
isFinite(NaN); // false
字符串
JavaScript 中的字符串是一串Unicode 字符序列。這對於那些需要和多語種網頁打交道的開發者來說是個好消
息。更准確地說,它們是一串UTF-16編碼單元的序列,每一個編碼單元由一個 16 位二進制數表示。每一個
Unicode字符由一個或兩個編碼單元來表示。
如果想表示一個單獨的字符,只需使用長度為 1 的字符串。
通過訪問字符串的 長度(編碼單元的個數)屬性可以得到它的長度。
"hello".length; // 5
這是我們第一次碰到 JavaScript 對象。我們有沒有提過你可以像 objects 一樣使用字符串?是的,字符串也
有methods(方法)能讓你操作字符串和獲取字符串的信息。
"hello".charAt(0); // "h"
"hello, world".replace("hello", "goodbye"); // "goodbye, world"
"hello".toUpperCase(); // "HELLO"
其他類型
JavaScript 中 null 和 undefined 是不同的,前者表示一個空值(non-value),必須使用null關鍵字才能訪問
,后者是“undefined(未定義)”類型的對象,表示一個未初始化的值,也就是還沒有被分配的值。我們之
后再具體討論變量,但有一點可以先簡單說明一下,JavaScript 允許聲明變量但不對其賦值,一個未被賦值的
變量就是 undefined 類型。還有一點需要說明的是,undefined 實際上是一個不允許修改的常量。
JavaScript 包含布爾類型,這個類型的變量有兩個可能的值,分別是 true 和 false(兩者都是關鍵字)。根據
具體需要,JavaScript 按照如下規則將變量轉換成布爾類型:
false、0、空字符串("")、NaN、null 和 undefined 被轉換為 false
所有其他值被轉換為 true
也可以使用 Boolean() 函數進行顯式轉換:
Boolean(""); // false
Boolean(234); // true
變量
在 JavaScript 中聲明一個新變量的方法是使用關鍵字 var:
var a;
var name = "simon";
如果聲明了一個變量卻沒有對其賦值,那么這個變量的類型就是 undefined。
JavaScript 與其他語言的(如 Java)的重要區別是在 JavaScript 中語句塊(blocks)是沒有作用域的,只有
函數有作用域。因此如果在一個復合語句中(如 if 控制結構中)使用 var 聲明一個變量,那么它的作用域是整
個函數(復合語句在函數中)。但是從 ECMAScript Edition 6 開始將有所不同的, let 和 const 關鍵字允許
你創建塊作用域的變量。
運算符
JavaScript的算術操作符包括 +、-、*、/ 和 % ——求余(與模運算不同)。賦值使用 = 運算符,此外還有一
些復合運算符,如 += 和 -=,它們等價於 x = x op y。
相等的比較稍微復雜一些。由兩個“=(等號)”組成的相等運算符有類型自適應的功能,具體例子如下:
123 == "123" // true
1 == true; // true
如果在比較前不需要自動類型轉換,應該使用由三個“=(等號)”組成的相等運算符:
1 === true; //false
123 === "123"; // false
JavaScript 還支持 != 和 !== 兩種不等運算符,具體區別與兩種相等運算符的區別類似。
2,JavaScript 還提供了 位操作符。,
3,&& 和 || 運算符使用短路邏輯(short-circuit logic),是否會執行第二個語句(操作數)取決於第一個操
作數的結果。在需要訪問某個對象的屬性時,使用這個特性可以事先檢測該對象是否為空:
var name = o && o.getName();
或運算可以用來設置默認值:
var name = otherName || "default";
類似地,JavaScript 也有一個用於條件表達式的三元操作符:
var allowed = (age > 18) ? "yes" : "no";
4,default 語句是可選的。switch 和 case 都可以使用需要運算才能得到結果的表達式;在 switch 的表達式
和 case 的表達式是使用 === 嚴格相等運算符進行比較的:
switch(1 + 3){
case 2 + 2:
yay();
break;
default:
neverhappens();
}
5,對象
JavaScript 中的對象可以簡單理解成“名稱-值”對,正因為 JavaScript 中的一切(除了核心類型,core
object)都是對象,所有 JavaScript 程序必然與大量的散列表查找操作有着千絲萬縷的聯系,而散列表擅長的
正是高速查找。“名稱”部分是一個 JavaScript 字符串,“值”部分可以是任何 JavaScript 的數據類型——
包括對象。這使用戶可以根據具體需求,創建出相當復雜的數據結構。
有兩種簡單方法可以創建一個空對象:
var obj = new Object();
和:
var obj = {};
這兩種方法在語義上是相同的。第二種更方便的方法叫作“對象字面量(object literal)”法。這種也是
JSON 格式的核心語法,一般我們優先選擇第二種方法。
“對象字面量”也可以用來在對象實例中定義一個對象:
var obj = {
name: "Carrot",
"for": "Max",
details: {
color: "orange",
size: 12
}
}
對象的屬性可以通過鏈式(chain)表示方法進行訪問:
obj.details.color; // orange
obj["details"]["size"]; // 12
數組
JavaScript 中的數組是一種特殊的對象。它的工作原理與普通對象類似(以數字為屬性名,但只能通過[] 來訪
問),但數組還有一個特殊的屬性——length(長度)屬性。這個屬性的值通常比數組最大索引大 1。
創建數組的傳統方法是:
var a = new Array();
a[0] = "dog";
a.length; // 3
使用數組字面量(array literal)法更加方便:
var a = ["dog", "cat", "hen"];
a.length; // 3
注意,Array.length 並不總是等於數組中元素的個數,如下所示:
var a = ["dog", "cat", "hen"];
a[100] = "fox";
a.length; // 101
記住:數組的長度是比數組最大索引值多一的數。
可以通過如下方式遍歷一個數組:
for (var i = 0; i < a.length; i++) {
// Do something with a[i]
}
這么做效率不太好,因為每循環一次都要計算一次長度。改進的版本是:
for (var i = 0, len = a.length; i < len; i++) {
// Do something with a[i]
}
遍歷數組的另一種方法是使用 for...in 循環。注意,如果有人向 Array.prototype 添加了新的屬性,使用這樣
的循環這些屬性也同樣會被遍歷。所以並不推薦這種方法:
for (var i in a) {
// Do something with a[i]
}
ECMAScript 5 增加了遍歷數組的另一個方法 forEach():
["dog", "cat", "hen"].forEach(function(currentValue, index, array) {
// Do something with currentValue or array[index]
});
如果想在數組后追加元素,只需要:
a.push(item);
函數
學習 JavaScript 最重要的就是要理解對象和函數兩個部分。最簡單的函數就像下面這個這么簡單:
function add(x, y) {
var total = x + y;
return total;
}
這個例子包括你需要了解的關於基本函數的所有部分。一個 JavaScript 函數可以包含 0 個或多個已命名的變
量。函數體中的表達式數量也沒有限制。你可以聲明函數自己的局部變量。return 語句在返回一個值並結束函
數。如果沒有使用 return 語句,或者一個沒有值的 return 語句,JavaScript 會返回 undefined。
已命名的參數更像是一個指示而沒有其他作用。如果調用函數時沒有提供足夠的參數,缺少的參數會被
undefined 替代。
add(); // NaN
// 不能在 undefined 對象上進行加法操作
你還可以傳入多於函數本身需要參數個數的參數:
add(2, 3, 4); // 5
// 將前兩個值相加,4被忽略了
這看上去有點蠢。函數實際上是訪問了函數體中一個名為 arguments 的內部對象,這個對象就如同一個類似
於數組的對象一樣,包括了所有被傳入的參數。讓我們重寫一下上面的函數,使它可以接收任意個數的參數:
function add(){
var sum=0;
for(var i=0,j=arguments.length; i<j; i++){
sum+=arguments[i];
}
return sum;
}
add(2,3,4,5); //24
接下來創建一個求平均數的函數:
function avg() {
var sum = 0;
for (var i = 0, j = arguments.length; i < j; i++) {
sum += arguments[i];
}
return sum / arguments.length;
}
avg(2, 3, 4, 5); // 3.5
求一個數組的的平均值:
function avg(arr){
var sum=0;
for(var i=0,j=arr.length; i<j; i++){
sum+=arr[i];
}
return sum/arr.length;
}
但如果能重用我們已經創建的那個函數不是更好嗎?幸運的是 JavaScript 允許使用任意函數對象的apply() 方
法來調用該函數,並傳遞給它一個包含了參數的數組。
avg.apply(null, [2, 3, 4, 5]); // 3.5
JavaScript 允許創建匿名函數:
var avg = function() {
var sum = 0;
for (var i = 0, j = arguments.length; i < j; i++) {
sum += arguments[i];
}
return sum / arguments.length;
};
document.write(avg(3,4,5,6,7)); //5
JavaScript 允許以遞歸方式調用函數。遞歸在處理樹形結構(比如瀏覽器 DOM)時非常有用。
function countChars(elm) {
if (elm.nodeType == 3) { // 文本節點
return elm.nodeValue.length;
}
var count = 0;
for (var i = 0, child; child = elm.childNodes[i]; i++) {
count += countChars(child);
}
return count;
}
這里需要說明一個潛在問題——既然匿名函數沒有名字,那該怎么遞歸調用它呢?在這一點上,JavaScript 允
許你命名這個函數表達式。你可以命名立即調用的函數表達式(IIFES——Immediately Invoked Function
Expressions),如下所示:
var charsInBody = (function counter(elm) {
if (elm.nodeType == 3) { // 文本節點
return elm.nodeValue.length;
}
var count = 0;
for (var i = 0, child; child = elm.childNodes[i]; i++) {
count += counter(child);
}
return count;
})(document.body);
自定義對象:
在經典的面向對象語言中,對象是指數據和在這些數據上進行的操作的集合。與 C++ 和 Java 不同,
JavaScript 是一種基於原型的編程語言,並沒有 class 語句,而是把函數用作類。那么讓我們來定義一個人名
對象,這個對象包括人的姓和名兩個域(field)。名字的表示有兩種方法:“名 姓(First Last)”或“姓, 名
(Last, First)”。使用我們前面討論過的函數和對象概念,可以像這樣完成定義
Person.prototype 是一個可以被Person的所有實例共享的對象。它是一個名叫原型鏈(prototype chain)的
查詢鏈的一部分:當你試圖訪問一個 Person 沒有定義的屬性時,解釋器會首先檢查這個 Person.prototype
來判斷是否存在這樣一個屬性。所以,任何分配給 Person.prototype 的東西對通過 this 對象構造的實例都是
可用的。
function Person(first, last) {
this.first = first;
this.last = last;
}
Person.prototype.fullName = function() {
return this.first + ' ' + this.last;
}
Person.prototype.fullNameReversed = function() {
return this.last + ', ' + this.first;
}
s = new Person("Simon", "Willison");
Person.prototype.firstNameCaps = function() {
return this.first.toUpperCase()
}
s.firstNameCaps(); // SIMON
還可以給 JavaScript 的內置函數原型(prototype)添加東西。讓我們給 String 添加一個方法用來返回逆序
的字符串:
var s = "Simon";
String.prototype.reversed = function() {
var r = "";
for (var i = this.length - 1; i >= 0; i--) {
r += this[i];
}
return r;
}
s.reversed(); // nomiS
定義新方法也可以在字符串字面量上用(string literal)。
正如我前面提到的,原型組成鏈的一部分。那條鏈的根節點是 Object.prototype,它包括 toString() 方法—
—將對象轉換成字符串時調用的方法。這對於調試我們的 Person 對象很有用:
var s = new Person("Simon", "Willison");
s; // [object Object]
Person.prototype.toString = function() {
return '<Person: ' + this.fullName() + '>';
}
s.toString(); // <Person: Simon Willison>
記得之前我們說的 avg.apply() 中的第一個參數 null,現在我們可以回頭看看這個東西了。apply() 的第一個
參數應該是一個被當作 this 來看待的對象。下面是一個 new 方法的簡單實現:
function trivialNew(constructor, ...args) {
var o = {}; // 創建一個對象
constructor.apply(o, args);
return o;
}
這並不是 new 的完整實現,因為它沒有創建原型(prototype)鏈。想舉例說明 new 的實現有些困難,因為
你不會經常用到這個,但是適當了解一下還是很有用的。在這一小段代碼里,...args(包括省略號)叫作剩余
參數(rest arguments)
因此調用
var bill = trivialNew(Person, "William", "Orange");
可認為和調用如下語句是等效的
var bill = new Person("William", "Orange");
apply() 有一個姐妹函數,名叫 call,它也可以允許你設置 this,但它帶有一個擴展的參數列表而不是一個數組
。
function lastNameCaps() {
return this.last.toUpperCase();
}
var s = new Person("Simon", "Willison");
lastNameCaps.call(s);
// 和以下方式等價
s.lastNameCaps = lastNameCaps;
s.lastNameCaps();
內部函數
JavaScript 允許在一個函數內部定義函數,這一點我們在之前的 makePerson() 例子中也見過。關於
JavaScript 中的嵌套函數,一個很重要的細節是它們可以訪問父函數作用域中的變量:
function betterExampleNeeded() {
var a = 1;
function oneMoreThanA() {
return a + 1;
}
return oneMoreThanA();
}
如果某個函數依賴於其他的一兩個函數,而這一兩個函數對你其余的代碼沒有用處,你可以將它們嵌套在會被
調用的那個函數內部,這樣做可以減少全局作用域下的函數的數量,這有利於編寫易於維護的代碼。
這也是一個減少使用全局變量的好方法。當編寫復雜代碼時,程序員往往試圖使用全局變量,將值共享給多個
函數,但這樣做會使代碼很難維護。內部函數可以共享父函數的變量,所以你可以使用這個特性把一些函數捆
綁在一起,這樣可以有效地防止“污染”你的全局命名空間——你可以稱它為“局部全局(local global)”
。雖然這種方法應該謹慎使用,但它確實很有用,應該掌握。
閉包
makeAdder 這個名字本身應該能說明函數是用來做什么的:它創建了一個新的 adder 函數,這個函數自身帶
有一個參數,它被調用的時候這個參數會被加在外層函數傳進來的參數上。
這里發生的事情和前面介紹過的內嵌函數十分相似:一個函數被定義在了另外一個函數的內部,內部函數可以
訪問外部函數的變量。唯一的不同是,外部函數被返回了,那么常識告訴我們局部變量“應該”不再存在。但
是它們卻仍然存在——否則 adder 函數將不能工作。也就是說,這里存在 makeAdder 的局部變量的兩個不
同的“副本”——一個是 a 等於5,另一個是 a 等於20。那些函數的運行結果就如下所示:
x(6); // 返回 11
y(7); // 返回 27
下面來說說到底發生了什么。每當 JavaScript 執行一個函數時,都會創建一個作用域對象(scope object),
用來保存在這個函數中創建的局部變量。它和被傳入函數的變量一起被初始化。這與那些保存的所有全局變量
和函數的全局對象(global object)類似,但仍有一些很重要的區別,第一,每次函數被執行的時候,就會創
建一個新的,特定的作用域對象;第二,與全局對象(在瀏覽器里面是當做 window 對象來訪問的)不同的是
,你不能從 JavaScript 代碼中直接訪問作用域對象,也沒有可以遍歷當前的作用域對象里面屬性的方法。
所以當調用 makeAdder 時,解釋器創建了一個作用域對象,它帶有一個屬性:a,這個屬性被當作參數傳入
makeAdder 函數。然后 makeAdder 返回一個新創建的函數。通常 JavaScript 的垃圾回收器會在這時回收
makeAdder 創建的作用域對象,但是返回的函數卻保留一個指向那個作用域對象的引用。結果是這個作用域
對象不會被垃圾回收器回收,直到指向 makeAdder 返回的那個函數對象的引用計數為零。
作用域對象組成了一個名為作用域鏈(scope chain)的鏈。它類似於原形(prototype)鏈一樣,被
JavaScript 的對象系統使用。
一個閉包就是一個函數和被創建的函數中的作用域對象的組合。
閉包允許你保存狀態——所以它們通常可以代替對象來使用。
內存泄露
使用閉包的一個壞處是,在 IE 瀏覽器中它會很容易導致內存泄露。JavaScript 是一種具有垃圾回收機制的語言
——對象在被創建的時候分配內存,然后當指向這個對象的引用計數為零時,瀏覽器會回收內存。宿主環境提
供的對象都是按照這種方法被處理的。
瀏覽器主機需要處理大量的對象來描繪一個正在被展現的 HTML 頁面——DOM 對象。瀏覽器負責管理它們的
內存分配和回收。
IE 瀏覽器有自己的一套垃圾回收機制,這套機制與 JavaScript 提供的垃圾回收機制進行交互時,可能會發生內
存泄露。
在 IE 中,每當在一個 JavaScript 對象和一個本地對象之間形成循環引用時,就會發生內存泄露。如下所示:
function leakMemory() {
var el = document.getElementById('el');
var o = { 'el': el };
el.o = o;
}
這段代碼的循環引用會導致內存泄露:IE 不會釋放被 el 和 o 使用的內存,直到瀏覽器被徹底關閉並重啟后。
這個例子往往無法引起人們的重視:一般只會在長時間運行的應用程序中,或者因為巨大的數據量和循環中導
致內存泄露發生時,內存泄露才會引起注意。
不過一般也很少發生如此明顯的內存泄露現象——通常泄露的數據結構有多層的引用(references),往往掩蓋
了循環引用的情況。
閉包很容易發生無意識的內存泄露。如下所示:
function addHandler() {
var el = document.getElementById('el');
el.onclick = function() {
el.style.backgroundColor = 'red';
}
}
這段代碼創建了一個元素,當它被點擊的時候變紅,但同時它也會發生內存泄露。為什么?因為對 el 的引用不
小心被放在一個匿名內部函數中。這就在 JavaScript 對象(這個內部函數)和本地對象之間(el)創建了一個
循環引用。
這個問題有很多種解決方法,最簡單的一種是不要使用 el 變量:
function addHandler(){
document.getElementById('el').onclick = function(){
this.style.backgroundColor = 'red';
};
}
有一種竅門解決因閉包而引入的循環引用,是添加另外一個閉包:
function addHandler() {
var clickHandler = function() {
this.style.backgroundColor = 'red';
};
(function() {
var el = document.getElementById('el');
el.onclick = clickHandler;
})();
}
內部函數被直接執行,並在 clickHandler 創建的閉包中隱藏了它的內容。
另外一種避免閉包的好方法是在 window.onunload 事件發生期間破壞循環引用。很多事件庫都能完成這項工
作。注意這樣做將使 Firefox 中的 bfcache 無法工作。所以除非有其他必要的原因,最好不要在 Firefox 中注
冊一個unload 的監聽器。
JavaScript 數據類型和數據結構
動態類型
JavaScript 是一種弱類型或者說動態語言。這意味着你不用提前聲明變量的類型,在程序運行過程中,類型會
被自動確定。這也意味着你可以使用同一個變量保存不同類型的數據:
var foo = 42; // foo is a Number now
var foo = "bar"; // foo is a String now
var foo = true; // foo is a Boolean now
數據類型
最新的 ECMAScript 標准定義了 7 種數據類型:
6 種 原始類型:
Boolean
Null
Undefined
Number
String
Symbol (ECMAScript 6 新定義)
和 Object類型(function函數對象,array數組對象,date日期對象,regexp正則表達式對象)
原始值
除 Object 以外的所有類型都是不可變的(值本身無法被改變)。例如,與 C 語言不同,JavaScript 中字符串
是不可變的(譯注:如,JavaScript 中對字符串的操作一定返回了一個新字符串,原始字符串並沒有被改變)
。我們稱這些類型的值為“原始值”。
布爾類型
布爾表示一個邏輯實體,可以有兩個值:true 和 false。
Null 類型
Null 類型只有一個值: null,更多詳情可查看 null 和 Null 。
Undefined 類型
一個沒有被賦值的變量會有個默認值 undefined,更多詳情可查看 undefined 和 Undefined。
數字類型
並沒有為整數給出一種特定的類型。除了能夠表示浮點數外,還有一些帶符號的值:+Infinity,-Infinity 和
NaN (非數值,Not-a-Number)。
要檢查值是否大於或小於 +/-Infinity,你可以使用常量 Number.MAX_VALUE 和 Number.MIN_VALUE。另
外在 ECMAScript 6 中,你也可以通過 Number.isSafeInteger() 方法還有 Number.MAX_SAFE_INTEGER 和
Number.MIN_SAFE_INTEGER 來檢查值是否在雙精度浮點數的取值范圍內。 超出這個范圍,JavaScript 中的
數字不再安全了,也就是只有 second mathematical interger 可以在 JavaScript 數字類型中正確表現。
數字類型只有一個整數,它有兩種表示方法: 0 可表示為 -0 和 +0("0" 是 +0 的簡寫)。 在實踐中,這也幾
乎沒有影響。 例如 +0 === -0 為真。 但是,你可能要注意除以0的時候:
42 / +0; // Infinity
42 / -0; // -Infinity
盡管一個數字常常僅代表它本身的值,但JavaScript提供了一些位運算符。 這些位運算符和一個單一數字通過
位操作可以用來表現一些布爾值。但這通常被認為是一個不好的做法,雖然 JavaScript 不提供其他的方式來表
示一組布爾值(如一個布爾值數組或一個布爾值分配給命名屬性的對象)。位操作也容易使代碼難以閱讀,理
解和維護, 在一些非常受限的情況下,可能需要用到這些技術,比如試圖應付本地存儲的存儲限制。 位操作
只應該是用來優化尺寸的最后選擇。
字符串類型
JavaScript的字符串類型用於表示文本數據。它是一組16位的無符號整數值的“元素”。在字符串中的每個元
素占據了字符串的位置。第一個元素的索引為0,下一個是索引1,依此類推。字符串的長度是它的元素的數量
。
不同於類 C 語言,JavaScript 字符串是不可更改的。這意味着字符串一旦被創建,就不能被修改。但是,可以
基於對原始字符串的操作來創建新的字符串。例如:
獲取一個字符串的子串可通過選擇個別字母或者使用 String.substr().
兩個字符串的連接使用連接操作符 (+) 或者 String.concat().
注意代碼中的“字串符類型”!
可以使用字串符來表達復雜的數據。以下是一些很好的性質:
容易連接構造復雜的字串符
字串符容易被調試(你看到的往往在字串符里)
字串符通常是許多APIs的常見標准 (input fields, local storage values, XMLHttpRequest當使用
responseText等的時候回應) 而且他只能與字符串一同使用。
符號類型
符號(Symbols)是ECMAScript 第6版新定義的。符號類型是唯一的並且是不可修改的, 並且也可以用來作為
Object的key的值(如下). 在某些語言當中也有類似的原子類型(Atoms). 你也可以認為為它們是C里面的枚舉類
型. 更多細節請看 Symbol 和 Symbol 。
對象
在計算機科學中, 對象是指內存中的可以被 標識符引用的一塊區域.
詳見msdn,web技術文檔 ->javascript
結構化數據: JSON
JSON (JavaScript Object Notation) 是一種輕量級的數據交換格式,來源於 JavaScrip 同時也被多種語言所
使用。 JSON 用於構建通用的數據結構。參見 JSON 以及 JSON 了解更多。
標准庫中更多的對象
JavaScript 有一個內置對象的標准庫。請查看參考來了解更多對象。
1,使用 typeof 操作符判斷對象類型,
2,判斷一個值是否是NaN
等號運算符(== 和 ===) 不能被用來判斷一個值是否是 NaN。必須使用 Number.isNaN() 或 isNaN() 函
數。
NaN === NaN; // false
Number.NaN === NaN; // false
isNaN(NaN); // true
isNaN(Number.NaN); // true
function valueIsNaN(v) { return v !== v; }
valueIsNaN(1); // false
valueIsNaN(NaN); // true
valueIsNaN(Number.NaN); // true
3,一個未初始化的變量的值為undefined,一個沒有傳入實參的形參變量的值為undefined,如果一個函數什么
都不返回,則該函數默認返回undefined.
你可以使用嚴格相等運算符來判斷一個值是否是undefined:普通相等運算符是==,嚴格相等運算符是===
var x;
if (x === undefined) {
// 執行到這里
}
else {
// 不會執行到這里
}
另外,還可以使用typeof來判斷:
var x;
if (typeof x === 'undefined') {
// 執行到這里
}
有時必須使用typeof的原因是,如果一個變量根本沒有被聲明,只有使用typeof判斷才不會報錯,用相等運算符判
斷會拋出異常.
// x沒有被聲明過
if (typeof x === 'undefined') { // 不會報錯
// these statements execute
}
if(x === undefined){ // 拋出ReferenceError異常
}
不過如果要檢測的變量是個全局變量,可以不使用typeof.可以通過檢測全局對象的同名屬性來代替:
// x可能沒有被聲明過,但如果已經聲明了的話,x是個全局變量
if (window.x === undefined) { // 即使window.x不存在,也不會報錯
// 可能會執行到這里
}
if(x === undefined){ // 如果window.x不存在,則會拋出ReferenceError異常
}
4,null
null 是一個字面量(而不是全局對象的一個屬性,undefined 是)。在 APIs 中,null 常被放在期望一個對象
,但是不引用任何對象的參數位置。當檢測 null 或 undefined 時,注意相等(==)與全等(===)兩個操作
符的區別 (前者會執行類型轉換)。
null 與 undefined 的不同點:
typeof null // object (bug in ECMAScript, should be null)
typeof undefined // undefined
null === undefined // false
null == undefined // true
讓元素移出視線的方法:
1,display:none; 顯示為無,實際存在
2,visibility:hidden; 隱藏,不存在
3,width,height的設置
4,透明度,為零則是看不見
5,改變left或是top值,移出去
6,拿一個白色的div蓋住后,慢慢移動
7,定義margin為負值,,,,12種以上
寫一個js的步驟:
1,實現布局
2,了解原理
3,學習語法
10,使用瀏覽器調試代碼時:
第一次調處錯誤,報錯后,瀏覽器會在緩存中記錄錯誤,所以改正代碼進行第二次調試前,應該把瀏覽器關掉
,清除緩存,再第二次調試
11,函數不會自動執行,
12,<script></script>腳本代碼,可以不放在文檔的最后面,但是可能不執行,這時就要把腳本代碼封裝成
一個函數,放在文檔的前面,然后在文檔全部加載完后對其進行調用,如下:
<head>
<script>
window.onload=abc;//注意不加括號,否則就直接執行下面的函數了,此時這段js代碼就可以隨便放了
function abc(){sfsafsafaeawr}
//或者是利用匿名函數如下:
window.onload=function(){ }
</script>
</head>
注意:也可以將window換成,body,img等,則是body.onload()和img.onload()
13,其它函數也可以使用匿名函數,如:li.onclick=function(){}
14,函數也可以就沒有名字,就是匿名函數,
可以以這種方式調用:元素.事件=function (){ };
何時使用有名函數,何時使用匿名函數?
同一個函數會被多次調用時,則將該函數命名,使用有名函數
15,onmouseout:鼠標離開事件。
onmousemove:鼠標撫摸事件
onmouseover:鼠標移入,移到元素上面觸發的事件
16,隨時寫,隨時做測試:
利用alert();
使用css偽類時:這些狀態包括:活動狀態,已被訪問狀態,未被訪問狀態,和鼠標懸停狀態。
a:link,a:visited,a:hover,a:active
注釋:在 CSS 定義中,a:hover 必須位於 a:link 和 a:visited 之后,這樣才能生效!
注釋:在 CSS 定義中,a:active 必須位於 a:hover 之后,這樣才能生效!
p:first-child {font-weight: bold;}
li:first-child {text-transform:uppercase;}
第一個規則將作為某元素第一個子元素的所有 p 元素設置為粗體。第二個規則將作為某個元素(在 HTML 中
,這肯定是 ol 或 ul 元素)第一個子元素的所有 li 元素變成大寫。
提示:最常見的錯誤是認為 p:first-child 之類的選擇器會選擇 p 元素的第一個子元素。
:lang 偽類
:lang 偽類使你有能力為不同的語言定義特殊的規則。在下面的例子中,:lang 類為屬性值為 no 的 q 元素定義
引號的類型:
<html>
<head>
<style type="text/css">
q:lang(no)
{
quotes: "~" "~"
}
</style>
</head>
<body>
<p>文字<q lang="no">段落中的引用的文字</q>文字</p>
</body></html>
10,讀操作:
元素.屬性名
11,寫操作:
元素.屬性名=新值,
讀取元素內的內容:innerHTML
obj.innerHTML=新值;//可以替換原來的所有內容
12,定義文字的顯示方向:
direction:rtl,ltr,
屬性操作的注意事項:
1,所有的相對路徑都不能拿來做判斷,如圖片的地址(img的src是href='1.jpg',或者href='html/index.html'
它是相對路徑),而href='http://www.miaov.com/1.jpg',是絕對路徑,可以用來做判斷,
2,顏色值也不要拿來做判斷,
3,innerHTML的值不要拿來做判斷
4,有些屬性不兼容時,可以利用隱藏和顯示,來回避不兼容的問題
5,兼容性問題的解決方案:如,float值進行修改時有些瀏覽器不兼容,:如object.style.float="left";這種寫
法對IE瀏覽器就不兼容,可以使用下面這種寫法:IE(styleFloat),非IE(cssFloat);也可以通過定義類選
擇器,然后修改類選擇器,如:
.left{float:left;}
.right{float:right;},需要時,修改元素本身的選擇器即可
6,中括號[]和點 . 的使用和區別:
點后面的是固定的,不能修改,如:object.style.width="100px"
中括號后的可以隨便寫,如:object.style[oAttr.value]=oVal.value;
oBtn.onclick=function(){
oAttr.value
oVal.value
oDiv.style[oAttr.value]=oVal.value;
}
20,當對同一個事物進行重復點擊時(或者點擊一次,執行兩件事中的一件事),可以利用開關來進行判斷,
onoff是開關,布爾值true則為真,
var onOff=true;
if(onOff){
this.style.background=url(images/aa.jpg);
onOff=false;
}else{
this.style.background=url(images/bb.jpg);
onOff=true;
}
21,數組的最后一句:arr[arr.length-1]
往數組的最后添加元素:arr.push();
22,先寫css樣式,再寫js代碼
23,left,top,right,bottom:相對與容器左端,頂端,有段,底端的偏移量,也可以為負值
24,調節背景顏色透明度的是:filter:alpha(opacity:80);//IE瀏覽器
opacity:0.6//非IE瀏覽器
25,將一個div塊元素放到底部時,要讓父元素有一個固定的定位,position:relative或是absolute,子元素必
須是絕對定位:position:absolute,padding-bottom:0px;
26,document.getElementById()是靜態方法,前邊只能是document,找到的是一個元素,
document.getElementsByTagName()是動態方法,前邊可以不是document,找到的 是元素的集合
黨同一個頁面中含有多個相同標簽元素時,可以不利用document來獲取,而改用父元
素.getElementsByTagName();
28,對於頁面中只含有一個的元素,可以利用 document.body.innerHTML='DSD';
document.title='';
document.body.innerHTML="<input type=""><input type=""><input type="">";
29,for循環的另一種格式:
for(;i<3;){ alert(i); i++; }
alert(i);//注意此時i的值為3
30,for(var i=0;i<3;i++){
arr[i].onclick=function(){
//此時i的值就是3,不是0等
}
}
30,innerHTML使用時注意:默認是替換當前內容,若要使其內容添加,則要使用
document.body.innerHTML+='<input type="text" value="hhhhh">';
31,考慮性能問題:
使用數組 時,先把數組的長度存起來,在使用它的長度;
當給頁面添加較多的內容時,可以不直接添加到body上,而是先把內容添加到某個變量上,最后再將變量添加
到body里,
var str=‘’;
for(var i=0;i<1000;i++){
str+=‘<input type="button" value=''>’;
}
document.body.innerHTML=str;
32,使用for循環,生成坐標:
33,改變樣式的方法:
1),使用style屬性:style.width;style.heigth;等
2),使用cssText:obj.style.cssText='width:100px;height:100px';
34,防止重復執行循環:
1)在按鈕身上找原因(用戶體驗不好),obj.disabled=true;
2)先清空,再生成,obj.innerHTML='';性能較差
3)使用判斷,利用開關onoff。設置成true,false,
36,html標簽屬性,自定義屬性:
var aBtn=document.getElementsByTagName("input");
aBtn[0].abc=456; //自定義屬性abc, 值為456
相當於是給input標簽添加了屬性abc:
<input type="button" abc=456 value="按鈕">
35,js可以為任意個html元素添加自定義屬性:
格式:對象.屬性名:
var aBtn=document.getElementByTagName("input");
for(var i=0;i<aBtn.length;i++){
aBtn[i].abc=123;//為每個input元素添加abc屬性,值為123,
aBtn[i].xyz=true;//為每個input元素添加xyz屬性,值為true,
}
<input type="text" value=""/>
<input type="text" value=""/>
<input type="text" value=""/>
36,for循環里若包含其他函數,函數里盡量不要用for循環里的變量:如:
for(var i=0;i<aBtn.length;i++){
aBtn[i].index=i;//使用自定義屬性(自定義索引),將i值賦給自定義屬性;
aBtn[i].onclick=function(){
//不要直接用這種形式,alert(i);而是要添加上面的自定義屬性,
alert(this.index);
}
}
37,想建立“匹配”,“對應”關系,就用自定義索引:
var arr=["李四","張三","王五"];
var aBtn=document.getElementByTagName("input");
var aP=document.getElementByTagName("p");
for(var i=0;i<aBtn.length;i++){
aBtn[i].index=i;
aBtn[i].onclick=function(){
this.value=arr[this.index]; //this指的是aBtn[i]
aP[this.index].innerHTML=arr[this.index];
}
}
37,對於單一元素,可以通過document.getElementsByTagName("")[0];獲取元素
38,對於圖片切換時的列表選項li:若想在點擊圖片時,切換每個li選項及樣式:有兩種方法:
1)全部清空,當前添加
for(var i=0;i<aLi.length;i++){
aLi[i].className='';//全部清空
}
this.className='active'; //當前添加
2)清空上個,當前添加
var num=0;
var oldLi=null;
oldLi=aLi[num];
oldLi.className='';
oldLi=this;
this.className='active';
38,存在兩層或兩層以上的for循環時,盡量先不要在里面寫事件,如點擊事件等,先將要操作的對象拿出來,
放在外面定義,例如聲明一個數組,再利用數組對象,調用push函數,進行添加其他元素,
var aLi=null;
var arrLi=[];
for(var i=0;i<aUl.length;i++){
aLi=aUl[i].getElementsByTagName("li");
for(var j=0;j<aLi.length;j++){
arrLi.push(aLi[j]); //先不寫點擊事件,//只是為了找元素
}
}
for(var i=0;i<arrLi.length;i++){ //添加事件
arrLi[i].onclick=function(){
//注意此處兩個for之間有函數包裹,所以可以用重復的i,若沒有函數,則不可以用重復的i,而是j
for(var i=0;i<arrLi.length;i++){
arrLi[i].className='';
}
this.className="hover"; //先清空再添加
}
}
39,任何一個非空對象object,都可以添加自定義屬性,自定義屬性的后面的值可以任意為任何東西
也可以添加函數:但是調用時要注意加括號;
var obj=document;
obj.fn1=function(){alert(123);}
obj.fn1();
var arr=[1,2,3,5];
alert(arr.length);
arr[2]=345;
alert(arr);//此時彈出的結果為1,2,345,5
向數組里添加東西的函數:push();如arr.push();
var json={ name:'hjhhh',age:5 };//json也是對象,用於存放數據等,不僅僅是數字
alert(json.name+'今年'+json.age+'歲');
var n=null;
n.abc=123;
alert(n.abc);//回報錯,因為n是空的對象,不存在,
35,類型轉換:
1)將看起來像數字的字符串轉換為數字:Number();
//Number()可以將空字符串轉換為0,將true裝換為1,將空數組轉化為0,將數組里的字符串也轉化為數字,
json的則轉不了,空類型也可以轉化為0;未定義類型的則轉不了,若數組里的元素太多了,也轉不了
36,parseInt和number():
不是整體轉換,一個一個字符轉換,碰到空格向后繼續找,
parseInt(b,10)//10代表十進制
36,parseFloat:認得小數點,
37,parseInt和parseFloat合作使用:
if(parseInt(num)==parseFloat(num)){
alert(num+'是整數');
}else{
alert(num+'是小數');
}
38,顯示類型轉換(強制類型轉換)
Number();
parseInt();
parseFloat();
39,隱式類型轉換:
-*/%,++,--:將字符串進行轉換然后變為數字
+:變成字符串,和-*/相反
>,<:也會轉換成數字
數字之間的比較和字符串都比較是不同的:
數字之間的比較:指的比較,
字符串的比較:一位一位的比較,比較每一位的大小,若第一位比較后分出了大小,后面就不用看了
!取反:,感嘆號后面的不論是數字還是字符串,都轉化成布爾值,把右邊的數據類型轉換成布爾值
==:判斷值,不論數據類型是什么,最后比較的結果轉換成布爾值,
===:判斷值和數據類型,先判斷類型,再判斷值,
無論是強制還是隱形,轉換不了時,都會出現NaN,
出現非法運算時,也會出現NaN
NaN:表示不是數字的數字類型
isNaN:是不是不是一個數字(不是數字)
NaN的特性,:
1)代表的布爾值是false
2)所有的東西自己和自己都是相等的,但是NaN除外,它自己和自己不相等,
3)是數字類型,但不是數字,
isNaN():
參數不是數字,討厭數字,參數也不可為布爾值,因為布爾值的返回結果是1或0,其他均可,值為true,false
,
若參數是包含數字的字符串,isNaN默認使用Number()來進行數字類型轉換,
41,函數傳遞的參數:就是js的 數據類型,包括數字,字符串,布爾,函數,對象,未定義等類型
42,函數傳參數時:
當參數為匿名函數時
43,,調用函數時,加括號:
fn3( function(a){alert(a)})
function fn3(fn){ fn(100); }
當參數為有名參數時,不加括號:
function fn4(){
alert(4);
}
fn3(fn4);//不加括號
function fn3(fn){
fn();
}
44,利用函數傳參(重用代碼)時,
1,盡量保證html代碼結構一致,可以通過父級元素選取子元素
2,把核心程序實現,用函數包起來
3,把每組不同的值找出來,通過傳參實現
44,從html里獲取的任何內容的值都是字符串形式,不能用+=。而要用++;或者將字符串先轉換為number
類型,再計算,
45,邊框顏色:burlywood,border:burlywood solid 1px;
46,段落縮進:text-indent:20px;
text-indent,可以應用在段落p上,也可以應用在li標簽的縮進上
46,作用域:
作用:讀,寫
域:空間,范圍,區域,
一個script就是一個域,在script里聲明的都是全局變量,全局函數,只要是域,就會發生預解析和逐行解讀,
瀏覽器:
js解析器:
1)預解析:先找一些東西存在倉庫里:var, function,參數,一開始讀的所有變量都是未定義,在正式運行
代碼之前,都提前顧了一個值,就是未定義,所有的函數,在正式運行之前,都是整個函數塊,一個整體,,
預解析該函數得到的就是整個代碼塊,
預解析就是對var,function,參數進行篩選,得到最終的存在庫里的東西
2)再逐行讀代碼:
每次讀取時,都是先看預解析時的倉庫里的對應的值,然后通過表達式修改相應變量的值
表達式:如,等號=,+,-,*,%,/,++,--,!,參數,.....Number(),這些都可以改寫變量的都叫表達式
表達式可以修改預解析的值,
47,預解析時,遇到重復定義的變量和函數,留下函數(不論聲明順序如何),
若是重復定義的是級別相同的,如函數,則遵循優先級,留下后聲明的,
例如:
alert(a);//彈出彈出函數function a(){alert(4)},原因如上
var a=1;
alert(a); //彈出1,
function a(){alert(2);}
alert(a);//彈出1
var a=3;
alert(a); //彈出3
function a(){alert(4)}
alert(a); //彈出3
alert(typeof(a));//彈出number
//執行結果是,彈出函數function a(){alert(4)},彈出1,彈出1,彈出3,/彈出3,彈出number
執行過程:
1)預解析:
a=1是未定義值; //根據var關鍵字
a=function a(){alert(2);} //根據function
但是由於未定義值1和函數function a(){alert(2);}相比,留下函數function a(){alert(2);},因為變量和函數重名
,留下函數,
a=3也是未定義值 //根據var關鍵字
所以留下函數function a(){alert(2);}
a=function a(){alert(4);} //根據function
函數function a(){alert(2);}和函數function a(){alert(4);}相比,留下最后聲明的function a(){alert(4);},
所以預解析篩選完后最終得到a=function a(){alert(4);},
所以第一個alert(a)得到的就是function a(){alert(4);},
2)逐行讀代碼:
第一個alert(a)就彈出function a(){alert(4);}
然后var a=1修改了未定義的a值,使其變成1,所以第二個和第三個alert(a)也彈出1,
后面又有var a=3,將a修改成3,所以第四個和第五個alert()彈出3,
48,js頁面中,可以有多個script代碼塊,但執行時是分塊執行的,先處理一個script里的代碼再執行另外的
script代碼塊
49,域:自上而下的,上面聲明的東西就會先存到庫里
函數:由里向外,若函數內部(子級)沒有var等關鍵字,就向上找父級里的內容看有無,稱之為作用域鏈。
50,函數也是域,
1)也會先預解析:var,function,參數,a=,,,,,,
2)逐行讀代碼:函數內部的變量和函數外部的變量無關,
例如:
var a=1;
function fn1(){
alert(a); //未定義
var a=2;
} //彈出的是undefined和1
fn1(); //彈出的是undefined
alert(a); /彈出的是1
函數內部的變量前面的var有很大影響:
例如:
var a=1;
function fn1(){
alert(a); //彈出1
a=2; //沒有var的情況,此處,局部變量a將全局變量a改成了2,
}
fn1();//彈出1
alert(a); //彈出2,因為全局變量改變了
過程:
1)預解析:var ,function,參數.....,得到:
a=未定義
fn1=function fn1(){
alert(a);
a=2;
}
2)逐行讀代碼:
表達式
函數調用(函數也是域,所以又開始預解析,讀代碼)
1)預解析:var,function,參數,得到:
由於內部沒有var,function,參數等,所以向上找,得a=1,並且將外部的a改成2
2)逐行讀代碼:
例如:
var a=1;
function fn1(a){
alert(a); //彈出未定義undefined
a=2; //因為函數內部有就近的a,所以改變的是函數內部的局部變量a,函數外部的沒變
}
fn1(); //彈出未定義undefined,因為沒有參數,所以上邊的參數a相當於就還是未定義
alert(a); //彈出1
例如:
var a=1;
function fn1(a){
alert(a);
a=2;
}
fn1(a); //彈出1,因為此處有參數,並且傳的是第一行的全局變量a,值為1
alert(a); //彈出1
1)預解析:
a=1;
function fn1(a){
alert(a);
a=2;
}
2)逐行解讀代碼:
碰到函數調用,再繼續解析,讀代碼:
1)預解析:此處可以解析到一個參數a,值是未定義,
2)逐行讀代碼:從參數開始執行,參數a是從全局變量傳來的,所以alert(1);同時a=2改變的是內部
的局部變量(參數a)的值,所以alert(a)彈出的是全局變量1;,所以兩次彈出的都是1
50,全局變量,任何函數都可以改變它,因為在函數內部找不到,所以通過作用域鏈,有里向外查找到全局變
量,對其修改,
51,外部的變量對應外部,找不到內部的東西,
52,從外部獲取函數內部的變量,1)可以通過全局變量來獲取:
var str='';
function fn1(){
var a='哈哈哈';
str=a;
}
alert(str);
2)function fn2(){
var a='鑽石';
fn3(a);
}
function fn3(b){
alert(b);
}
53,並非所有的大括號都是作用域,只有函數的大括號才是作用域,if,for,dowhile等的括號不是作用域,
可以接受解析,但因火狐瀏覽器不同,有不同結果,火狐不能對他們預解析,
54,盡量不在if,for,等的循環中,進行全局變量或全局函數的定義,否則容易不被解析。
55,for循環下有click等事件並且有函數,在函數里面不能直接用for循環里的i,因為for循環執行速度非常快
,例如:for(i=0;i<aBtn.length;i++)執行到函數里邊時,i已經變成aBtn.length了,不存在而數組里的元素的
下標最大是aBtn.length-1,所以會報錯,未定義,所以往往需要加雙重循環,而不是直接寫相應操作,如:
for(var i=0;i<aBtn.length;i++){
aBtn.onclick=function(){
//不能在此處直接寫aBtn.style.background='yellow';
for(var i=0;i<aBtn.length;i++){
//此處有無var進行聲明,也有影響,若沒有就向外查找,有則是undefine,否則是3
aBtn.style.background='yellow';
}
}
}
56,運算符 :
取模%:有時在播放5張圖片時,會用到 var i=0;i++;if(i ===5 ){ i=0;},播放完再回到第一張,此時可以
利用取模運算符,將if語句塊替換成i%=5,或者是i=i%5;這樣也可以依次輪流播放5張圖片;
57,在平鋪顏色時,可以利用取模運算來使有限幾個的顏色,重復顯示,
var aLi=document.getElementsByTagName("li");
var arr=['red','yellow','blue'];
for(var i=0;i<aLi.length;i++){
aLi[i].style.background=arr[i%arr.length];
}
58,利用取模運算符,實現鼠標移入,移開時的顏色變化:
for(var i=0;i<aLi.length;i++){
aLi[i].index=i; //注意要想在下面的函數內部使用i,不能直接使用,而是要添加索引,
aLi[i].style.background=arr[i%arr.length];
aLi[i].onmouseover=function(){
this.style.background='gray';
- }
aLi[i].onmouseout=function(){
this.style.background=arr[this.index%arr.length];
}
58,可以利用暫存的方法來更改顏色值:
var str='';//先聲明一個空值變量,用於以后暫存顏色值
for(var i=0;i<aLi.length;i++){
aLi[i].index=i; //注意要想在下面的函數內部使用i,不能直接使用,而是要添加索引,
aLi[i].style.background=arr[i%arr.length];
aLi[i].onmouseover=function(){
str=this.style.background;//暫存顏色值
this.style.background='gray';
}
aLi[i].onmouseout=function(){
//this.style.background=arr[this.index%arr.length];
this.style.background=str;
}
60,checkbox的寫法:
<input type='checkbox' checked/>//checked是默認代表選中的,
61,js控制checkbox的選中和取消:
var aInp=document.getElementsByTagName('input');
aInp[[0].onclick=function(){
for(var i=1;i<aInp.length;i++){
if(aInp[i].checked){
aInp[i].checked=false;
}else{
aInp[i].checked=true;
}
//上面的if語句塊,可以用下面的一句布爾值來替換
aInp[i].checked=!aInp[i].checked;//若是真則變為假,若是假則變為真
}
}
61,流程控制:
1)if(){}else if(){}else{}語句有時可以通過switch語句來替換;
2)簡單的if()else()語句可以利用三元運算符來替換,?:
3)while循環有時等同於for循環;
4)break:跳出循環;
continue:跳過本次循環,繼續下次循環,
for(var i=0;i<6;i++){
if(i==4){
//break; //跳出
continue; //跳過
}
alert(i);
}
62,真假問題:數據類型,數字(NaN),字符串,布爾,函數,對象(元素,數組[],null,json{},)
真:所有數字除0之外的數字都是真的即非0 的數字,非空字符串(空格),true,函數,能找到的元素,數組
[],json{},
假:0, NaN,空字符串,false,不能找到的元素,null,未定義
63,函數返回值return詳解:
所有函數的默認返回值都是未定義,不加return或是return后沒有東西,都是未定義,
return 后的東西就是數據類型:數字,字符串,布爾,函數,對象,,未定義,
return后的值就等於函數名稱+()
functon fn(){
return ‘hhh’; }
hhh=fn();//return后的值就等於函數名稱+();
alert( typeof(fn()) ); //彈出的就是string
return 一個函數:
function fn2(){
return function(){
alert(1);
}
}
alert(fn2());//注意此處會彈出function(){alert(1);},不是1,
要想彈出1:fn2()();//fn2()是匿名函數的名稱,再加個括號才是調用
若利用函數傳參:
function fn2(a){
return function(b){
alert(a+b);
}
}
fn(20)(10);//彈出30
function fn3(){
return window;
}
fn3.onload=function(){ document.body.innerHTML=123;}
65,return和函數結合,獲取元素ID:
window.onload=function(){
getId('btn1').onclick=function(){
alert( getId('div1').innerHTML);
}
}
function getId( id ){
return document.getElementById( id );
}
66,return和數組結合使用:
alert( fn1(5) );
alert( fn1(7) );
function fn1(n){
var arr=[];
for(var i=1;i<=n;i++){
arr.push(i);
}
return arr;
}
67,arguments實參集合與局部變量,局部參數,作用域:
實參:實際傳遞的參數,
形參:形式上,代表實際參數的參數
arguments:實參的集合,ByTagName也是集合,
當函數的參數個數無法確定時,用arguments參數集合;
alert(sum(1,2,3));
alert(sum(1,2,3,4));
function sum(){//函數參數個數不確定,
var n=0;
for (var i = 0; i < arguments.length; i++) {
n+=arguments[i];
}
return n;//注意返回值別忘寫
}
var a=1;
function fn2( a ){ //此處的a和arguments[0],alert( a)中的a等同,;
arguments[0]=3; //此處arguments集合對其進行改寫為3,其既可以讀也可以寫
alert( a); //彈出3
var a=2;
alert( arguments[0] ); //彈出2
}
fn2(a);
alert(a); //彈出1
css樣式表里的樣式和行間樣式(元素標簽內部寫的style樣式),兩者相比之下,獲取時獲取到的是行間樣式。
68,currentStyle與ComputedStyle
getComputedStyle().width函數獲得的是計算機(瀏覽器)計算之后的樣式; //IE6,7,8低版本不支持
currentStyle.width 也可以得到樣式但是也有兼容性問題 //標准瀏覽器不兼容
68,不要通過以上兩個方法去獲取未設置的樣式
69,復合樣式:如background:url(),red.......屬性值有多種的,就是復合樣式
使用getStyle函數獲取該類復合樣式時,注意要轉換為單一樣式的寫法,如:backgroundColor,也不要寫成
background-color,js不喜歡這種。
function $(v){
if (typeof(v)=== 'function') {
window.onload=v;
}else if (typeof(v)==='string') {
return document.getElementById(v);
}
}
$(function(){
$('btn1').onclick=function(){
alert(getStyle($('div1'),'backgroundColor'));
//注意此處的實參的寫法,帶引號,注意引號和屬性之間不能有空格
//否則是undefined
/*注意火狐4.4版本之前的,此處應該寫一個參數(任意值均可),alert(getStyle
($('div1'),250).width);可以為任意值,可以不是250*/
}
})
function getStyle(obj,attr){
if (obj.currentStyle) {
return obj.currentStyle[attr];
}else{
return getComputedStyle(obj)[attr];
}
}
68,定時器基礎:
for(var i=0;i<3;i++){}//瞬間完成,沒有時間根據,
定時器:
var timer=setInterval(函數,毫秒);
clearInterval(timer);//清除定時器,就是讓定時器停止
setTimeout()常用於頁面廣告,打開頁面后過幾秒后彈出廣告
var timer1=setTimeout(函數,毫秒),只執行一次的,
clearTimeout(timer1);
例:
<style>
img{display:none;}
</style>
window.onload=function(){
var miaov=document.getElementById('miaov');
setTimeOut(function(){
miaov.style.display='inline-block';//注意圖片的顯示方式是inline-block;
setTimeOut(function(){
miaov.style.display='none';
},3000); //廣告圖片展示3秒后消失
},2000);//頁面打開2秒后彈出廣告圖片
}
<body>
<img id='miaov' src='img/miaov.jpg'/>
</body>
兩種定時器可以互換,只要將setInterval設置開關,就可以控制實現setTimeout的功能。
setInterval(fn,1000);//注意setInterval中的函數fn后邊不加括號,否則就和直接調用沒區別了
函數調用:
1)fn(); //直接調用
2)document.onclick=fn; //事件調用
例:
var i=0;
var timer=null; //注意先聲明一個變量,為空
function fn(){
i++;
document.title=i;
//i++,注意順序,順序不同,結果不同
if (i===3) {
clearInterval(timer);
}
}
timer=setInterval(fn,1000);// 調用定時器,此時調用函數,
70,使用定時器時,注意,1)有時若連續觸發定時器事件后,容易產生定時器亂套或重復點擊速度加快的的
情況,即事件發生的時間頻率變的越來越短,解決辦法是,在事件發生的開頭就先利用clearInterval清除一次
定時器,
2)初次之外,有時到達位置后再點擊還會運動,是因為定時器所在位置附近還有別的語句,則連續點擊定時
器時,雖然定時器清空看,但別的語句還會執行,此時可以利用if{}else{}語句,將定時器和其他語句分別封裝
起來,分開執行。
3)有時當速度設置成等於某些值時,不會停止,此時可將速度設置成大於等於某些值即可
運動框架:
1)在開始運動前,關閉已有定時器
2)把運動和停止隔開(if {}else{}語句)
var arrUrl=[‘1.jpg’,‘2.jpg’,‘3.jpg’,‘4.jpg’];
var timer=null;
var num=0;
var oBody=document.body;
aBtn[0].onclick=function(){
clearInterval(timer);
//注意此處先清除定時器,若沒有這句,狂點按鈕后會造成圖片快速變化的亂套情況
timer=setInterval(function(){
oBody.style.background='url('arrUrl[num]+')';
num++;
num%=arrUrl.length; //可以使圖片重復循環
},1000);
}
注意:如果定時器是由用戶控制的,要先關后開,即如上面的例子先清除,再開始
70,注意利用數組,存放圖片;
72,使用定時器循環顯示圖片時可能會和鼠標移入事件沖突:此時利用清除定時器操作,
並且注意是在整個頁面上使用定時器:若oDiv代表頁面,則
oDiv.onmouseover=function(){clearInterval(timer);}
鼠標離開時,再繼續定時器的循環操作,可以將定時器的操作封裝成一個函數如function autoPlay()={},
省的再重復編寫調用定時器函數,如oDiv.onmouseout=autoPlay;
71, 事件調用時,函數不加括號:
function autoPlay(){}
72,QQ面板及旁邊的title,並列div:
使用定時器,定時顯示和隱藏即可,
也可以應用到淘寶,天貓等網站上方的導航處,鼠標移入時下方出現並列的介紹細節的div
如:oDiv.onmouseout=autoPlay; //函數名稱+括號=返回值,若沒定義返回值,就是undefine,
73,變量放到外面的問題:
寫函數時,外邊盡量不放變量,如定時器,通常會在外面設置timer為null,有時可以將其甚至為某個元素的屬
性,如oDiv.timer=null;清除時,清除的就是div身上的屬性,clearInterval(oDiv.timer)
74,函數封裝的傳參,判斷:
當有相同部分代碼出現時,可以將其封裝成函數,找到不同的點,將其進行傳參或判斷處理,數字是可以作為
傳遞的參數,但是符號則不可以,
75,兩個相同執行語句的if語句可以進行合並,如下:
if(speed>target && dir >0){
speed=targe;
}
if(speed<target && dir <0){
speed=targe;
}
可以合並成:
if(speed>target && dir >0 || speed<target && dir <0){
speed=targe;
}
76,判斷方向時:
如果當前位置大小小於目標點位置,則移動的方向應該是正方向,否則就是負方向。
77,回調函數:
調用函數時,當所有都執行完后,再讓它做別的動作,就是回調函數,將回調函數寫在參數位置處。
78,當某個函數,存在的時候就執行,不存在就不執行,的寫法:
if(endFn){endFn();}
或者:endFn&&endFn();
79,點擊頁面上任意位置的對象是document:document.onclick=........
80,函數內部的this指的是window,若讓其指向指定對象 ,需要對其進行傳遞,var _this=this;
81,控制台語句:(可用於調試js代碼)
1)console.log('控制台輸出信息'); //並非彈出,而是在控制台輸出信息;
alert();會阻止后面的運行,還要點確定
2)console.warn('警告信息提示');
3)console.error('錯誤信息提示'); //try catch 語句可用利用到
4)分組調試:console.group(‘第一組’);//雙引號內為分組的名字
console.log(123456);
console.groupEnd();//分組有開始,也有結束
例如:
<script>
console.group(‘第一組’);//雙引號內為分組的名字
console.log(123456);
console.groupEnd();//分組有開始,也有結束
</script>
5)console.dir(名稱);//顯示該對象的所有信息,
console.log(名稱);//可能會有一部分信息顯示不出來
6)console.dirxml(oDiv);//顯示oDiv當前元素的包含的所有結構內容
7)斷言:
console.assert(a);//若a的值為真,則表示斷言成功,若a的值為假,表示斷言失敗,會顯示失敗
8)查看函數執行過程,console.trace()
例如:
function a(){
return b();
}
function b() {
return c();
}
function c(){
console.trace();
return 1;
}
a();
9)計算執行時間console.time('')
console.time('計時器')//注意括號內必須寫標題
console.timeEnd('計時器')//有開始有結束
例如:
console.time('計時器')
for(var i=0;i<1000000;i++){}
console.timeEnd('計時器')
10)顯示概況,console.profit(); 作用和FireBug里的概況是相同的,顯示也相同
例如:
console.profile();
for(){}//代碼
console.profileEnd();
11)在其他瀏覽器下(如IE,等)也可以使用FireBug,不過應該是FireBug-Lite.,可以在線引用,將其網址
復制到script代碼中,也可以將其下載下來,
<script type="text/javascript" src="https://getfirebug.com/firebug-lite.js"></script>
80,offsetLeft:就是該元素當前所處的位置,
81,讓一個物體從左到右跑,就是不斷加大它的left值,首先將定位,設置為絕對定位,
82,當想要獲取一個圖片的透明度時,沒有特定的屬性可以利用,不像left,top,width等可用offsetLeft,
offsetWidth,沒有offsetOpacity和offsetAlpha,此時可以先在style樣式里將其透明度設置成一個值,然后再
聲明一個變量,值為和style樣式里相同的透明度值,對這個變量進行操作
83,“分享到”側邊欄,原理:通過目標點計算速度值,offsetLeft和target比較,得到speed的正負
83,緩沖運動:
逐漸變慢,越接近終點,速度越小,
var speed=(target-oDiv.offsetLeft)/8;
target-oDiv.offsetLeft,表示目標點到當前位置的距離,除以8之前速度的大小就是距離這么長,除以8后有了
緩沖的效果,速度由大變小,
緩沖運動時,有時物體到達的位置不是正好的所要求的像素值,利用取整方法
if(speed >0){
speed=Math.ceil(speed);
}else { speed = Math.floor(speed);}
或者是三目寫法:
speed=speed>0?Math.ceil(speed):Math.floor(speed);
83,任何的if else 語句都可以寫成三目運算的寫法
84,向上取整,向下取整:Math.ceil(),Math.floor();
Math.ceil(0.00001);//結果是1
Math.floor(0.999999);//結果是0
Math.ceil(-12.5);//結果是-12
84,小數的問題:如在透明度變換的定時器中,會由於反復執行定時器而產生透明度閃爍的問題,原因就是透
明度是小數的問題,計算機,手機,服務器等內存是有限的,不能真正的存儲小數,模擬地存儲小數。
編程時,盡量避免寫小數。
如:iOpacity=parseFloat(getStyle(obj,attr)*100);//這樣寫會產生閃爍情況,因為透明度的值是小數,只要
將其轉換成整數即可,如下:
iOpacity=parseInt(parseFloat(getStyle(obj,attr)*100));
85,運動框架:
window.onload=function(){
var oDiv=document.getElementById('div1');
oDiv.onmouseover=function(){
over(300);
}
oDiv.onmouseout=function(){
over(100);
}
}
var timer=null;
function over(target){
var oDiv=document.getElementById('div1');
clearInterval(timer);
timer=setInterval(function(){
var speed=(target-oDiv.offsetWidth)/8;
speed=speed>0?Math.ceil(speed):Math.floor(speed);
//利用取整函數是為了達到緩沖運動的效果
if (oDiv.offsetWidth==target) {
clearInterval(timer);
}else{
oDiv.style.width=oDiv.offsetWidth+speed+'px';
//注意此處是odiv.style.width
};
},30);
}
86,多物體及任意值(包含透明度opacity)運動框架:
<script type="text/javascript">
window.onload=function(){
var aDiv=document.getElementsByTagName('div');
//aDiv[i].timer=null;//在每個div身上都加一個定時器
aDiv[0].onmouseover=function(){
move(this,'width',300);
//此處添加參數表明是哪個div運動
}
aDiv[1].onmouseover=function(){
move(this,'height',200);
}
aDiv[2].onmouseover=function(){
move(this,'font-size',100);
}
aDiv[0].onmouseout=function(){
move(this,'width',100);//恢復到原來
}
aDiv[1].onmouseout=function(){
move(this,'height',50);//恢復到原來
}
aDiv[2].onmouseout=function(){
move(this,'font-size',20);//恢復到原來
}
}
//var timer=null;為了解決多個物體同時運動時出現定時器卡的問題,在每個div身上都加一個定時
器,在上面添加一個aDiv[i].timer=null;
function getStyle(obj,attr){
if (obj.currentStlye) {
return obj.currentStlye[attr];
}else{
return getComputedStyle(obj,false)[attr];
}
}
function move(obj,attr,target){
clearInterval(obj.timer);
obj.timer=setInterval(function(){
//注意對速度的聲明賦值等操作要在定時器函數里面,否則緩沖效果不會實現
var iCur=0;
if (attr == 'opacity') {
iCur=parseInt(parseFloat(getStyle(obj,attr))*100);
}else{
iCur = parseInt(getStyle(obj,attr));
}
var speed=(target-iCur)/8;
speed=speed>0?Math.ceil(speed):Math.floor(speed);
if (iCur==target) {//注意此處
clearInterval(obj.timer);
}else{
if (attr =='opacity') {
obj.style.opacity=(iCur+speed)/100;
}else{
obj.style[attr]=iCur+speed+'px';
}
//注意此處是obj.style[attr]
}
},30);
}
</script>
87,多個物體淡入淡出:
window.onload=function(){
var aDiv=document.getElementsByTagName('div');
var i = 0;
for (i = 0; i < aDiv.length; i++) {
//var aDiv.timer=null;
aDiv[i].alpha=30;//將透明度綁定為物體的屬性
aDiv[i].onmouseover=function(){
move(this,100);
}
aDiv[i].onmouseout=function(){
move(this,30);
}
};
//var alpha=30;定時器可以單獨定義,透明度alpha也可以,所以此處的透明度定義省
略,放在for循環里定義
function move(obj,target){
clearInterval(obj.timer);
obj.timer=setInterval(function(){
var speed=(target-obj.alpha)/8;
speed=speed>0?Math.ceil(speed):Math.floor(speed);
//緩沖運動
if (obj.alpha==target) {
clearInterval(obj.timer);
}else{
obj.alpha+=speed;
//obj.style.filter='alpha(opacity:'+alpha')';
obj.style.opacity=obj.alpha/100;
}
},30);
}
}
88,多個對象同時執行一個鼠標移入移出事件:
oBtnPrev.onmouseover=oMarkLeft.onmouseover=function(){..............};
oBtnPrev.onmouseout=oMarkLeft.onmouseout=function(){..............};
89,封裝getByClass(oParent,sClass)函數:該函數可通過父元素來獲取子元素,
function getByClass(oParent,sClass){
var aEle=document.getElementByTagName('*');
var i=0;
var aResult=[];
for(i=0;i<aEle.length;i++){
if(aEle[i].className==sClass){
aResult.push(aEle[i]);
}
}
return aResult;
}
如:var oSmallUl=getByClass(oDiv,'small_pic')[0];//第0個是因為只有一個
89,調試程序時,如果程序沒反應,甚至頁面都沒反應,
1)先看事件加沒加上去,利用alert()進行調試,若有反應,則可能是元素選錯了
2)將相應元素加個邊框
90,制作透明度可以變化的選項卡時:
例如:在執行鼠標點擊事件時,只有當前的圖片顯示,其他圖片模糊,則可以這樣操作透明度:
aImg[i].onclick=function(){
for(var i=0;i<aImg[i].length;i++){
startMove(aImg[i],'opacity',60); //其他圖片模糊
}
startMove(this,'opacity',100); //當前的圖片顯示
}
91,圖片進行切換(下拉切換)時,注意層級關系,否則其他圖片都會被第一張圖片(層級最高)擋住,通過改變
索引值來改變解決層級問題:
aBigLi[this.index].style.zIndex=iMinZindex++;//aBigLi是當前小圖片對應的大圖片,iMinZindex是開始圖片
的索引值
aBigLi[this.index].style.height=0;//先將其高度定義為0,然后才能利用定時器有下拉的動作;
startMove(aBigLi[this.index],'height',oBigUl.offsetHeight);//另其下拉到oBigUl.offsetHeight的高度;
92,當重復執行某個動作時,不想讓它重復執行事件,可利用return;
如:if(this.index==iNow)return;//直接return就行,不用加別的;
93,鏈式運動框架(一環扣一環):
<script type="text/javascript">
window.onload=function(){
var oDiv=document.getElementsByTagName('div')[0];
oDiv.onmouseover=function(){
move(oDiv,'width',200,function(){
move(oDiv,'height',200,function(){
move(oDiv,'opacity',100);
});
});
}
oDiv.onmouseout=function(){
move(oDiv,'opacity',30,function(){
move(oDiv,'height',100,function(){
move(oDiv,'width',100);
});
});
}
}
function getStyle(obj,attr){
if (obj.currentStyle) {
return obj.currentStyle[attr];
}else{
return getComputedStyle(obj,false)[attr];
}
}
function move(obj,attr,target,fn){
clearInterval(obj.timer);
obj.timer = setInterval(function(){
var iCur=0;
if (attr == 'opacity') {
iCur=parseInt(parseFloat(getStyle(obj,attr))*100);
}else{
iCur = parseInt(getStyle(obj,attr));
}
var speed = (target-iCur)/8
speed = speed>0?Math.ceil(speed):Math.floor(speed);
if (iCur == target) {
clearInterval(obj.timer);
fn&&fn();//注意位置,要放在這里
}
else{
if (attr =='opacity') {
obj.style.opacity=(iCur+speed)/100;
}else{
obj.style[attr]=iCur+speed+'px';
}
}
},30);
}
</script>
93,數組循環方法:
1)普通的循環方法:
var i=0;
for(i=0;i<arr.length;i++){。。。。。。}
2)利用 in
for(i in arr){。。。。。。。}