個人自學前端10-JS3
DOM操作和表示式
一 DOM操作入門
DOM操作包含兩部分基本操作:
1:獲取標籤(元素)(節點)
2:運算元標籤(元素)(節點)
1.1 獲取元素
html標籤在DOM中用 js 標籤物件來表示。(標籤都是js物件)
js 標籤物件有很多預設的屬性,不同屬性有不同作用。
獲取方法:
// 通過id獲取元素(只獲取一個) let oDiv = document.getElementById(元素id); // 通過標籤名獲取元素(獲取一堆) let aDiv = document.getElementsByTagName(元素標籤名); // 通過類名獲取元素(獲取一堆) let aDiv = document.getElementsByClassName(元素類名); // 通過選擇器獲取元素(只獲取一個) let oDiv = document.querySelector(選擇器); // 通過選擇器獲取元素(獲取一堆) let aDiv = document.querySelectorAll(選擇器);
如果標籤不在頁面中,則返回null。
1.2 操作元素
js 可以操作html標籤的內容和屬性。
js 不能操作html標籤的樣式,只能操作html標籤的style屬性。
js 獲取到的任何關於html標籤的資料,都是字串!(html標籤的內容,屬性,樣式都是字串!)
1.2.1 操作元素內容
兩個方法:
// 獲取元素內容
console.log(oDiv.innerText);
console.log(oDiv.innerHTML);
// 設定元素內容
oDiv.innerText = 新的內容;
oDiv.innerHTML = 新的內容;
其中:
innerHTML可以獲取html標籤內容,並且可以實現插入新標籤。
innerText只能獲取和操作文字內容。
1.2.2 操作元素行間樣式
html標籤是一個 js 物件, html標籤的style屬性也是一個 js 物件。style物件是標籤物件的一個屬性。
// 獲取行間width樣式
console.log(oDiv.style.width)
// 設定width屬性。
oDiv.style.width = '100px';
// 如果樣式名帶-,需要寫成駝峰形式
oDiv.style.marginLeft = '100px';
js 只能獲取行間樣式和操作行間樣式,不能獲取和操作內部樣式和外部樣式。
js 只能獲取最終樣式。不能設定
// 獲取優先順序最高的那個width樣式 (最終的width樣式)
getComputedStyle(oDiv).width
1.2.3 操作元素屬性
html標籤的屬性可以在對應的 js 物件中通過 js 物件屬性獲取。(html標籤屬性和 js 物件屬性不要混為一談)
因此,給 js 標籤物件新增新屬性,html標籤並不會多出新的屬性。
同樣,刪除 js 標籤物件的屬性,html標籤並不會刪除對應屬性。
js 標籤物件預設擁有的屬性是html標籤的全域性屬性,事件屬性和可選屬性。
因此通過 js 我們也可以操作html標籤的全域性屬性,事件屬性和可選屬性。
// 獲取對應的html標籤屬性。class屬性需要寫成className
console.log(oDiv.id);
console.log(oText.value);
console.log(oText.className);
// 設定元素的id屬性
oDiv.id = 'wrap';
oText.value = '你好嗎';
oText.className = 'active';
標籤的布林屬性,用 js 獲取,得到的就是布林屬性。例如checked,mutiple,disabled屬性
// 獲取複選框的checked屬性,得到的值就是true或者false
console.log(oCheckbox.checked)// true或者false
// 通過設定checked屬性可以控制複選框的勾選狀態
oCheckbox.checked = true
// 禁用oBtn
oBtn.disabled = true
標籤的自定義屬性預設在對應 js 標籤物件上沒有,因此不能通過操作 js 標籤物件來操作html標籤的自定義屬性。
可以通過標籤物件的getAttribute方法來獲取自定義屬性。
可以通過標籤物件的setAttribute方法來設定自定義屬性。
// 獲取abc自定義屬性。
oDiv.getAttribute('abc');
// 把abc自定義屬性設定為wwww。
oDiv.setAttribute('abc','wwww');
1.2.4 新增事件
什麼是事件?
特定情況下,傳送的事情,例如下雨了,下課了。
事件發生後會有對應的事件現象。例如,下雨了,大家都會撐傘,下課了,大家都去吃飯。
標籤也有對應的事件,例如,按鈕被點選了。這裡點選就是一個事件。
如果點選按鈕,需要產生某些效果,則需要通過事件屬性來新增程式碼實現需要的效果。
通過操作 js 標籤物件的事件屬性,可以給標籤新增事件。事件需要實現的效果需要需要寫在函式內。
// 給按鈕新增點選事件,事件發生產生的效果寫在函式內。
// 點選按鈕,彈出100
oBtn.onclick = function(){
alert(1000)
}
// 或者
oBtn.onclick = show;
function show(){
alert(1000)
}
常見事件(注意事件沒有駝峰):
onclick。(點選事件)
onmouseover,onmouseout。(滑鼠移入移出事件)
onmouseenter,onmouseleave。(滑鼠移入移出事件)
onblur,onfocus (失去獲得焦點事件)
onchange (value改變事件)
oninput (正在輸入事件)
onmousedown,onmouseup (滑鼠按下鬆開事件)
onkeydown,onkeyup (鍵盤按下鬆開事件)
事件產生的效果,為什麼要寫在函式內?
我們知道,js的執行是發生在html文件的解析階段的,而事件需要實現的效果是發生在html文件渲染之後的,
如何讓某些程式碼在html文件在渲染之後才執行呢?通過函式就可以。
**函式可以決定某些程式碼什麼時候執行,這是函式的一個顯著特徵。
二:操作符(運算子)
程式中需要對資料進行各種運算,以得到計算後的結果。
計算有很多種型別,不同計算方式需要使用不同的操作符。
注意,這裡的計算不限於傳統的數學計算,實際上數學運算只是程式設計運算中的一小部分。
常見運算子:
1:算術運算子
2:比較運算子
3:邏輯運算子
4:三目運算子(條件運算子,三元運算子)
5:其他運算子
運算元:用於計算的資料叫運算子的運算元。
根據運算元的不同個數,還可以把運算子分為:
1:單目運算子
2:雙目運算子
3:三目運算子
大多數的運算子都是雙目運算子,小部分是單目運算子,三目運算子只有一個。
三:表示式
程式設計本質上都是在處理資料和資料邏輯。
那程式是如何表示資料的?程式中的資料都是怎麼獲得的?
程式中的所有資料都是通過表示式獲得的。表示式是程式中最基本的組成單元。
任何的資料,程式都是通過表示式來獲取或者表示的。
表示式分類:
1:原始表示式
單個常量和單個變數。
如果是object型別的常量,一般叫直接量,也可以看作原始表示式。
物件的屬性訪問和陣列的元素訪問,也可以看作原始表示式。
2:計算表示式
運算元 + 操作符構成的表示式。
運算元本身是資料,因此運算元本身也可以通過任意的表示式來提供。
// 1+1 => 這是兩個常量1和運算子 + 構成的表示式。
// 第一個運算元1同時也可以通過表示式0.5+0.5來提供,寫成 (0.5+0.5)+1
3:函式呼叫表示式
函式呼叫也可以提供資料,構成函式呼叫表示式。
// Math.random() => 這是函式呼叫表示式,它和其他表示式一樣提供一個結果,賦值給變數res
let res = Math.random();
表示式的返回值:
表示式經過計算得到的結果就是表示式的返回值。
表示式一定有返回值。
// 1+1 計算的結果是2,因此我們說表示式 1+1的返回值是2
// 以下程式碼的意義為:把1+1的返回值賦值給變數x。
let x = 1+1;
// 以下程式碼的意義為:把Math.random()的返回值賦值給變數res
let res = Math.random();
操作符和表示式
一:算術運算子
小學就學過的是:+,-,*,/,計算順序也是先乘除,後加減。
1.1.1:取餘(取模):%
取餘運算子,求兩個運算元的餘數。
// 4/2 => 求商,得2
// 4%2 => 求餘數,因為可以整除,餘數為0,因此計算得0
// 2%4 => 求餘得2.
// 3%5 => 求餘得3.
// 0%5 => 求餘得0.
// 結論:如果較小的數取餘較大的數,結果是較小的數
1.1.2:++
自增。單目運算子。分為前自增和後自增。計算後變數的值+1。只能操作變數。是一種語法糖。
let x = 10;
// 前自增
++x;
// 後自增
x++;
// 不管是前自增還是後自增,x的值經過計算後都+1
前自增和後自增在進行賦值時會有區別。
let x = 10;
// 如果是後自增。y的值是10.x的值是11
let y = x++;
// 如果是前自增,y的值是11.x的值是11
let y = ++x;
// 為什麼會這樣?
//let y = x++;可以用完整的賦值邏輯表示如下:
// 先把x賦值給y
let y = x;
// 再把x加1
x = x + 1;
// y = ++x;可以用完整的賦值邏輯表示如下:
// 先把x加1
x = x + 1;
// 再把x賦值給y
let y = x;
總結:前置++,計算結果是+1之後的值。後置++,計算結果是+1之前的值。
難點:區分x++,++x和x的區別。
二:比較運算子
初中就學過的:>,<,>=,<=
布林值:一種JavaScript的資料型別,表示真假,對錯,有無。
比較運算子計算得到的結果都是布林值。
1.2.1 值等 ==
判斷兩個數是否相等,用的是 == ,注意 = 是賦值,不是判斷相等。
如果兩個運算元都是object型別。則比較的是兩個物件是否是同一個物件。
// 比較兩個數字的值是否相等
let x = 10;
let y = 20;
console.log(x == y);//false
// 比較兩個物件是否是同一個物件。
let obj1 = {};
let obj2 = {};
console.log(obj1 == obj2);//false
1.2.2 全等 ===
判斷兩個數的值和型別是否全等。值和資料型別必須都一致才會返回true
let x = 1;
let str = '1';
console.log(x == str);// true
// x的資料型別是number,str的資料型別是string,型別不一樣。因此是false。
console.log(x === str);// false
1.2.3 值不等 !=
判斷兩個資料的值是否相等。
let x = 10;
let y = 20;
console.log(x != y);//true
1.2.4 值不等或者型別不等 !==
判斷兩個資料的值不等或者型別不等,只要有一個不等,都返回true,如果全部相等返回false
let x = 2;
let str = '2';
// 值等,因此是false
console.log(x != str);// false
// 值等,但是型別不等
console.log(x !== str);// true
let x = 2;
let y = 2;
// 值和型別都相等。
console.log(x !== y);// false
三:判斷
判斷不是表示式,是控制結構中的一種。讓我們可以實現類似如果....否則....這樣的程式邏輯。
語法:
if(條件){
條件為真需要做的事
}else{
條件為假需要做的事
}
其中條件可以由任何表示式提供。
當這個表示式的返回值是true時執行第一個程式碼塊。
當返回值是false時,執行第二個程式碼塊。
幾種拓展的表現形式:
1:只有如果,沒有否則
if(條件){
條件為真做的事情
}
// 這種寫法可以省略{},但是極度不推薦
2:有很多的條件判斷
if(條件1){
條件1為真做的事情
}else if(條件2){
條件2為真做的事情
}
.........
else{
所有條件都為假時做的事情。
}
// 這種寫法,如果多個條件同時為真,則只執行第一個真條件匹配的程式碼段,其他的程式碼段不執行
3:switch判斷
switch判斷有時候可以簡化多個 if.else if的判斷書寫。
// 類似以下的判斷形勢可以用switch代替
if(變數 == 值1){
相等時做的事情
}else if(變數 == 值2){
相等時做的事情
}
.........
else{
所有值都不等時做的事情。
}
// 以下寫法,break不能省略,它可以防止多個值都為真時錯誤的執行多個語句
// default 的作用類似於最後一個else。
switch(變數){
case 值1:
變數等於值1時做的事情;
break;
case 值2:
變數等於值2時做的事情;
break;
........
default:
所有值都不等時做的事情。
}
四:隱式轉換
1.1 轉換現象
很多時候,運算元的資料型別是有規定的。
比如,算術運算子的運算元的資料型別必須是數字,因為不是數字無法計算。
但是,js在書寫上卻允許不是數字的資料進行算術運算。
因為js是弱型別的程式語言,對資料型別不敏感,在需要的時候會自動進行型別轉換。
console.log('1' * 2 );//結果是2
// '1' * 2 => 第一個運算元是字串 '1',不是數字,因此理論上不會進行相乘計算。
// 為了讓以上運算正常執行,js自動把字串 '1'轉換成了數字1.實際進行的計算是 1*2
另外,比較運算子的運算元也應該是數字,如果不是,js會自動轉換為數字在進行比較運算。
console.log('1' < 2);// 結果是true
// 理論上字串 '1' 是不能和數字2進行比較大小的,為了讓運算完成,js會自動把'1'轉換成數字1以後再比較。
判斷語句的判斷條件的值應該是布林值,如果不是,js會自動轉換條件的值為布林值,然後再判斷
// 100是數字,不是布林值,為了讓判斷執行,js會把100轉換為布林值true,然後再進行判斷
if(100){
console.log('100是true')
}
100轉換為布林值為什麼是true,為什麼不是false?什麼東西轉換為布林值是false?
重點: js的世界中,只有5種常量轉換為布林值是false,其餘都是true;
這5個值是:NaN,0,'' (空字串),undefined,null。
在js的世界中,隱式轉換無處不在。再比如,alert(),括號內的值應該是字串,如果不是,js會自動轉換為字串.
// window是物件,不是字串,因此js自動把window轉換成了字串[Object object]
alert(window);// [Object object]
1.2 顯示轉換
對應的資料型別的轉換方法:
1:把任意值轉換為number型別 Number (待轉換的值)
2:把任意值轉換為string型別 String (待轉換的值)(還有很多)
3:把任意值轉換為boolean型別 Boolean (待轉換的值)
不存在把其他值轉換為物件的方法。因為萬物皆物件。
1.3 轉換規律
1:算術運算子
預設會把不是數字的運算元隱式轉換為number型別。
例外:
如果是 + 操作符,如果有一個運算元是字串,則把另一個運算元隱式轉換為字串,
然後進行字串拼接操作。
'1' + 1 => 結果是'11',而不是2
2:比較運算子
預設會把不是數字的運算元隱式轉換為number型別。
例外:
如果是 == 操作符,如果比較的兩個操作都是物件,則比較兩個物件是不是同一個物件,而不會進行隱式轉換。
3:判斷條件
預設會把判斷()內的值轉換為布林值。沒有例外。
會轉換為布林值的5個常量:NaN,0,空字串,undefined,null
1.4 程式設計經驗
利用隱式轉換轉換字串為數字。
'2'+3 因為js預設會把3轉換為 '3',因此結果是'23',如果我們希望結果是5,則需要把 '2'轉換為數字,再+3
可以這樣做:'2'*1+3
這樣先計算'2'*1,這樣js會把'2'轉換為2,乘1得2,再+3得5
利用隱式轉換轉換其他值為字串。
true + 2 因為js預設會把true轉換為數字1,因此結果是3,如果我們希望結果是true2,則需要把true轉換為字串
可以這樣做:true+''+2
這樣先計算true+'',js會把true隱式轉換為'true',再+2,得'true2'