目錄
## 一、時間對象
1. 創建一個原生的時間對象, 對象身上各種的屬性和方法
```javascript
var date = new Date(); // 當前時間
console.log(typeof date); // object
```
2. 獲取本地狀態時間
```javascript
// 本地狀態時間
console.log(date.toLocaleString()); // 2020/5/6 下午2:48:01
console.log(date.toLocaleDateString()); // 2020/5/6
console.log(date.toLocaleTimeString()); // 下午2:49:12
```
3. 單個時間
```javascript
var date = new Date();
// 獲取單個時間
console.log(date.getFullYear()); // 年
console.log(date.getMonth()); // 月 從0開始, 0-11表示1-12月
console.log(date.getDate()); // 日
console.log(date.getDay()); // 星期, 從0開始, 0->星期日, 1-6代表週一-->週六
var week = ['星期日','星期一','星期二','星期三','星期四','星期五','星期六' ];
console.log(week[date.getDay()]);
console.log(date.getHours()); // 小時 14
console.log(date.getMinutes()); // 分鐘
console.log(date.getSeconds()); // 秒
console.log(date.getTime()); // 毫秒數 時間戳 距1970.1.1
```
## 二、創建時間
1. 單獨創建
```javascript
// 創建時間
var date = new Date(); // 當前時間
// 創建未來時間
// 單獨設置 所有get的方法除了getDay, 其他的都有set方法
console.log(date);
date.setFullYear(2021);
date.setMonth(10); // 0-11 多餘11時, 減去12然後顯示剩餘月份對應的月份
date.setDate(20);
date.setHours(20);
date.setMinutes(20);
date.setSeconds(20);
console.log(date);
```
2. 字符串創建
```javascript
// 創建未來時間對象
// var date = new Date(年, 月, 日, 時, 分, 秒); 全部都是number類型
// var date = new Date(2020, 11, 12, 12, 12, 12);
// var date = new Date(2020, 11, 12); // Sat Dec 12 2020 00:00:00 GMT+0800 (中國標準時間)
// var date = new Date(時間字符串); '年/月/日 hh:mm:ss';
// var date = new Date('2020 12 12 12:12:12');
// var date = new Date('2020/12/12 12:12:12');
// var date = new Date('2020-12-12 12:12:12');
// var date = new Date('2020,12,12 12:12:12');
// var date = new Date('2020,12,12'); // Sat Dec 12 2020 00:00:00 GMT+0800 (中國標準時間)
var date = new Date('2020-12-12'); // Sat Dec 12 2020 08:00:00 GMT+0800 (中國標準時間)
console.log(date);
```
3. 獲取時間戳: Date.parse(字符串格式化時間);
```javascript
// Date.parse(字符串格式化時間) 得到時間戳
console.log(Date.parse('2020-12-12 00:00:00')); // 1607702400000
```
## 三、moment
1. 獲取特定格式時間
1. YYYY--年
2. MM--月
3. DD--日
4. HH--時
5. mm--分
6. ss--秒
```javascript
console.log(date.format('YYYY年MM月DD日 HH:mm:ss'));
console.log(date.format('YYYY年MM月DD日'));
console.log(date.format('HH:mm:ss'));
console.log(date.format('YYYY-MM-DD'));
console.log(date.format('HH:mm:ss YYYY/MM/DD'));
console.log(date.format('YYYY/MM/DD HH:mm:ss'));
console.log(date.format('YYYY HH:mm:ss'));
console.log(date.format('YYYY')); // 四個數字完整的年份
console.log(date.format('MM')); // 表示月份, 有前導0 01-12
console.log(date.format('DD')); // 表示日期, 有前導0 01-31
console.log(date.format('d')); // 星期中的第幾天, 0-6,0--周天 6---週六
console.log(date.format('HH')); // 小時, 前導0, 00-23
console.log(date.format('mm')); // 分鐘, 00 - 59
console.log(date.format('ss')); // 秒, 00 - 59
console.log(date.format('X')); // 只含秒的時間戳
```
2. 轉成原生時間對象: moment().toDate();
3. 得到時間戳: moment().valueOf();
4. 單獨時間的獲取和設置: 加前導0
```javascript
var date = moment();
console.log(date);
// 讀取
console.log(date.year());
// 設置
date.year(2022);
date.set('year', 2023);
date.set({'year': 2024});
// 設置月
date.month(3); // 0-11
date.set('month', 4);
date.set({'month': 5});
// 獲取
console.log(date.month()); // 0-11表示1-12
// 類似
console.log(date.day()); // 星期幾
console.log(date.date()); // 日, 這個月的第幾天
console.log(date.hour()); // 小時
console.log(date.minute()); // 分鐘
console.log(date.second()); // 秒
console.log(date.week()); // 一年中的第幾周
console.log(date.dayOfYear()); // 一年中的第幾天
console.log(date.quarter()); // 一年中的第幾個季度
console.log(date.daysInMonth()); // 日期所在的月份有多少天
console.log(date);
```
5. 判斷時間方法
1. 早於 moment(時間1).isBefore(時間2字符串); 判斷時間1是否早於時間2, 返回true/false
```javascript
console.log(moment().isBefore('2020-05-08')); // true
console.log(moment('2020-05-08').isBefore('2020-05-07')); // false
console.log(moment('2020-06-22').isBefore('2020-07-30', 'year')); // false
console.log(moment('2019-06-22').isBefore('2020-07-30', 'year')); // true
console.log(moment('2019-06-22').isBefore('2020-06-30', 'month')); // true
```
2. 晚於 moment(時間1).isAfter(時間2); 判斷時間1是否晚於時間2
```javascript
console.log(moment('2020-05-08').isAfter('2020-05-07')); // true
console.log(moment('2020-06-22').isAfter('2020-07-30', 'year')); // false
console.log(moment('2019-06-22').isAfter('2020-07-30', 'year')); // false
console.log(moment('2019-06-22').isAfter('2020-06-30', 'month')); // false
```
3. 相等 moment(時間1).isSame(時間2); 判斷時間是否相等
```javascript
console.log(moment().isSame('2020-05-07')); // false
console.log(moment().isSame('2020-06-07', 'year')); // true
console.log(moment().isSame('2019-05-07', 'month')); // false, 判斷月份是否相等, 年份必須相同; 是否是同一個年份、月份、日期、小時。。。。
```
4. 兩者之間 moment(時間1).isBetween(時間2, 時間3); 判斷時間1是否在時間2與時間3之間
```javascript
console.log(moment().isBetween('2019-12-01', '2020-12-01')); // true
console.log(moment().isBetween('2019-12-01', '2020-12-01', 'year')); // false
console.log(moment().isBetween('2019-12-01', '2021-12-01', 'year')); // true
console.log(moment().isBetween('2020-05-07 14:00:00', '2020-05-07 23:59:59', 'hour')); // true
```
5. 判斷是否是閏年
```javascript
console.log(moment().isLeapYear()); // true
console.log(moment('2021-12-31').isLeapYear()); // false
```
6. 當前時間的毫秒數
```javascript
console.log(Date.now());
console.log(moment().format('X')); // 當前時間的秒數
```
## 四、字符串
1. 單雙引號包裹的就是字符串
2. 長度: .length
3. charAt(): 指定下標的字符
4. 強制轉換: String() .toString()
5. 查找字符
* indexOf: 字符串.indexOf(要查找的字符, [從哪裏開始查找]);
如果找到第一個, 結束查找並返回其第一個的下標
如果找不到, 返回-1
```javascript
var str = 'abcdefghijklmnf';
// 字符串.indexOf(要查找的字符, [從哪裏開始查找]);
// 如果找到第一個, 結束查找並返回其第一個的下標
// 如果找不到, 返回-1
console.log(str.indexOf('f')); // 5 表示從左到右, 從0開始查找
console.log(str.indexOf('f', 6)); // 14 表示從左到右, 從下標6的位置開始查找
console.log(str.indexOf('z'));
```
* lastIndexOf: 字符串.lastIndexOf(要查找的字符, [從哪裏開始查找]); 從右向左查找
```javascript
// 字符串.lastIndexOf(要查找的字符, [從哪裏開始查找]); 從右向左查找
console.log(str.lastIndexOf('f')); // 14 表示從右向左查找,從最後一個下標開始往前查找
console.log(str.lastIndexOf('f', 10)); // 5
console.log(str.lastIndexOf('z')); // -1
```
6. 截取
1. substring: 字符串.substring([起始位置, 結束位置]);
+ 如果沒有參數, 返回整個字符串
+ 傳一個參數, 表示從開始位置截取到整個字符串的結束爲止
+ 傳2個參數, 表示從開始位置截取到結束位置的前一個
+ 如果第一個參數大於第二個參數, 將兩個參數位置互換再截取
+ 如果參數爲負數, 將負數轉成0之後, 在按照上面的規則進行截取
```javascript
// 包含起始位置, 不包含結束位置
var str = 'abcdefghijklmnopqrst';
console.log(str.substring()); // 如果沒有參數, 返回整個字符串
console.log(str.substring(2)); // 傳一個參數, 表示從開始位置截取到整個字符串的結束爲止
console.log(str.substring(30)); // 空字符
console.log(str.substring(2, 4)); // cd 傳2個參數, 表示從開始位置截取到結束位置的前一個
console.log(str.substring(8, 2)); // cdefgh 如果第一個參數大於第二個參數, 將兩個參數位置互換再截取
console.log(str.substring(8, -1)); // abcdefgh 如果參數爲負數, 將負數轉成0之後, 在按照上面的規則進行截取
```
2. slice: 字符串.slice([起始下標, 結束下標]);
- 沒有參數, 返回整個字符串
- 一個參數, 返回起始下標的字符到整個字符串的結束字符爲止
- 兩個參數, 返回起始下標的字符到結束下標的前一位字符爲止(包含起始下標, 不包含結束下標);
- 起始下標大於結束下標, 返回空字符
- 如果參數爲負數, 表示從後往前數幾位,然後做截取
```javascript
// 字符串.slice([起始下標, 結束下標]);
// []--->表示其中的參數可選項
console.log(str.slice()); // 沒有參數, 返回整個字符串
console.log(str.slice(2)); // 一個參數, 返回起始下標的字符到整個字符串的結束字符爲止
console.log(str.slice(2,4)); // 兩個參數, 返回起始下標的字符到結束下標的前一位字符爲止(包含起始下標, 不包含結束下標);
console.log(str.slice(8, 2)); // 起始下標大於結束下標, 返回空字符
console.log(str.slice(8, -3)); // 如果參數爲負數, 表示從後往前數幾位,然後做截取
console.log(str.slice(-1, -10)); // 起始下標大於結束下標, 返回空字符
console.log(str.slice(-10, -1)); // klmnopqrs
```
3. substr: 字符串.substr([要截取的起始下標, 截取字符串的長度])
+ 沒有參數, 返回整個字符串
+ 從起始下標位置開始, 截取到整個字符串的結束爲止
+ 從起始下標開始, 截取長度爲幾的字符
+ 截取字符長度爲負數, 返回空字符串
+ 起始下標爲負數,從右往左數幾位開始截取
```javascript
// 字符串.substr(要截取的起始下標, 截取字符串的長度)
console.log(str.substr(5,3)); // 從起始下標開始, 截取長度爲幾的字符
console.log(str.substr(5)); // 從起始下標位置開始, 截取到整個字符串的結束爲止
console.log(str.substr()); // 沒有參數, 返回整個字符串
console.log(str.substr(10, 20));
console.log(str.substr(5, -1)); // 空字符
console.log(str.substr(-10, 3)); // 起始下標爲負數,從右往左數幾位開始截取
```
7. 轉大小寫:
1. 轉小寫: 字符串.toLowerCase();
2. 轉大寫: 字符串.toUpperCase();
```javascript
var str = 'FGFHAahhsjaSDgwADF';
// 轉小寫: 字符串.toLowerCase();
console.log(str.toLowerCase()); // fgfhaahhsjasdgwadf
// 轉大寫: 字符串.toUpperCase();
console.log(str.toUpperCase()); // FGFHAAHHSJASDGWADF
// 驗證碼、驗證字符正確與否、封裝函數
```
8. 將字符串分割成數組
字符串.split('分割符'); 可以是一切字符
```javascript
var str = '優學習字符串分割成數組';
console.log(str.split(','));
console.log(str.split('一'));
console.log(str.split('')); // 每個字符會被拆成一項
console.log(str.split('優')); // 2項
```
9. 將數組拼接成字符串
數組.join('連接符'); 可以是一切字符
```javascript
var arr = [1,2,3,4,5];
console.log(arr.join(',')); // 1,2,3,4,5
console.log(arr.join('123')); // 11232123312341235
console.log(arr.join('')); // 12345
```
10. 替換: 字符串.replace(要替換掉的字符, 要替換進來的字符);
注意: 一次只能替換一個位置的字符
```javascript
var str = '今天是個好日子, 今天是個週四, 今天之後在上兩天課就放假了';
// 替換字符: 字符串.replace(要替換掉的字符, 要替換進來的字符);
// 一次只能替換一個位置的字符
console.log(str.replace('今天', '5月7號'));
```
## 五、數組
### 1、數組的概念和創建
1. 概念: 數組是值得有序的集合, 每一個值叫元素, 下標叫做索引
2. 作用: 可以用來存儲不定數量不定類型的數據
3. 創建方式:
1. 字面量創建: 將數組的項放在[]中, 可以直觀地看到
2. 構造函數創建
注意: 如果構造函數中傳一個參數並且這個參數是數字時, 表示的是創建出來的數組的長度, 每一項存儲爲empty, 獲取得到的undefined
```javascript
// 1. 字面量創建
var arr = [2,3,4,5];
var arr1 = [];
// 2. 構造函數創建
var arr2 = new Array();
console.log(arr2);
var arr3 = new Array(1,2,3,4);
console.log(arr3);
var arr4 = new Array(5);
console.log(arr4);
console.log(arr4[2]);
```
### 2、數組棧方法四個
1. 向數組後面添加一位或者是多位元素, 返回新數組的長度
數組.push(項1, 項2, ...., 項n);
2. 從數組末尾刪除一項, 返回被刪除的元素, 爲了方便後續去使用
數組.pop();
3. 向數組首位添加一位或者是多位元素, 返回新數組的長度
數組.unshift(項1, 項2, ...., 項n);
4. 從數組首位刪除一項, 返回被刪除的元素
數組.shift();
```javascript
var len = arr.push('大喬', '羋月', '百里守約');
console.log(arr);
console.log(len);
var a1 = arr.pop();
console.log(arr);
console.log(a1);
var len2 = arr.unshift('莊周', '米萊迪');
console.log(arr);
console.log(len2);
var a2 = arr.shift();
console.log(arr);
console.log(a2);
```
### 3、splice
萬能的splice: 添加、刪除、替換
數組.splice(起始下標, 刪除的個數, 項1, 項2, 項3.....);
注意: 返回刪除掉的項組成的數組, 如果沒有刪除, 返回一個空數組
```javascript
var arr = ['小喬', '大喬', '亞瑟', '呂布', '貂蟬'];
// 刪除
var a2 = arr.splice(3, 2);
console.log(arr);
console.log(a2);
// 添加: 不需要刪除, 刪除個數爲0
// 如果起始位置大於數組長度, 直接添加在數組的末尾
arr.splice(1, 0, '亞索', '女槍', '李白');
console.log(arr);
// 替換: 添加幾個就刪除幾個
arr.splice(1, 2, '米萊迪', '韓信');
console.log(arr);
```
### 4、排序
1. 選擇排序
1. 拿數組的每一項和後面的每一項進行比較, 如果後面的比前面的小, 互換位置
```javascript
var arr = [1,2,3,4,1,2,3,4,12,4,46,54,2];
for(var i = 0; i < arr.length; i++){
for(var j = i + 1; j < arr.length; j++){
if(arr[i] > arr[j]){
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
console.log(arr);
```
2. 冒泡排序
1. 相鄰的兩項依次進行比較, 如果後面的小於前面的就互換位置
```javascript
for(var i = 0; i < arr1.length; i++){ // 循環次數
for(var j = 0; j < arr1.length - i; j++){ // 每次循環的排序
if(arr1[j] > arr1[j+1]){
var temp = arr1[j];
arr1[j] = arr1[j+1];
arr1[j+1] = temp;
}
}
}
console.log(arr1);
```
3. sort方法
1. 數組.sort([參數]); 直接對原數組進行排序
2. 沒有參數: 默認按照從小到大的順序排序, 默認按照字符串的順序排序
3. 有參數:參數是一個函數, 函數有2個形參,
設置返回值時:
第一個形參-第二個形參, 按照從小到大
第二個形參-第一個形參, 按照從大到小
```javascript
var arr = [1, 3, 2, 4, 2, 5, 6, 11, 12, 22];
console.log(arr.sort());
arr.sort(function(x, y){
return y - x;
// return x - y;
});
console.log(arr);
```
### 5、其他方法
1. join: 數組.join('拼接符');
2. reverse: 數組.reverse(); 將數組翻轉
注意: 改變原數組
```javascript
arr.reverse();
console.log(arr);
```
3. concat: 數組a.concat(b, c, d, 項1, .., 項2);
將數組b拼接到數組a上, 返回拼接以後的新數組, 原數組不會改變
```javascript
var arr = [1, 2, 3];
var b = [4, 5, 6];
var m = arr.concat(b, '猜一猜', b);
console.log(m);
console.log(arr, b);
```
4. indexOf: 數組.indexOf(要查找的項, [起始下標]); 從左往右查找, 找得到的時候返回第一個找到的下標, 找不到返回-1
注意: 查找的項與數組中的項必須完全一致(全等)
ie8及以下不支持
5. lastIndexOf: 數組.lastIndexOf(要查找的項, [起始下標]); 從右向左查找, 找得到的時候返回第一個找到的下標, 找不到返回-1\
```javascript
// [1, 2, 3, 4, 5, 6, "猜一猜", 4, 5, 6]
console.log(m.indexOf(1)); // 0
console.log(m.indexOf('4')); // -1
// lastIndexOf: 數組.lastIndexOf(要查找的項, [起始下標]); 從右向左查找, 找得到的時候返回第一個找到的下標, 找不到返回-1
console.log(m.lastIndexOf(4)); // 7
console.log(m.lastIndexOf(4, 6)); // 3
```
### 6、迭代方法
1. every: 針對數組的每一項做一些判斷, 如果所有的項判斷的結果都爲true, 返回的結果就是true, 如果有一個爲false, 返回結果就爲false
語法: 數組.every(function(value, index, array){
value: 數組的每一項 index:索引 array: 數組本身
});
```javascript
var s = arr.every(function(value, index, array){
console.log(value, index, array);
return value >= 1;
});
console.log(s);
```
2. some: 針對數組的每一項做一些判斷, 如果所有的項判斷的結果都爲false, 返回的結果就是false, 如果有一個爲true, 返回結果就爲true
語法: 數組.some(function(value, index, array){
value: 數組的每一項 index:索引 array: 數組本身
});
```javascript
var m = arr.some(function(value, index, array){
console.log(value, index, array);
return value >= 15;
});
console.log(m);
```
3. filter: 針對數組中的元素去做一些判斷, 滿足條件的元素挑選出來, 組成一個新數組並且返回回來
數組.filter(function(value, index){
value: 每一項 index: 索引
});
```javascript
arr = [3,4,5,6,2,1,3,4,5];
var s = arr.filter(function(value, index){
console.log(value, index);
return value >=3;
});
console.log(s);
```
4. map: 對數組中的每一項運行給定的函數, 返回每次函數調用的結果組成的一個新數組
數組.map(function(value, index, array){});
```javascript
var mn = arr.map(function(value, index, array){
console.log(value, index, array);
return value * value + index;
});
console.log(mn);
```
5. forEach: 對數組中的每一項運行給定的函數,沒有返回值, 就是一個循環
數組.forEach(function(value, index, array){});
```javascript
var sn = arr.forEach(function(value, index, array){
console.log(value, index, array);
array[index] = 1;
// return value * value + index;
});
console.log(sn); // undefined
console.log(arr);
```
### 7、localCompare
- 要排序的項.localCompare(對比的排序項, [語言]);
- 不傳語言, 默認按照本地環境語言對比
- zh--中文 en---英文
```javascript
var arr = [
{ name: 'd武麗昕', num: 78 },
{ name: '湯文博', num: 38 },
{ name: 's盧文博', num: 58 },
{ name: '鄧鈞鍵', num: 97 },
{ name: 'f劉繼昂', num: 56 },
{ name: '慄軍安', num: 78 },
{ name: 'r屈曉月', num: 98 },
{ name: '付秋萍', num: 79 }
];
// 要排序的項.localCompare(對比的排序項, [語言]);
// 不傳語言, 默認按照本地環境語言對比
// zh--中文 en---英文
arr.sort(function(a, b){
// console.log(a, b);
return a.name.localeCompare(b.name, 'zh');
});
console.log(arr);
```
## 六、DOM
> 文檔對象模型, 是W3C推薦的處理可拓展標誌性語言的標準編程接口
> 瀏覽器生成頁面時形成的樹狀結構, 用來表示頁面的內部結構, 成爲DOM樹
### 節點
- 類型: nodeType, 1-12數字, 標籤-1, 屬性-2, 文本-3, 註釋-8, 文檔-9
- 名字: nodeName, 所有標籤名字都是大寫
- 節點的內容: nodeValue, 只有文本節點纔有內容
#### 1. 獲取子節點
節點.children: 非標準屬性, 獲取的標籤子節點(ie8及以下含註釋節點)
節點.childNodes: 標準屬性, 獲取到文本節點(ie8及以下只返回標籤節點)
```javascript
var a = document.getElementsByTagName('a')[0];
console.log(a.children); // HTMLCollection
console.log(a.childNodes); // NodeList
for(var i = 0; i< a.children.length; i++){
var s = a.children[i];
console.log(s, s.nodeType, s.nodeName, s.nodeValue);
if(s.nodeType == 1){ // 標籤---span
console.log(s.childNodes, s.childNodes[0].nodeValue, '1----');
}
}
```
#### 2. 獲取父節點
節點.parentNode: 直接父元素
節點.offsetParent: 獲取距離節點最近的定位父元素, 如果沒有, 會找到body
```javascript
var span1 = document.getElementsByClassName('span1')[0];
console.log(span1.parentNode);
console.log(span1.offsetParent);
```
#### 3. 獲取其他節點
1. 獲取首節點
父元素.firstChild: 標準瀏覽器中會獲取到文本節點, 在ie678獲取到標籤節點
父元素.firstElementChild: 獲取到標籤節點, ie678不支持
兼容: 父元素.firstElementChild || 父元素.firstChild
```javascript
var ul = document.getElementsByTagName('ul')[0];
console.log(ul.firstChild);
console.log(ul.firstElementChild);
// 處理兼容 || 從左到右, 第一個條件爲真,直接返回第一個條件的結果, 當第一個條件爲假的時候, 判斷第二個條件, 返回第二個條件的結果
console.log(ul.firstElementChild || ul.firstChild);
```
2. 獲取尾結點
父元素.lastChild: 標準瀏覽器中會獲取到文本節點, 在ie678獲取到標籤節點
父元素.lastElementChild: 獲取到標籤節點, ie678不支持
兼容: 父元素.lastElementChild || 父元素.lastChild
```javascript
console.log(ul.lastChild);
console.log(ul.lastElementChild);
console.log(ul.lastElementChild || ul.lastChild);
```
3. 獲取上一個兄弟節點
節點.previousSibling: 標準中得到文本節點,在ie678獲取到標籤節點
節點.previousElementSibling: 獲取到標籤節點, ie678不支持
```javascript
var box = document.getElementsByTagName('li')[2];
console.log(box);
console.log(box.previousSibling);
console.log(box.previousElementSibling);
console.log(box.previousElementSibling || box.previousSibling);
```
4. 獲取下一個兄弟節點
節點.nextSibling: 標準中得到文本節點, 在ie678獲取到標籤節點
節點.nextElementSibling: 獲取到標籤節點, ie678不支持
```javascript
console.log(box.nextSibling);
console.log(box.nextElementSibling);
console.log(box.nextElementSibling || box.nextSibling);
```
#### 4. 創建節點
創建標籤節點:
document.createElement('標籤名');
創建文本節點:
document.createTextNode('要顯示的內容');
```javascript
var li = document.createElement('li');
var text = document.createTextNode('這是一個新的li');
console.log(li);
console.log(text);
// 將文本節點添加到標籤節點中
li.appendChild(text);
console.log(li);
```
#### 5. 添加節點
注意: 如果追加一個已經存在的元素, 而是發生物理位移
1. 追加節點:
父節點.appendChild(子節點);
2. 在某個節點之前追加節點:
父節點.insertBefore(要追加的節點|新節點, 參考節點);
```javascript
ul.appendChild(li);
// ul1.appendChild(li);
var lis = document.getElementsByTagName('li');
// ul1.appendChild(lis[0]);
ul.insertBefore(li, lis[2]);
```
#### 6. 刪除節點
1. 刪除自身及子元素
父節點.remove();
2. 刪除某個子節點
父節點.removeChild(要移除的節點);
```javascript
ul1.remove();
ul.removeChild(lis[0]);
```
#### 7. 替換節點
父節點.replaceChild(新節點, 參考節點);
```javascript
ul.replaceChild(li, lis[0]);
```
#### 8. 克隆節點
參考節點.cloneNode(boolean);
true: 克隆標籤和內容, 克隆其中的所有子節點
false: 默認false, 只克隆標籤, 不克隆其中的內容
注意: 克隆出來的節點是一個新節點, 變量接收, 不會直接顯示在頁面中
```javascript
var newLi = li.cloneNode(true);
console.log(newLi);
ul.appendChild(newLi);
var newUl = ul1.cloneNode(true);
console.log(newUl);
document.body.appendChild(newUl);
```
## 七、獲取元素的方式
1. 獲取符合選擇器的條件的第一個標籤:
document.querySelector('選擇器');
選擇器寫法與css的一致
2. 獲取符合選擇器的條件的元素的集合:
document.querySelecorAll('選擇器');
```javascript
var li = document.querySelector('.b.a');
console.log(li);
// console.log(document.querySelector('#one')); // <li id="one"></li>
// console.log(document.querySelector('li')); // <li id="one"></li>
// console.log(document.querySelector('.a')); // <span class="a">這是第1個span</span>
// console.log(document.querySelector('.box,.a')); // <span class="a">這是第1個span</span>
// console.log(document.querySelector('.box .a')); // <span class="a b">這是第4個span</span>
// console.log(document.querySelector('.a.b')); // <span class="a b">這是第4個span</span>
// console.log(document.querySelector('li:nth-child(3)'));
// console.log(document.querySelector('li[class]'));
// console.log(document.querySelector('li[class=box]'));
// console.log(document.querySelector('li:first-child'));
console.log(document.querySelectorAll('li')); // 拿到所有li的標籤
console.log(document.querySelectorAll('.a')); // 拿到所有類名爲a的標籤
console.log(document.querySelectorAll('.box .a')); // 拿到所有類名爲box的子元素類名爲a的標籤
var lis = document.getElementsByTagName('li');
var lis1 = document.querySelectorAll('li');
var ul = document.getElementsByTagName('ul')[0];
// 動態性, className與tagName獲取的標籤具有動態性
// querySelectorAll不具有動態性, 獲取的時候存在就能拿到, 不存在就拿不到
ul.innerHTML += '<li>111111111111</li>';
console.log(lis);
console.log(lis1);
```
## 八、節點屬性操作
1. 點的方式:
獲取: 元素.屬性名
設置: 元素.屬性名 = 屬性值;
box.id box.className = 'a';
2. []的方式
獲取: 元素['屬性名']
設置: 元素['屬性名'] = 屬性值;
3. 獲取: 元素.getAttribute('屬性名');
4. 設置: 元素.setAttribute('屬性名', '屬性值');
5. 移除: 元素.removeAttribute('屬性名');
問題: 1.2不能去操作自定義屬性
3.4.5既可以操作固有屬性也可以操作自定義屬性, 並且html上可見
```javascript
var div = document.querySelector('div');
console.log(div.className);
console.log(div['className']);
console.log(div.tag); // undefined
console.log(div['tag']); // undefined
console.log(div.getAttribute('class'));
console.log(div.getAttribute('tag')); // 123
console.log(div.setAttribute('id', 'b'));
console.log(div.setAttribute('n', 'ttt'));
div.id = '';
div.removeAttribute('id');
```
#### 快速獲取表格元素的方式
```javascript
// 快速獲取表格元素的方式
var table = document.getElementsByTagName('table')[0];
// 獲取表格中的元素
console.log(table.tHead); // 獲取head, 直接元素
console.log(table.tFoot); // 獲取foot, 直接元素
console.log(table.tBodies); // 獲取表格體body, 集合
console.log(table.rows); // 獲取到整個表格的行
console.log(table.tBodies[0].rows); // 獲取指定表格體的所有行
console.log(table.cells); // undefined
// 只有行中才有單元格
console.log(table.rows[1].cells);
// 添加行--->添加單元格--->創建單元格--->標籤+內容--->單元格添加到tr--->tr添加到tbody
var tr = document.createElement('tr');
var td = document.createElement('td');
td.innerText = '123';
tr.appendChild(td);
var td1 = document.createElement('td');
td1.innerText = '123111';
tr.appendChild(td1);
var td2 = document.createElement('td');
td2.innerText = '123111';
tr.appendChild(td2);
var td4 = document.createElement('td');
td4.innerText = '123111';
tr.appendChild(td4);
table.tBodies[0].appendChild(tr);
```