來自拉鉤教育-JAVA就業(yè)集訓(xùn)營(yíng)
JavaScript 詳解
課程目標(biāo):
1眉孩、JavaScript介紹
2、HTML和JavaScript結(jié)合方式
3草戈、JavaScript的使用
4、DOM操作
5、BOM操作
1. JavaScript介紹
- 雖然是java作為前綴拱烁,但java和javascript的關(guān)系耳胎,就像老婆和老婆餅之間的關(guān)系缸废,沒有一毛錢關(guān)系!
- 網(wǎng)景公司在Netscape2.0首先推出了JavaScript
- JavaScript 的正式名稱是 “ECMAScript”妓肢,此標(biāo)準(zhǔn)由 ECMA 組織發(fā)展和維護(hù)揪惦,簡(jiǎn)稱“js”
- JavaScript 是一種網(wǎng)頁編程技術(shù)性宏,用來向 HTML 頁面添加交互行為
- JavaScript 是一種基于對(duì)象和事件驅(qū)動(dòng)的解釋性腳本語言枪向,直接嵌入 HTML 頁面赛不,由瀏覽器解釋執(zhí)行代碼蔬胯,不進(jìn)行預(yù)編譯。
1.1 js的特點(diǎn)
- 可以使用任何文本編輯工具編寫畜伐,只需要瀏覽器就可以執(zhí)行程序 (后面會(huì)學(xué)習(xí)不用瀏覽器也能運(yùn)行)
- 解釋執(zhí)行:事先不編譯,逐行執(zhí)行
- 基于對(duì)象:內(nèi)置大量現(xiàn)成對(duì)象
- 適宜:
- 客戶端數(shù)據(jù)計(jì)算
- 客戶端表單合法性驗(yàn)證
- 瀏覽器事件的觸發(fā)
- 網(wǎng)頁特殊顯示效果制作
1.2 js的組成
- ECMAScript:定義核心語法家凯,關(guān)鍵字,運(yùn)算符,數(shù)據(jù)類型等系列標(biāo)準(zhǔn)
- DOM:文檔對(duì)象模型颂碘,將一個(gè)html頁面的所有節(jié)點(diǎn)看成是一個(gè)一個(gè)的對(duì)象。更有層次感的管理每一個(gè)節(jié)點(diǎn)。
- BOM:瀏覽器對(duì)象模型崩泡,是對(duì)瀏覽器窗口進(jìn)行訪問和操作庶弃。使用 BOM屡穗,開發(fā)者可以移動(dòng)窗口芋绸、改變狀態(tài)欄中的文本以及執(zhí)行其他與頁面內(nèi)容不直接相關(guān)的動(dòng)作。使 BOM 獨(dú)樹一幟且又常常令人懷疑的地方在于颂跨,它只是 JavaScript 的一個(gè)部分敢伸,沒有任何相關(guān)的準(zhǔn)。
- 彈出新的瀏覽器窗口
- 移動(dòng)恒削、關(guān)閉瀏覽器窗口以及調(diào)整窗口大小
- 提供 Web 瀏覽器詳細(xì)信息的定位對(duì)象
- 提供用戶屏幕分辨率詳細(xì)信息的屏幕對(duì)象
- 對(duì) cookie 的支持
- IE 擴(kuò)展了 BOM池颈,加入了 ActiveXObject 類尾序,可以通過 JavaScript 實(shí)例化 ActiveX對(duì)象,進(jìn)而實(shí)現(xiàn)ajax局部刷新技術(shù)
2. HTML與javaScript結(jié)合方式
- 使用js的三種方式
2.1.行內(nèi)腳本
- 點(diǎn)擊按鈕(觸發(fā))
- 彈框(具體的操作)
<button onclick="alert('彈框測(cè)試')">點(diǎn)我一下</button>
2.2.內(nèi)部腳本
- 使用<script></script>
- 標(biāo)準(zhǔn)是寫在head和body之間(脖子位置)躯砰,但其實(shí)只要寫在html文件內(nèi)部就可以每币,無論什么位置<html>外,<p></p>內(nèi)部琢歇,都可以兰怠。
<body>
<script>
alert("彈框");
</script>
</body>
2.3.外部腳本
- 在項(xiàng)目根目錄下創(chuàng)建一個(gè)目錄js
- 在js目錄中創(chuàng)建一個(gè)文件,后綴名是.js
- 在html頁面中李茫,使用
<script src="js/xx.js"></script>
- 以上使用腳本的三種方式的優(yōu)先級(jí)揭保,誰在上,誰先執(zhí)行魄宏。因?yàn)槭墙忉屝哉Z言秸侣。
3. JavaScript的使用
3.1 變量
- 因?yàn)閖s是弱類型語言,所以娜庇,在定義變量的時(shí)候塔次,所有的數(shù)據(jù)類型都是var
- 聲明變量: var x ; var x,y;
- 數(shù)值類型:number
- 不區(qū)分整型數(shù)值和浮點(diǎn)型數(shù)值
- 所有數(shù)字都采用 64 位浮點(diǎn)格式存儲(chǔ),類似于double 格式
- 字符串:string
- 首尾由單引號(hào)或雙引號(hào)括起
var aa="歡迎來到\"JavaScript世界";
- 布爾類型:
- 僅有兩個(gè)值:true和false也代表1和0
- 實(shí)際運(yùn)算中true=1,false=0
3.1.1 自動(dòng)類型轉(zhuǎn)換
數(shù)字 + 字符串:數(shù)字轉(zhuǎn)換為字符串 10+’a’ -> 10a
數(shù)字 + 布爾值:true轉(zhuǎn)換為1名秀,false轉(zhuǎn)換為0 true+5->6
字符串 + 布爾值:布爾值轉(zhuǎn)換為字符串true或false true+’a’->truea
布爾值 + 布爾值:布爾值轉(zhuǎn)換為數(shù)值1或0 true+true->2
3.1.2 數(shù)據(jù)類型轉(zhuǎn)換函數(shù)
- parseInt:強(qiáng)制轉(zhuǎn)換成整數(shù)
- 如果不能轉(zhuǎn)換励负,則返回 NaN (NaN 屬性是代表非數(shù)字值的特殊值。該屬性用于指示某個(gè)值不是數(shù)字)
- 例如:parseInt("6.32")=6
- parseFloat:強(qiáng)制轉(zhuǎn)換成浮點(diǎn)數(shù)
- 如果不能轉(zhuǎn)換匕得,則返回 NaN
- 例如:parseFloat("6.32")=6.32
- typeof:查詢數(shù)值當(dāng)前類型继榆,返回 string / number / boolean / object
- 例如:typeof("test"+3)=="string"
3.1.3 null 與 undefined
- null 在程序中代表“無值”或者“無對(duì)象”
- 可以通過給一個(gè)變量賦值 null 來清除變量的內(nèi)容
- undefined
- 聲明了變量但從未賦值或者對(duì)象屬性不存在
3.1.4 算術(shù)運(yùn)算
- 加(+)、 減(-)汁掠、 乘( * ) 略吨、除( / ) 、余數(shù)( % )
- - 可以表示減號(hào)考阱,也可以表示負(fù)號(hào)翠忠,如:x = -y
- +可以表示加法,也可以用于字符串的連接
- 遞增( ++ ) 乞榨、遞減( -- )
- i++ 相當(dāng)于 i=i+1
- i-- 相當(dāng)于 i=i-1
3.1.5 關(guān)系運(yùn)算
- 嚴(yán)格相等:===
- 類型相同
- 數(shù)值相同
- 非嚴(yán)格相等:!==
var a = "10";
var b = 10;
if (a == b)
alert("equal");
if (a === b)
alert("same");
3.1.6 邏輯運(yùn)算
- 邏輯非(!)秽之、邏輯與(&&)、邏輯或(||)
- 邏輯運(yùn)算的操作數(shù)均為 boolean 表達(dá)式
- 我要吃兩碗拉面或者10個(gè)包子才能吃飽吃既!問題是考榨,我只吃兩碗面,飽了鹦倚! 我只吃10個(gè)包子河质,飽了
- 我要吃兩碗拉面并且10個(gè)包子才能吃飽!問題是,我只吃兩碗面掀鹅,沒飽散休! 我只吃10個(gè)包子,沒飽淫半,
3.1.7 控制語句
if(關(guān)系表達(dá)式) {
// 語句塊 1
}else {
// 語句塊 2
}
if (表達(dá)式1) {
// 語句1;
}else if (表達(dá)式2){
// 語句2;
}else if (表達(dá)式3){
// 語句3;
} else{
// 語句4;
}
switch (表達(dá)式) {
case 值1:
// 語句1;
break;
case 值2:
// 語句2;
break;
default:
// 語句4;
}
for (var i=1 ; i<=5 ; i++){
alert(i);
}
while (條件){
// 語句1;
...
}
3.2 常用字符串API
- length:獲取字符串的長(zhǎng)度(字符串中字符的個(gè)數(shù)) 屬性溃槐,沒有小括號(hào)
var str = "hello";
console.log( str.length );
- toUpperCase/toLowerCase :轉(zhuǎn)大小寫
var name = "AngierSun";
console.log( "大寫:"+name.toUpperCase() );
console.log( "小寫:"+name.toLowerCase() );
- charAt(下標(biāo)) : 返回某個(gè)下標(biāo)上的字符
var str1 = "javascript網(wǎng)頁教程";
var str2 = str1.charAt(12); // 下標(biāo)12上的字符
console.log(str2); //教
var str3 = str1.charCodeAt(12);
console.log(str3); //25945:(漢字“教”在unicode編碼中的編號(hào))
- indexof(字符):查找字符串中字符出現(xiàn)的首次下標(biāo)
- lastIndexof(字符):查找字符串中字符最后一次出現(xiàn)的下標(biāo)
var str1 = "javascript網(wǎng)頁教程";
var str2 = str1.indexOf("a");
console.log(str2); // 1 , a字符在str1中第一次出現(xiàn)的下標(biāo)
var str3 = str1.lastIndexOf("a"); //3,a字符在str1中最后一次出現(xiàn)的下標(biāo)
console.log(str3);
- substring(開始,結(jié)束):截取字符串中一部分(結(jié)束是不包含的)
var str1 = "abcdefgh";
var str2 = str1.substring(2,4);
console.log(str2); //cd,從2開始(包含)科吭,4結(jié)束(不包含)
- replace(舊的,新的):將字符串中的舊字符替換成新字符
var str1 = "abcde";
var str2 = str1.replace("cd","XXX");
console.log(str2); // abXXXe昏滴,將str1中的cd替換成XXX
- split(分割的節(jié)點(diǎn)):一個(gè)字符串切割成N個(gè)小字符串,所以返回的是數(shù)組類型
var str1 = "一,二,三,四,五";
var arr = str1.split(","); // 將str1 以逗號(hào)進(jìn)行分割对人,分割成N份谣殊,所以返回的結(jié)果一定是數(shù)組結(jié)構(gòu)
console.log( "共分割成:"+arr.length+"份" );
console.log( "第三份是:" + arr[2] ); // 三
3.3 數(shù)組
3.3.1 創(chuàng)建數(shù)組
var arr1 = new Array();
3.3.2 初始化數(shù)組的三種方式
// 第一種
var arr1 = new Array();
arr1[0] = 110;
arr1[1] = 119;
arr1[2] = 120;
// 第二種
var arr1 = new Array(10,"a",true);
// 第三種
var arr1 = [10,"a",true];
for (var i = 0; i < arr1.length; i++) {
console.log(arr1[i]);
}
3.3.3 數(shù)組的常用方法
- tostring():將數(shù)組轉(zhuǎn)換成字符串
var arr = [1,2,3,4];
console.log("類型為:" + typeof( arr ) );
var str = arr.toString(); // 將數(shù)組轉(zhuǎn)換成字符串
console.log( str +",類型為:" + typeof( str ) );
- join(連接符號(hào)):將數(shù)組中的每個(gè)元素用連接符號(hào)連接成一個(gè)新的字符串。
var arr = [1,2,3,4];
var str = arr.join("-"); // 將數(shù)組中每個(gè)元素用-進(jìn)行連接牺弄,并形成一個(gè)全新的字符串
console.log( str +",類型為:" + typeof( str ) );
- concat(新元素):將原來的數(shù)組連接新元素姻几,原數(shù)組不變。
var arr = [1,2,3,4];
var arrnew = arr.concat(5,6); // 在arr數(shù)組的后面添加新的元素势告,形成一個(gè)新數(shù)組蛇捌,但是原數(shù)組是不變的
console.log( arrnew +",類型為:" + typeof( arrnew ) );
console.log("原數(shù)組:" + arr);
- slice(開始,結(jié)束):在數(shù)組中提取一部分咱台,形成新的數(shù)組络拌。
- 1,2,3,4,5 slice(2,4) 結(jié)果:3,4
var arr = ['a','b','c','d','e','f','g','h'];
var arrnew = arr.slice( 2,4 ); // 在arr數(shù)組中截取,從2開始(包含)回溺,4結(jié)束(不包含)
console.log( arrnew ); // cd
- reverse():數(shù)組的反轉(zhuǎn)(倒序)
var arr = [31,12,111,444];
console.log( arr.toString() );
arr.reverse(); // 將數(shù)組中的元素倒置
console.log( arr.toString() );
- sort():數(shù)組排序
- arr.sort() 字符排序
var arr = [31,12,111,444];
arr.sort(); // 字符排序(不會(huì)按照字面量的大写好场)
console.log( arr );
- arr.sort(func) 數(shù)值排序
var arr = [31,12,111,444];
arr.sort( laosun ); // 數(shù)字排序(會(huì)按照字面量的大小)
console.log( arr );
// 定義排序函數(shù)
function laosun(a,b){
return a-b;
}
3.4 Math數(shù)學(xué)對(duì)象
- Math 對(duì)象用于執(zhí)行數(shù)學(xué)任務(wù)
- 沒有構(gòu)造函數(shù) Math()
- 無需創(chuàng)建遗遵,直接把 Math 作為對(duì)象使用就可以調(diào)用其所有屬性和方法
// 返回0-9之間任意一個(gè)隨機(jī)數(shù)字
var i = Math.random() * 10;
var j = Math.floor(i);
console.log(j);
3.5 Number對(duì)象
- Number.fixed(2); 自帶四舍五入技能
var n = new Number( 12.345 );
var n1 = n.toFixed(2); // 12.35萍恕,固定兩位小數(shù),第三位小數(shù)四舍五入
console.log( n1 );
var x = new Number( 12.3 );
var n2 = x.toFixed(2); // 12.30车要,固定兩位小數(shù)允粤,位數(shù)不夠,0來補(bǔ)齊
console.log( n2 );
3.6 正則表達(dá)式
- 對(duì)字符串執(zhí)行模式匹配的強(qiáng)大工具
var reg1 = /^\d{3,6}$/; // 匹配純數(shù)字3-6個(gè)
var reg2 = new RegExp(“^\\d{3,6}$");
// 方式1
var age = "18"; // 判斷:1-3位純數(shù)字
var reg = /^\d{1,3}$/; // 以/^開始翼岁,中間寫正則內(nèi)容维哈,以$/結(jié)束
var b = reg.test(age); // 驗(yàn)證age變量的是否符合reg的匹配
if (b == true) {
console.log("驗(yàn)證通過!");
} else {
console.log("格式錯(cuò)誤");
}
// 方式2
var name = "abc123"; // 大小寫字母和數(shù)字的組合(特殊字符不能出現(xiàn)), 5~8位
var reg = new RegExp("^[a-zA-Z0-9]{5,8}$"); // 以^開始登澜,中間寫正則內(nèi)容,以$結(jié)束
if (reg.test(name)) {
console.log("驗(yàn)證通過飘庄!");
} else {
console.log("格式錯(cuò)誤");
}
3.7 日期對(duì)象
var time = new Date();
console.log( time ); // Tue Jul 14 2020 11:09:46 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)
var year = time.getFullYear(); // 年份
var month = time.getMonth() + 1; //月份從0開始脑蠕,11結(jié)束,所以國(guó)內(nèi)習(xí)慣要+1
var day = time.getDate(); // 幾號(hào)
var hour = time.getHours(); // 幾點(diǎn)
var mm = time.getMinutes(); // 分鐘
var s = time.getSeconds(); //秒
var ms = time.getMilliseconds(); // 毫秒, 1000毫秒 = 1秒
var timestr = year+"年"+month+"月"+day+"號(hào) "+hour+"點(diǎn)"+mm+"分"+s+"秒"+ms+"毫秒";
console.log( timestr );
3.8 函數(shù)
- 使用關(guān)鍵字 function 定義函數(shù)
function 函數(shù)名( 形參列表 ){
// 函數(shù)體
return 返回值;
}
- 函數(shù)聲明后不會(huì)立即執(zhí)行谴仙,會(huì)在我們需要的時(shí)候調(diào)用到迂求。
-
注意:
- 形參:一定不要帶數(shù)據(jù)類型
- 分號(hào)是用來分隔可執(zhí)行JavaScript語句。 由于函數(shù)聲明不是一個(gè)可執(zhí)行語句晃跺,所以不以分號(hào)結(jié)束揩局。
3.8.1 無返回值
function qiuhe(a, b) {
var he = a + b;
console.log("兩數(shù)之和:" + he);
}
qiuhe(3,4);
3.8.2 有返回值
function qiuhe(a, b) {
var he = a + b;
return "兩數(shù)之和:" + he;
}
var s = qiuhe(3,4);
console.log( s );
3.8.3 參數(shù)對(duì)象
- 在函數(shù)內(nèi)部,調(diào)用參數(shù)列表的屬性
function func(a,b,c){
console.log( arguments.length ); // 獲得參數(shù)的個(gè)數(shù)
console.log( arguments[1] ); // 獲得下標(biāo)為1的參數(shù)
}
3.8.4 構(gòu)造函數(shù)
- 函數(shù)同樣可以通過內(nèi)置的 JavaScript 函數(shù)構(gòu)造器(Function())定義
var myFunction = new Function("a", "b", "return a * b");
var x = myFunction(4, 3);
console.log(x);
注: 上述函數(shù)以分號(hào)結(jié)尾掀虎,因?yàn)樗且粋€(gè)執(zhí)行語句凌盯。
3.8.5 匿名函數(shù)
- 沒有名稱的函數(shù)
var fn = function(a, b) {// 沒有名字的函數(shù),應(yīng)該用一個(gè)變量來接收
return a * 10 + b;
};
console.log( fn(3, 4) );
3.8.6 全局函數(shù)
- isNaN:檢查其參數(shù)是否是非數(shù)字值
console.log( isNaN( 123 ) ); // 數(shù)字烹玉,false
console.log( isNaN( "hello" ) ); // 非數(shù)字驰怎,true
console.log( isNaN( 4-1 ) ); // 數(shù)字,false
console.log( isNaN( 123 ) ); // 數(shù)字二打,false
console.log( isNaN( -10 ) ); // 數(shù)字县忌,false
console.log( isNaN( "123" ) ); // 數(shù)字,false
console.log( isNaN( "1a23" ) ); // 非數(shù)字继效,true
- eval:用來轉(zhuǎn)換字符串中的運(yùn)算
var str = "1+3";
console.log( str ); // 1+3 , +會(huì)認(rèn)定為一種字符符號(hào)而已症杏,沒有加法的作用
console.log( eval( str ) ); // 讓字符串中的運(yùn)算符號(hào)生效
- encodeURI 與 decodeURI
var name = "拉勾網(wǎng)";
console.log( "轉(zhuǎn)碼前:" + name );
name = encodeURI(name);
console.log( "轉(zhuǎn)碼后:" + name );
name = decodeURI(name);
console.log( "解碼后:" + name );
3.8.7 閉包
1、閉包的概念:指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù)瑞信,一般情況就是在一個(gè)函數(shù)中包含另一個(gè)函數(shù)厉颤。
2、閉包的作用:訪問函數(shù)內(nèi)部變量喧伞、保持函數(shù)在環(huán)境中一直存在走芋,不會(huì)被垃圾回收機(jī)制處理;
簡(jiǎn)單地說:就是在函數(shù)的局部范圍內(nèi)聲明一個(gè)封閉的環(huán)境潘鲫,此環(huán)境不會(huì)被垃圾回收探測(cè)到翁逞。保證了數(shù)據(jù)的安全唯一性
想了解閉包,首先要了解什么是全局變量溉仑,什么是局部變量
a = 10; // 全局變量挖函,聲明的時(shí)候可以不使用var
function test1(){
b = 20; // 不適用var聲明的變量,就是全局變量
var c = 30; // 用var聲明浊竟,并且在函數(shù)的內(nèi)部怨喘。這樣的變量叫做局部變量,有效范圍只能在其聲明的函數(shù)內(nèi)部
console.log(c);
}
function test2(){
console.log(c); //c is not defined (c變量沒有定義)
}
test1();
test2();
需求:統(tǒng)計(jì)方法執(zhí)行了多少次
var count = 0; // 總次數(shù)
function test1(){
count++; // 自增+1
}
test1();
test1();
test1();
console.log( count );
誰都可以訪問count振定,所以count變量并不安全必怜,因?yàn)槭侨肿兞俊?/p>
如何才能安全呢?將count聲明為局部變量
function test1(){
var count = 0; //局部變量
return count++; //外部無法訪問count后频,只能通過return才能將count變量返回梳庆,并輸出
}
test1();
test1();
test1();
console.log( test1() ); // 每次調(diào)用方法暖途,首先就是將變量還原為0
結(jié)果一直是0,因?yàn)槊看握{(diào)用test1()膏执,方法體的第一句代碼就是還原驻售,無論曾經(jīng)的值是多少。
突發(fā)奇想更米,如果在test1()函數(shù)里面欺栗,再嵌套一個(gè)函數(shù),js是支持函數(shù)嵌套的
function test1(){
var count = 0; //局部變量
function jia(){
return count++;
}
jia();
return count;
}
test1();
test1();
test1();
console.log( test1() ); // 每次調(diào)用方法征峦,首先就是將變量還原為0
如果每次只調(diào)用test1()里面的jia()就好了迟几。ok,閉包幫你解決此問題眶痰!
function test1(){
var count = 0; //局部變量
function jia(){
return count+=1;
}
return jia;
}
var fn = test1(); // fn => function jia(){return count+=1; }
fn();
fn();
console.log( fn() ); // 每次調(diào)用方法瘤旨,首先就是將變量還原為0
- 閉包是一種保護(hù)私有變量的機(jī)制,在函數(shù)執(zhí)行時(shí)形成私有的作用域竖伯,保護(hù)里面的私有變量不 受外界干擾存哲。
- 直觀的說就是形成一個(gè)不銷毀的棧環(huán)境。
- 閉包的優(yōu)點(diǎn): 方便調(diào)用上下文中聲明的局部變量 邏輯緊密七婴,可以在一個(gè)函數(shù)中再創(chuàng)建個(gè)函數(shù)祟偷,避免了傳參的問題
- 閉包的缺點(diǎn): 因?yàn)槭褂瞄]包,可以使函數(shù)在執(zhí)行完后不被銷毀打厘,保留在內(nèi)存中修肠,如果大量使用閉包就會(huì)造 成內(nèi)存泄露,內(nèi)存消耗很大
3.9 彈框輸出
- 普通彈框 alert("hello户盯,拉勾");
- 控制臺(tái)日志輸出 console.log("谷歌瀏覽器按F12進(jìn)入控制臺(tái)");
- 頁面輸出 document.write("<h2>我愛你中國(guó)</h2>"); 將<h2>元素輸出到<body>中
- 確認(rèn)框 confirm("確定刪除嗎嵌施?");
var b = confirm("確定刪除嗎?");
if(b){
document.write( "<h1>刪除成功莽鸭!</h1>" );
}else{
document.write( "<h1>你取消了操作</h1>" );
}
- 輸入框 prompt("請(qǐng)輸入姓名:");
var name = prompt("請(qǐng)輸入你的名字:");
document.write( "<h1>大名:"+name+"吗伤!</h1>" );
4.DOM 操作
- 在一個(gè)html頁面中,會(huì)使用很多標(biāo)簽來規(guī)劃制作頁面硫眨。
- 每個(gè)標(biāo)簽都有它存在的意義足淆,如果我們想要?jiǎng)討B(tài)的修改某個(gè)標(biāo)簽的值。那我們就需要在頁面中查找到這個(gè)標(biāo)簽元素
- 如何查找到這個(gè)元素是個(gè)難題礁阁,W3C組織的工程師們巧号,突然看到了一棵大樹。我要是想找到某一片葉子姥闭,應(yīng)該怎么做丹鸿?
- “順藤摸瓜”,主樹干有分支棚品,每個(gè)分支還有許多小分支卜高,只要把這個(gè)分支的結(jié)構(gòu)整理清楚弥姻,任何一片葉子都不是難事了
- 葉子和大樹的一些啟發(fā),工程師們開會(huì)討論就定了這個(gè)理論“文檔對(duì)象模型”掺涛,
- 文檔對(duì)象模型,就是將頁面中所有的標(biāo)簽元素都看成是一個(gè)對(duì)象(一片葉子)疼进,主樹干定義為根節(jié)點(diǎn)(根元素)薪缆,所有的標(biāo)簽都是從根元素延伸出去的,摸清結(jié)構(gòu)伞广,找到某個(gè)標(biāo)簽就不再困難了
- 在節(jié)點(diǎn)樹中拣帽,頂端節(jié)點(diǎn)就是根節(jié)點(diǎn)(root)
- 每個(gè)節(jié)點(diǎn)都有父節(jié)點(diǎn)(除了根節(jié)點(diǎn))
- 任何一個(gè)節(jié)點(diǎn)都可以擁有任意數(shù)量的子節(jié)點(diǎn)
- 同胞是擁有相同父節(jié)點(diǎn)的節(jié)點(diǎn)
<html>
<head>
<meta charset="utf-8">
<title>DOM 教程</title>
</head>
<body>
<h1>第一節(jié):HTML DOM</h1>
<p>Hello world!</p>
</body>
</html>
- 從上面的 HTML 中:
- <html> 節(jié)點(diǎn)沒有父節(jié)點(diǎn);它是根節(jié)點(diǎn)
- <head> 和 <body> 的父節(jié)點(diǎn)是 <html> 節(jié)點(diǎn)
- 文本節(jié)點(diǎn) "Hello world!" 的父節(jié)點(diǎn)是 <p> 節(jié)點(diǎn)
- 并且:
- <html> 節(jié)點(diǎn)擁有兩個(gè)子節(jié)點(diǎn):<head> 和<body>
- <head> 節(jié)點(diǎn)擁有兩個(gè)子節(jié)點(diǎn):<meta> 與 <title> 節(jié)點(diǎn)
- <title> 節(jié)點(diǎn)也擁有一個(gè)子節(jié)點(diǎn):文本節(jié)點(diǎn) "DOM 教程"<h1> 和 <p> 節(jié)點(diǎn)是同胞節(jié)點(diǎn)嚼锄,同時(shí)也是
- <body> 的子節(jié)點(diǎn)
- 并且:
- <head> 元素是 <html> 元素的首個(gè)子節(jié)點(diǎn)
- <body> 元素是<html> 元素的最后一個(gè)子節(jié)點(diǎn)
- <h1> 元素是 <body> 元素的首個(gè)子節(jié)點(diǎn)
- <p> 元素是 <body> 元素的最后一個(gè)子節(jié)點(diǎn)
- js為我們提供了很多種方法來實(shí)現(xiàn)在頁面找查找某個(gè)元素節(jié)點(diǎn)
4.1 DOM訪問
- getElementById:通過id屬性獲得元素節(jié)點(diǎn)對(duì)象
- 案例:當(dāng)帳號(hào)為空時(shí)减拭,阻止表單提交
<body>
<form action="xxx" onsubmit="return login()">
<p>帳號(hào):<input id="username"/></p>
<p>電話:<input id="phone"/></p>
<p><button>登錄</button></p>
</form>
<script>
function login() {
var name = document.getElementById("username").value ;
if(name == ""){
alert("帳號(hào)不能為空!");
return false; // 阻止表單的提交
}
return true; // 放行区丑,讓表單提交
}
</script>
</body>
- getElementsByName:通過name屬性獲得元素節(jié)點(diǎn)對(duì)象集
- 案例:購(gòu)物車全選效果
<body>
<h2>我的購(gòu)物車</h2>
<table border="1" cellspacing="0">
<tr>
<td><input type="checkbox" onchange="quan(this)" /> 全選</td>
<td>名稱</td>
<td>單價(jià)</td>
</tr>
<tr>
<td><input type="checkbox" name="one" />1</td>
<td>功能性飲料-尖叫</td>
<td>4.0</td>
</tr>
<tr>
<td><input type="checkbox" name="one" />2</td>
<td>火腿腸</td>
<td>2.0</td>
</tr>
<tr>
<td><input type="checkbox" name="one" />3</td>
<td>包子</td>
<td>1.5</td>
</tr>
</table>
<p>
<button>提交訂單</button>
</p>
<script>
function quan(all) {
var arr = document.getElementsByName("one");
for (var i = 0; i < arr.length; i++) {
arr[i].checked = all.checked; // 將全選框的狀態(tài)拧粪,賦值給每一個(gè)復(fù)選框
}
}
</script>
</body>
- getElementsByTagName:通過標(biāo)簽名稱獲得元素節(jié)點(diǎn)對(duì)象集
- 案例:表格隔行變色
<body>
<table border="1" cellspacing="0">
<tr>
<td><input type="checkbox" onchange="quan(this)" /> 全選</td>
<td>名稱</td>
<td>單價(jià)</td>
</tr>
<tr>
<td><input type="checkbox" name="one" />1</td>
<td>功能性飲料-尖叫</td>
<td>4.0</td>
</tr>
<tr>
<td><input type="checkbox" name="one" />2</td>
<td>火腿腸</td>
<td>2.0</td>
</tr>
<tr>
<td><input type="checkbox" name="one" />3</td>
<td>包子</td>
<td>1.5</td>
</table>
<script>
var rows = document.getElementsByTagName("tr"); //通過標(biāo)簽名獲得元素對(duì)象
集合
for (var i = 0; i < rows.length; i++) {
if(i % 2 == 1){ // 奇數(shù)
rows[i].style.backgroundColor = "pink";
}
}
</script>
</body>
4.2 DOM修改
- 修改 HTML DOM 意味著許多不同的方面:
- 改變 HTML 內(nèi)容
- 改變 CSS 樣式
- 改變 HTML 屬性
- 創(chuàng)建新的 HTML 元素
- 刪除已有的 HTML 元素
- 改變事件(處理程序)
- 改變一個(gè) <h2> 元素的 HTML 內(nèi)容 :
<body>
<button onclick="test()">點(diǎn)我試試</button>
<script>
function test(){
document.getElementById("hello").innerHTML = "走哇,喝點(diǎn)去~沧侥!";
}
</script>
<h2 id="hello">你好可霎!</h2>
</body>
- 改變一個(gè)<h2>的 HTML 樣式
<body>
<button onclick="chou()">你瞅啥</button>
<script>
function chou(){
document.getElementById("hello").style.color = "red";
document.getElementById("hello").style.fontFamily = "華文彩云";
}
</script>
<h2 id="hello">你好!</h2>
</body>
4.2.1 添加節(jié)點(diǎn)
- 點(diǎn)擊按鈕宴杀,在頁面中創(chuàng)建一張圖片
<body>
<button onclick="add()">添加</button>
<div></div>
<script>
function add(){
var img = document.createElement("img"); // <img>
img.setAttribute("src","../lagou-html/img/cat.gif"); // <img
src="../lagou-html/img/cat.gif">
img.setAttribute("title","小貓咪"); // <img src="../lagouhtml/img/cat.gif" title="小貓咪">
img.setAttribute("id","cat"); // <img src="../lagouhtml/img/cat.gif" title="小貓咪" id="cat">
var divs = document.getElementsByTagName("div");
divs[0].appendChild(img);
}
</script>
</body>
4.2.2 刪除節(jié)點(diǎn)
- 點(diǎn)擊按鈕癣朗,把上面剛創(chuàng)建的圖片從頁面上刪除
<body>
<button onclick="add()">添加</button>
<button onclick="del()">刪除</button>
<div>
</div>
<script>
function add(){
。旺罢。旷余。略正卧。罩驻。。
}
function del(){
var img = document.getElementById("cat");
img.parentNode.removeChild(img); // 必須通過父節(jié)點(diǎn)砾跃,才能刪除子節(jié)點(diǎn)
}
</script>
</body>
4.2.3 替換節(jié)點(diǎn)
- 點(diǎn)擊按鈕节吮,把上面剛創(chuàng)建的圖片替換成另一張
<body>
<button onclick="add()">添加</button>
<button onclick="del()">刪除</button>
<button onclick="rep()">替換</button>
<div>
</div>
<script>
function add(){
透绩。壁熄。。略碳竟。草丧。。
}
function del(){
莹桅。昌执。。略诈泼。懂拾。。
}
function rep(){
var imgold = document.getElementById("cat");
// 通過修改元素的屬性铐达,做的替換
// img.setAttribute("src","../lagou-html/img/2.jpg");
var imgnew = document.createElement("img");
imgnew.setAttribute("src","../lagou-html/img/1.jpg");
imgold.parentNode.replaceChild( imgnew, imgold );
}
</script>
</body>
4.3 事件
- js捕獲某個(gè)動(dòng)作而做出的反饋
- HTML 事件的例子:
- 當(dāng)用戶點(diǎn)擊鼠標(biāo)時(shí)
- 當(dāng)網(wǎng)頁已加載時(shí)
- 當(dāng)圖片已加載時(shí)
- 當(dāng)鼠標(biāo)移動(dòng)到元素上時(shí)
- 當(dāng)輸入字段被改變時(shí)
- 當(dāng) HTML 表單被提交時(shí)
- 當(dāng)用戶觸發(fā)按鍵時(shí)
4.3.1 窗口事件 (Window Events)
- 僅在 body 和 frameset 元素中有效岖赋。
- onload 當(dāng)文檔被載入時(shí)執(zhí)行腳本
<body onload="test()">
<script>
function test() {
document.write("哈哈哈哈");
}
</script>
</body>
4.3.2 表單元素事件 (Form Element Events)
- 僅在表單元素中有效。
- onblur 當(dāng)元素失去焦點(diǎn)時(shí)執(zhí)行腳本
- onfocus 當(dāng)元素獲得焦點(diǎn)時(shí)執(zhí)行腳本
<body>
<script>
function a() {
console.log("獲得焦點(diǎn)==被激活");
}
function b() {
console.log("失去焦點(diǎn)");
}
</script>
<form action="">
<p>帳號(hào):<input onfocus="a()" onblur="b()" /></p>
<p>密碼:<input /></p>
</form>
</body>
4.3.3 鼠標(biāo)事件 (Mouse Events)
- onclick 當(dāng)鼠標(biāo)被單擊時(shí)執(zhí)行腳本
- ondblclick 當(dāng)鼠標(biāo)被雙擊時(shí)執(zhí)行腳本
- onmouseout 當(dāng)鼠標(biāo)指針移出某元素時(shí)執(zhí)行腳本
- onmouseover 當(dāng)鼠標(biāo)指針懸停于某元素之上時(shí)執(zhí)行腳本
<style>
img{
width: 30%;
border: 5px solid white;
}
</style>
<body>
<img src="img/logo.png" onmouseover="shang(this)" onmouseout="xia(this)"
onclick="dan()">
<img src="img/logo.png" onmouseover="shang(this)" onmouseout="xia(this)"
ondblclick="shuang()">
<img src="img/logo.png" onmouseover="shang(this)" onmouseout="xia(this)" >
<script>
function dan(){
alert("點(diǎn)了一下");
}
function shuang(){
alert("連續(xù)快讀點(diǎn)兩下");
}
function shang(img){
img.style.border = "5px solid red";
}
function xia(img){
img.style.border = "5px solid white";
}
</script>
</body>
4.3.4 鍵盤事件
- onkeydown 按下去
- onkeyup 彈上來
<script>
window.onkeydown = function(){
// event:事件源(按鍵)
// console.log( "按鍵編碼:"+event.keyCode );
if(event.keyCode == "13"){ // 回車鍵
alert("登錄成功瓮孙!");
}
}
window.onkeyup = function(){
console.log(event.keyCode); // 按住按鍵不松手是不會(huì)觸發(fā)的唐断。當(dāng)松手時(shí),按鍵回彈則
觸發(fā)
}
</script>
4.3.5 事件冒泡
- 創(chuàng)建兩個(gè)div衷畦,一個(gè)大一些栗涂,一個(gè)小一些
<style>
#father {
width: 200px;
height: 200px;
background: black;
padding: 10px;
}
#child {
width: 100px;
height: 100px;
background: greenyellow;
}
</style>
<body>
<div id="father">
<div id="child"></div>
</div>
<script>
// 代碼不重要,重要是知道這個(gè)事件發(fā)生祈争,是正辰锍蹋現(xiàn)象
document.getElementById("father").addEventListener("click", function() {
alert("父級(jí)元素的事件被觸發(fā):" + this.id);
});
document.getElementById("child").addEventListener("click", function(e) {
e.stopPropagation() //取消事件的冒泡機(jī)制
alert("子級(jí)元素的事件被觸發(fā):" + this.id);
});
</script>
</body>
- 先子,后父忿墅。事件的觸發(fā)順序自內(nèi)向外,這就是事件冒泡棍弄;
4.3.6 事件捕獲
- 還是剛才創(chuàng)建兩個(gè)div呼畸,一個(gè)大一些,一個(gè)小一些
<style>
#father {
width: 200px;
height: 200px;
background: black;
padding: 10px;
}
#child {
width: 100px;
height: 100px;
background: greenyellow;
}
</style>
<body>
<div id="father">
<div id="child"></div>
</div>
<script>
document.getElementById("father").addEventListener("click",function(){
alert("父級(jí):" + this.id);
},true);
document.getElementById("child").addEventListener("click",function(){
alert("子級(jí):" + this.id);
},true);
</script>
</body>
- 先父,后子花嘶。事件觸發(fā)順序變更為自外向內(nèi)椭员,這就是事件捕獲;
4.4 面向?qū)ο驩OP
- 使用Object創(chuàng)建通用對(duì)象
var user = new Object();
user.name = "呂布";
user.age = 21;
user.say = function(){
console.log("大家好,我叫:"+this.name+"蚜印,我今年"+this.age+"歲了!");
}
user.say();
var dog = new Object();
dog.nickname = "屎尿多";
dog.wang = function(){
console.log("我餓了忆绰,我要拆家了!");
}
dog.wang();
- 使用構(gòu)造函數(shù)
function userinfo(name , age){
this.name = name;
this.age = age;
this.say = function(){
console.log("大家好稚茅,我叫:"+this.name+",我今年"+this.age+"歲了欺税!");
}
}
var user = new userinfo("詹姆斯",35);
user.say();
- 使用直接量
var user = {
username : "孫悟空",
age : 527,
say : function(){
console.log("大家好,我叫:"+this.username+"晃虫,我今年"+this.age+"歲了扛吞!");
}
};
user.say();
4.5 JSON
- 大家在互聯(lián)網(wǎng)上來回傳遞數(shù)據(jù)滥比,如果沒有一個(gè)統(tǒng)一的格式,解析起來的難度很大(每個(gè)人的編碼喜好不一樣)
- JSON(JavaScript Object Notation) 是一種輕量級(jí)的數(shù)據(jù)交換格式寺滚。
- 易于人閱讀和編寫,同時(shí)也易于機(jī)器解析和生成
{
屬性1:值1蚁孔,
屬性2:值2,
鼻百。愕宋。。邻寿。
}
<script>
var json1 = { username: "呂布", age: 31 };
console.log("姓名:" + json1.username + ",年齡:" + json1.age + "歲");
// json數(shù)組
var josnarr = [{ name: "貂蟬", age: 18 }, { name: "小喬", age: 17 }];
console.log("貂蟬" + josnarr[0].age + "歲了");
console.log("小喬" + josnarr[1].age + "歲了");
// 復(fù)雜的json對(duì)象
var long = {
name: "趙云",
sex: "男",
hobby: ["玉蘭白龍駒", "龍膽亮銀槍", "青釭劍"]
};
console.log(long.name + "的主攻武器:" + long.hobby[1]);
</script>
5. BOM操作
- 就是javascript對(duì)瀏覽器的一些常規(guī)操作的方法
5.1 window對(duì)象
<button onclick="kai()">極速入職</button>
<script>
function kai(){
window.open("http://lagou.com" , "拉勾網(wǎng)" ,
"width=500,height=300,left=400");
// window.open("http://lagou.com" , "拉勾網(wǎng)" , "fullscreen=yes"); // IE才
生效
}
</script>
5.1.1 screen屏幕對(duì)象
- 我想知道我的電腦屏幕多大蒜撮?實(shí)際上取逾,得到的就是分辨率
<body>
<button onclick="kai()">求大小</button>
</body>
<script>
function kai() {
alert(window.screen.width + "|" + window.screen.height);
}
</script>
5.1.2 location定位
- 包含有關(guān)當(dāng)前 URL 的信息,通常用來做頁面跳轉(zhuǎn)
<button onclick="test()">測(cè)試</button>
<script>
function test(){
console.log( "當(dāng)前頁面的URL路徑地址:"+ location.href );
location.reload(); // 重新加載當(dāng)前頁面(刷新)
location.; // 跳轉(zhuǎn)頁面
}
</script>
5.1.3 history瀏覽器歷史
- history對(duì)象會(huì)記錄瀏覽器的痕跡
- a.html
<a href="b.html">去b頁面</a>
- b.html
<button onclick="hui()">返回</button>
<script>
function hui(){
//history.go(-1); //上一級(jí)頁面
history.back(); // 與go(-1)是等價(jià)的
}
</script>
5.1.4 navigator 導(dǎo)航(了解)
- window.navigator 對(duì)象包含有關(guān)訪問者瀏覽器的信息;
<script>
var str = "";
str += "<p>瀏覽器的代號(hào):"+ navigator.appCodeName +"</p>";
str += "<p>瀏覽器的名稱:"+ navigator.appName+"</p>";
str += "<p>瀏覽器的版本:"+ navigator.appVersion+"</p>";
str += "<p>硬件平臺(tái):"+ navigator.platform+"</p>";
str += "<p>用戶代理:"+ navigator.userAgent +"</p>";
str += "<p>啟用Cookies:"+navigator.cookieEnabled+"</p>";
document.write(str);
</script>
5.1.5 存儲(chǔ)對(duì)象
- 用起來和我們?cè)趈ava中map很相似,都是鍵值對(duì)的方式存數(shù)據(jù)
5.1.5.1 本地存儲(chǔ) localStorage
在關(guān)閉窗口或標(biāo)簽頁之后將會(huì)刪除這些數(shù)據(jù)
- 保存數(shù)據(jù)
localStorage.setItem("name","curry");
- 提取數(shù)據(jù)
localStorage.getItem("name");
- 刪除數(shù)據(jù)
localStorage.removeItem("name");
多樣化操作
// 三種方式保存數(shù)據(jù)
localStorage["a"] = 1;
localStorage.b = 2;
localStorage.setItem("c",3);
// 查看數(shù)據(jù)類型
console.log( typeof localStorage["a"] )
console.log( typeof localStorage["b"] )
console.log( typeof localStorage["c"] )
// 第一種方式讀取
var a = localStorage.a;
console.log(a);
// 第二種方式讀取
var b = localStorage["b"];
console.log(b);
// 第三種方式讀取
var c = localStorage.getItem("c");
console.log(c);
5.1.5.2 會(huì)話存儲(chǔ) sessionStorage
會(huì)話,就是保持瀏覽器別關(guān)閉晶丘。
關(guān)閉瀏覽就等于結(jié)束了一次會(huì)話。
開啟瀏覽器就意味著創(chuàng)建了一次會(huì)話捷枯。
- 保存數(shù)據(jù)
sessionStorage.setItem("name", "klay");
- 提取數(shù)據(jù)
var lastname = sessionStorage.getItem("name");
- 刪除指定鍵的數(shù)據(jù)
sessionStorage.removeItem("name");
- 刪除所有數(shù)據(jù)
sessionStorage.clear();
案例:記錄點(diǎn)擊了幾下按鈕
<button onclick="dian()">點(diǎn)我</button>
<h3 id="result"></h3>
<script>
function dian(){
if( sessionStorage.getItem("clickCount") ){
sessionStorage.setItem("clickCount",
Number(sessionStorage.getItem("clickCount")) + 1);
}else{
sessionStorage.setItem("clickCount", 1);
}
document.getElementById("result").innerHTML = "已經(jīng)點(diǎn)擊了"+
sessionStorage.getItem("clickCount") +"次!"
}
</script>
5.2 計(jì)時(shí)操作
5.2.1 周期性定時(shí)器 setInterval
setInterval(1,2):周期性觸發(fā)代碼exp (常用)
1:執(zhí)行語句
2:時(shí)間周期,單位為毫秒
- 案例:閃爍的字體 (1秒1變色)
<body>
<h1 id="title">拉勾網(wǎng):極速入職</h1>
<script>
var colors = ["red","blue","yellow","pink","orange","black"];
var i = 0;
function bian(){
document.getElementById("title").style.color = colors[i++];
if(i == colors.length){
i = 0; // 顏色重新開始
}
}
setInterval(bian,100); // 每隔0.1秒苟径,執(zhí)行一次bian函數(shù)
</script>
</body>
- 案例:在閃爍字體的基礎(chǔ)上擴(kuò)展棘街,閃爍的電子時(shí)鐘
<body>
<h1 id="title"></h1>
<script>
var colors = ["red","blue","yellow","pink","orange","black"];
var i = 0;
function bian(){
document.getElementById("title").style.color = colors[i++];
if(i == colors.length){
i = 0; // 顏色重新開始
}
}
function time(){
var d = new Date();
var str = d.getFullYear()+"年"+(d.getMonth()+1)+"月"+d.getDate()+"號(hào)
"+d.getHours()+"點(diǎn)"+d.getMinutes()+"分"+d.getSeconds()+"秒";
document.getElementById("title").innerHTML = str;
}
setInterval(bian,100); // 每隔1秒博助,執(zhí)行一次變色函數(shù)bian
setInterval(time,1000); // 每隔1秒富岳,執(zhí)行一次時(shí)間函數(shù)time
</script>
</body>
5.2.2 停止定時(shí)器 clearInterval
- 案例:模擬年會(huì)抽獎(jiǎng)
<body>
<img id="tu" src="../lagou-html/img/1.jpg" width="50%" />
<br />
<button onclick="begin()">開始</button>
<button onclick="stop()">停止</button>
<script>
var arr = ["1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg"];
function begin() {
timer = setInterval(bian, 100); // 沒有使用var疾瓮,所以timer是全局變量
}
function stop() {
clearInterval(timer); // 停止定時(shí)器
}
function bian() {
var i = Math.floor(Math.random() * arr.length); // 0-4
document.getElementById("tu").src = "../lagou-html/img/" + arr[i];
}
</script>
</body>
5.2.3 一次性定時(shí)器 setTimeout
- 相當(dāng)于延遲的效果狼电,只執(zhí)行一次
<script>
function bian(){
document.body.style.backgroundColor = "red";
}
//3秒之后調(diào)用
setTimeout(bian,3000);
</script>