#### 一、math
- 数学函数:不是一个函数,是一个对象,对象中存储了很多操作数
字的函数,因此被称为数学函数。
```
console.log(typeof(Math));//=>"object"
console.dir(Math);
/*
* Math={
* PI:3.141592653589793
* abs:function(){[native code]}
* ceil:function(){[native code]}
* ···
* }
* Math.abs();
* Math.PI;
*/
```
##### Math中常用的属性和方法
### 1.Math.abs([value])
获取绝对值,绝对值永远非负数
```
console.log(Math.abs(-12.5));//=>12.5
console.log(Math.abs(12));//=>12
console.log(Math.abs(0));//=>0
//不是数字类型的值:先基于Number()转换为数字再处理
console.log(Math.abs('-1'));//=>1
console.log(Math.abs('-1px'));//=>NaN
console.log(Math.abs(true));//=>1
```
### 2.Math.ceil/floor([number value])
把一个数向上取整/向下取整
```
console.log(Math.ceil(12));//=>12
console.log(Math.ceil(12.1));//=>13
console.log(Math.ceil(12.9));//=>13
console.log(Math.ceil(-12.1));//=>-12
console.log(Math.ceil(-12.9));//=>-12
console.log(Math.floor(12));//=>-12
console.log(Math.floor(12.1));//=>12
console.log(Math.floor(12.9));//=>12
console.log(Math.floor(-12.1));//=>-13
console.log(Math.floor(-12.9));//=>-13
```
### 3.Math.round()
四舍五入
```
console.log(Math.round(12));//=>12
console.log(Math.round(12.1));//=>12
console.log(Math.round(12.5));//=>13
console.log(Math.round(12.9));//=>13
console.log(Math.round(-12.1));//=>-12
console.log(Math.round(-12.5));//=>-12(负数中 .5舍)
console.log(Math.round(-12.9));//=>-13
```
### 4.Math.max/min([val1],[val2],...)
获取一堆数中的最大值和最小值
```
console.log(Math.max(12,5,68,23,45,3,28));//=>68
console.log(Math.min(12,5,68,23,45,3,28));//=>3
//思考题:如何基于Math.max/min获取数组中的最大值/最小值?
Math.max([12,5,68,23,45,3,28]);//=>NaN 此处只传递第一个值,
是个数组,和内置的语法要求不符
```
### 5.Math.sqrt/pow()
sqrt:给一个数开平方
pow:计算一个数的
```
console.log(Math.sqrt(9));//=>3
console.log(Math.sqrt(-9));//=>NaN
console.log(Math.pow(2,10));//=>1024
```
### 6.Math.random()
获取0-1之间的随机小数
```
for (let i = 0; i <= 10; i++) {
console.log(Math.random());
}
/*
0.2351119504604302
0.8103880292045642
0.9153034803838505
···
*/
```
### 扩展:获取[n-m]之间的随机整数
包含n、m
n<m
```
Math.round(Math.random()*(n-m)+n)
```
#### 数组及数组中常用的方法
数组是对象数据类型的,它属于特殊的对象
```
let ary=[12,23,34,45];
console.log(typeof(ary));//=>object
console.dir(ary);
/*
ary{
0:12,
1:23,
2:34,
3:45,
length:4
}
数字作为索引(key属性名)
length代表长度
ary[0]根据索引获取指定项的内容
ary.length 获取数组的长度
ary.length-1最后一项的索引
*/
```
### 数组中常用的方法
+ 方法的作用和和含义
+ 方法的实参(类型和含义)
+ 方法的返回值
+ 原来的数组是否会发生改变
1. 实现数组增删改的方法
这一部分方法都会修改原有的数组
'push'
```
push:向数组末尾增加内容
参数:@params
多个任意类型
返回值:@return
新增后数组的长度
let ary=[10,20];
let res=ary.push(30,'AA');
//基于原生JS操作键值对的方法,也可以向末尾追加一项新的内容
ary[ary.length]=40;
console.log(res,ary);//=>4 [10,20,30,'AA',40]
```
'unshift'
```
unshift:向数组开始位置增加内容
参数:@params
多个任意类型
返回值:@return
新增后数组的长度
let ary=[10,20];
let res=ary.unshift(30,'AA');
console.log(res,ary);//=>4 [30,'AA',10,20]
```
'shift'
```
shift:删除数组中的第一项
参数:@params
返回值:@return
删除的那一项
let ary=[10,20,30,40];
let res=ary.shift();
console.log(res,ary);//=>10 [20,30,40]
//基于原生JS中的delete,把数组当做普通的对象,确实可以删除
某一项内容,但是不会影响数组本身的结构特点(length长度不会
跟着修改),真实项目中杜绝这样的删除使用
delete ary[0];
console.log(res,ary);//=>{1:30,2:40,length:3}
```
'pop'
```pop:删除数组中的最后一项
参数:@params
返回值:@return
删除的那一项
let ary=[10,20,30,40];
let res=ary.pop();
console.log(res,ary);//=>40 [10,20,30]
//基于原生JS让数组长度删掉一位,默认删除最后一项
ary.length--;//ary.length = ary.length - 1;
console.log(res,ary);//=>40 [10,20]
```
'splice'
```
splice:实现数组的增加、修改
参数:@params
n,m,x 从索引n开始删除m个元素,用x占用删除的部分
n,0,x 从索引n开始,一个都不删,把x放到索引n的前面
返回值:@return
把删除的部分用新数组存储起来返回
let ary = [10, 20, 30, 40, 50];
let res = ary.splice(1,2,'哈哈哈');
console.log(res, ary);//=>[20,30] [10,'哈哈哈',40,50]
//实现增加
ary.splice(3,0,'嘻嘻')
console.log(ary);//=>[10, '哈哈哈', 40, '嘻嘻', 50]
//向数组末尾追加
ary.splice(ary.length,0,'AAA');
console.log(ary);//=>[10, '哈哈哈', 40, '嘻嘻', 50,
'AAA']
//向数组开端追加
ary.splice(0,0,'BBB');
console.log(ary);//=>['BBB', 10, '哈哈哈', 40, '嘻嘻',
50, 'AAA']
```
2.数组的查询和拼接
此组学习的方法,原来数组不会改变
slice
```
slice:实现数组的查询
参数:@params
n,m 都是数字 从索引n开始,找到索引为m的地方(不包含m
这一项)
返回值:@return
把找到的内容以一个新数组的形式返回
let ary=[10,20,30,40,50];
let res=ary.slice(-1,-3);
console.log(res);//=>[20,30]
//m不写是找到末尾
// res=ary.slice(1);
// console.log(res);//=>[20,30,40,50]
//数组的克隆,参加0不写也可以
// res=ary.slice(0);
// console.log(res);//=>[10,20,30,40,50]
//思考:
// 1.如果n、m是负数会怎么样?若n>m会怎么样?如果是小数会怎么
样?若是非有效数字会怎么样?若m或n的值比最大索引都大会怎么样?
// 若n为负,则无论m是正或负,均为空字符串
// 若n为正,
// 2.这种克隆方式叫浅克隆,深克隆如何处理?
```
'concat'
```
concat:实现数组拼接
参数:@params
多个任意类型值
返回值:@return
拼接后的新数组(原来数组不变)
let ary1=[1,2,3];
let ary2=[4,5,6];
let res=ary1.concat('QQQ',ary2);
console.log(res);//=>[1,2,3,'QQQ',4,5,6]
```
3.把数组转换为字符串
原有数组不变
tostring
```
tostring:把数组转换为字符串
参数:@params
返回值:@return
转换后的字符串,每一项用逗号分隔(原来数组不变)
let ary=[1,2,3];
let res=ary.toString();
console.log(res); //=>"1,2,3"
console.log([].toString());//=>""
console.log([12].toString());//=>"12"
```
join
```
join:把数组转换为字符串
参数:@params
指定的分隔符(字符串格式)
返回值:@return
转换后的字符串(原来数组不变)
let ary=[1,2,3];
// let res=ary.join('');
// console.log(res); //=>"123"
// let res=ary.join('|');
// console.log(res); //=>"1|2|3"
// let res=ary.join();
// console.log(res);
let res=ary.join('+');
console.log(res);
console.log(eval(res)); //=>eval把字符串变为JS表
达式执行
```
4.检测数组中是否包含某一项
indexof/lasIndexof
```
indexOf / lastIndexOf:检测当前项在数组中第一次或者最后一
次出现位置的索引值(在IE6-8中不兼容)
参数:@params
要检索的这一项内容
返回值:@return
这一项出现的位置索引值(数字),如果数组中没有这一
项,返回的结果是-1
原来数组不变
let ary = [1, 2, 3, 1, 2, 3];
console.log(ary.indexOf(2));//=>1
console.log(ary.lastIndexOf(2));//=>4
//验证ary中是否包含'哈哈哈'
if (ary.indexOf('哈哈哈') === -1){
//不包含
}
//也可以直接使用ES6新提供的includes方法判断
if(ary.includes('哈哈哈')){
//包含:如果存在返回的是true
}
```
5.数组的排序或排列
reverse
```
reverse:把数组倒过来排列
参数:@params
返回值:@return
排列后的新数组
原来数组改变
let ary = [12, 15, 9, 28, 10, 22];
ary.reverse();
console.log(ary);//=>[22, 10, 28, 9, 15, 12]
```
sort
```
sort :实现数组的排序
参数 :@params
可以没有,也可以是个函数
返回值 :@return
排列后的新数组
原来数组改变
// let ary = [4,7,5,8,3,6,1,9,2];
// ary.sort();
// console.log(ary);//=>[1, 2, 3, 4, 5, 6, 7, 8, 9]
//sort 方法中如果不传递参数,是无法处理10以上数字排序的(它
默认按照每一项第一个字符来排序,不是按照数值大小排的)
/* let ary = [12, 15, 9, 28, 10, 22];
ary.sort();
console.log(ary);//=>[10, 12, 15, 22, 28, 9] */
//实现多位数正常排序,需要给sort传递一个函数,函数中返回a-b
实现升序,返回b-a 实现降序(? 需了解冒泡排序的机制)
let ary = [12, 15, 9, 28, 10, 22];
//ary.sort(function(a,b){return a-b});
//a和b是相邻的两项
ary.sort((a, b) => a - b);
console.log(ary);//=>[9, 10, 12, 15, 22, 28]
```
6.遍历数组中每一项的方法
forEach
```
forEach :遍历数组中的每一项内容
参数 :@params
回调函数
返回值 :@return
原来数组改变
*/
let ary = [1, 5, 9, 6, 5, 12, 14];
/* //基于原生JS中的循环可以实现
for (let i = 0; i < ary.length; i++) {
//i:当前循环这一项的索引
//ary[i]:根据索引获取循环的这一项
console.log('索引:' + i + '内容:' + ary[i]);
} */
ary.forEach((item, index) => {
// 数组中有多少项,函数就会被默认执行多少次
//每一次执行函数:item是数组中当前要操作的这一项,index
是当前项的索引
console.log('索引:' + index + '内容:' + item);
});
```
map
filter
find
reduce
some
every
····
Array.prototype在控制台查看数组中所有提供的方法,可以基于
MDN网站去查询方法的用法
#### 数组去重
```
let ary = [1, 2, 3, 1, 2, 1, 2, 3, 2, 1, 2, 3];
//=>[1,2,3]
/*
方案一:
循环原有数组中的每一项,每拿到一项都往新数组中添加
添加之前验证新数组中是否存在这一项,不存在再添加
*/
let newAry = [];
for (let i = 0; i < ary.length; i++) {
//循环获取原有数组中的每一项
let item = ary[i];
//验证新数组中是否存在这一项
if (newAry.includes(item)) {
//存在这一项,不再增加到新数组,继续下一轮循环即可
continue;
}
//新数组中不存在这一项,我们加入到新数字即可
newAry.push(item);
}
console.log(newAry);
```
```
//方案一优化
let newAry = [];
ary.forEach(item => {
if (newAry.includes(item)) return;
newAry.push(item);
});
console.log(newAry);
```
方案二:
``` 先分别拿出数组中的每一项A
用这一项A和它后边的每一项依次进行比较,如果遇到和当前
项A相同的,则在原来数组中把这一项移除掉
不用includes/indexOf,保证兼容性
var ary = [1, 2, 3, 1, 2, 1, 2, 3, 2, 1, 2, 3];
for (var i = 0; i < ary.length; i++) {
//item:每一次循环拿出来的当前项
//i:当前项索引
var item = ary[i];
/*
itemLast:当前项后边所有的内容(新数组)
var itemLast = ary.slice(i + 1); //创建数组耗性能*/
//i+1:代表后一项
//让当前项与后边的每一项进行比较(循环)
for (var j = i + 1; j < ary.length; j++) {
//compare:后边需要比较的每一项
var compare = ary[j];
//如果compare和item相等,说明这一项是重复的,把他删掉
if (compare === item) {
//j索引这一项要从数组中移除
ary.splice(j, 1);
//数组塌陷了:j后边的每一项索引都提前了一位,下一
次要比较还是j这个索引的内容
j--;
}
}
}
console.log(ary);
```
方案三:
```
let ary = [1, 2, 3, 1, 2, 1, 2, 3, 2, 1, 2, 3];
//1.创建一个空对象
let obj = {};
//2.循环数组中的每一项,把每一项向对象中进行存储 => item:item
for (let i = 0; i < ary.length; i++) {
let item = ary[i];
//3.存储之前进行判断:验证obj中是否存在这一项
if (obj[item] !== undefined) {
//已经存在这一项
ary.splice(i, 1);
i--;
continue;
}
obj[item] = item;//obj[1]=1;···
}
console.log(ary);
```
```
//基于splice实现删除性能不好:当前项被删后,后面每一项的索引都
要向前提一位,如果后面内容过多,定影响性能
/*
let ary = [1, 2, 3, 1, 2, 1, 2, 3, 2, 1, 2, 3];
let obj = {};
for (let i = 0; i < ary.length; i++) {
let item = ary[i];
if (obj[item] !== undefined) {
ary[i] = ary[ary.length - 1];
ary.length--;
i--;
continue;
}
obj[item] = item;//obj[1]=1;···
}
console.log(ary);
*/
/*
unique:实现数组去重的方法
@params
ary[Array]要去重的数组
@return
[Array]去重后的数组
by ct on 20230214
*/
function unique(ary) {
let obj = {};
for (let i = 0; i < ary.length; i++) {
let item = ary[i];
if (obj[item] !== undefined) {
ary[i] = ary[ary.length - 1];
ary.length--;
i--;
continue;
}
obj[item] = item;
}
return ary;
}
let aa = [1, 5, 6, 8, 12, 1, 2, 5, 6, 15, 47, 12, 47];
aa = unique(aa);
aa.sort((a, b) => a - b);
console.log(aa);
```
//正则
```
let ary = [1, 5, 6, 8, 12, 1, 2, 5, 6, 15, 47, 12, 47];
ary.sort((a, b) => a - b);
let str = ary.join('@') + '@';
let reg = /(\d+@)\1*/g;
console.log(str.match(reg));
ary = [];
str.replace(reg, (n, m) => {
m = Number(m.slice(0, m.length - 1));
ary.push(m);
});
console.log(ary);//=>[1, 2, 5, 6, 8, 12, 15, 47]
```
//基于ES6的set(对应的Map)实现去重
```
let ary = [1, 5, 6, 8, 12, 1, 2, 5, 6, 15, 47, 12, 47];
ary = [...new Set(ary)];
console.log(ary);//=>[1, 5, 6, 8, 12, 2, 15, 47]
```
#### 字符串中常用的方法
> 所有用 单引号、双引号、反引号 包起来的都是字符串
```
let str = 'hahahahahah';
//每一个字符串都是由零到多个字符组成的
str.length //=>字符串长度
str[0] //=>获取索引为零(第一个)字符
str[str.length-1] //=>获取最后一个字符str.length-1最后一线
索引str[10000] //=>undefined 不存在这个索引
//循环输出字符串中的每一个字符
let str = 'hahahahahah';
for(let i=0;i<str.length;i++){
let char = str[i];
console.log(char);
}
```
`charAt / charCodeAt`
```
charAt:根据索引获取指定位置的字符
charCodeAt:获取指定字符的ASII码值(Unicode编码值)
@params
n[number] 获取字符指定的索引
@return
返回查找到的字符
找不到返回的是空字符串㐊undefined,或者对应的编码值
let str = 'hahahahahah';
console.log(str.charAt(0)); //=>'h'
console.log(str[0]); //=>'h'
console.log(str.charAt(100)); //=>''
console.log(str[100]); //=>undefined
console.log(str.charCodeAt(0)); //=>104
console.log(String.fromCharCode(str.charCodeAt(0)));//=>'h'
```
`substr / substring / slice`
```
都是为了实现字符串截取(在原来字符串查找到自己想要的)
substr(n,m):从索引n开始截取m个字符,m不写截取到末尾(其他的
方法也是)
substring(n,m):从索引n开始找到索引m处(不包含m)
slice(n,m):和substring一样,都是找到索引m处,但slice可以
支持负数作为索引,其余两个方法不可以
let str = 'hahahahahaha';
console.log(str.substr(3,7));//=>'ahahaha'
console.log(str.substring(3,7));//=>'ahah'
console.log(str.substr(3));//=>'ahahahaha' 截取到末尾
console.log(str.substring(3,100));//=>'ahahahaha' 截取到末
尾(超过索引的也只截取到末尾)
console.log(str.substring(3,7));//=>'ahah'
console.log(str.slice(3,7));
console.log(str.substring(-7,-3));//=>'' substring不支持负
数索引
console.log(str.slice(-7,-3));//=>'nqit' slice支持负数索引
快捷查找:负数索引,按照STR.length+负索引的方式找
=>slice(12-7,12-3) =>slice(5,9) =>ahah
```
`indexof / lastIndexOf / includes`
```
验证字符是否存在
indexOf(x,y):获取x第一次出现位置的索引,y是控制查找的起
始位置索引
lastIndexOf(x):最后一次出现位置的索引
=>没有这个字符,返回的结果是-1
let str = 'hahahahahaha';
console.log(str.indexOf('h'));//=>0
console.log(str.lastIndexOf('h'));//=>10
console.log(str.indexOf('!'));//=>-1 不存在返回-1
if(str.indexOf('!')===-1){
//字符串中不包含!这个字符
}
console.log(str.indexOf('aha'));//=>1 验证整体第一次出现
的位置,返回的索引是第一个字符所在位置的索引值
console.log(str.indexOf('ahan'));//=>-1
console.log(str.indexOf('ha',5));//=>6 查找索引5及之后的
字符串中,ha第一次出现的位置索引
if(!str.includes('!')){
console.log('当前字符串不包含!');
}
```
`toUpperCase / toLowerCase`
```
字符串中字母的大小写转换
toUpperCase():转大写
toLowerCase():转小写
let str = 'Hahahahahaha';
str=str.toUpperCase();
console.log(str);//=>'HAHAHAHAHAHA'
str=str.toLowerCase();
console.log(str);//=>'hahahahahaha'
//实现首字母大写
str = str.substr(0, 1).toUpperCase() + str.substr(1);
console.log(str);//=>Hahahahahaha
```
`split`
```
split([分隔符]):把字符串按照指定的分隔符拆分成数组(和
数组里的join相对应)
split支持传递正则表达式
//需求:把|分隔符变为,分隔符
let str = 'music|movie|eat|sport';
let ary=str.split('|');//=>['music', 'movie', 'eat',
'sport']
console.log(ary);
str=ary.toString();
console.log(str);//=>music,movie,eat,sport
str=ary.join(',');
console.log(str);//=>music,movie,eat,sport
```
`replacr`
```
replace(老字符,新字符):实现字符串的替换(经常伴随着正
则使用)
let str='哈喽!你好!是吧?';
/* str=str.replace('!','+');
console.log(str);//=>哈喽+你好!是吧? 在不使用正则表达式
的情况下,执行一次replace只能替换一次字符 */
str=str.replace(/!/g,'-');
console.log(str);//=>哈喽-你好-是吧?
```
`match`
`localCompare`
`trim / trimLeft / trimRight`
···
控制台输出string.prototype查看所有字符串中提供的方法
#### 实现一些常用的需求
> 5.时间字符串的处理
```
let time = '2023-2-14 19:45:45';
//=>变为自己需要呈现的格式,例如:
//"2023年2月14日 19点45分45秒"
//"2023年2月14日"
//"2/14 19:45"
//···
//方案一:
/*
let time = '2023-2-14 19:45:45';
time = time.replace('-', '年').replace('-', '月')
.replace(' ', '日 ').replace(':', '时').replace(':',
'分') + '秒';
console.log(time);//=>2023年2月14日 19时45分45秒
*/
//方案二:获取年月日时分秒这几个值,按照所想拼出效果
//不足十位补零
/*
let addZero = val => {
if (val.length < 2) {
val = '0' + val;
}
return val;
};
*/
let addZero = val => val.length < 2 ? '0' + val : val;
let time = '2023-2-14 19:45:45';
let ary = time.split(/(?: |-|:)/g);//=>['2023', '2',
'14', '19', '45', '45']
time = ary[0] + '年' + addZero(ary[1]) + '月' +
addZero(ary[2]) + '日';
console.log(time);//=>2023年02月14日
//获取值的方法:基于split一项项拆分
/*
let time = '2023-2-14 19:45:45';
let n = time.split(' ');//=>["2023-2-14" ,"19:45:45"]
let m = n[0].split('-')//=>["2023","2","14"]
let x = n[1].split(':');//=>["19","45","45"]
console.log(x);
*/
//获取值的方法:基于indexOf获取指定符号索引,基于substring
一点点截取
/*
let time = '2023-2-14 19:45:45';
let n = time.indexOf('-');
let m = time.lastIndexOf('-');
let x = time.indexOf(' ');
let y = time.indexOf(':');
let z = time.lastIndexOf(':');
let year = time.substring(0, n);
let month = time.substring(n + 1, m);
let day = time.substring(m + 1, x);
console.log(year, month, day); */
```
> 6.实现一个方法ueryURLPqarameter获取一个URL地址问号后边
传递的参数信息
```
// let url = 'http://www.zhufengpeixun.cn/index.html?lx=1&name=zhufeng&teacher=aaa#box';
/*
结果:{
lx:1,
name:'zhufeng',
teacher:'aaa',
HASH:'box'
}
*/
/* //1.获取问号或者井号后边的值
let askIndex = url.indexOf('?');
let wellIndex = url.indexOf('#');
let askText = url.substring(askIndex + 1, wellIndex);
let wellText = url.substring(wellIndex + 1);
console.log(askText, wellText);
// askText="lx=1&name=zhufeng&teacher=aaa"
// wellText="box"
//2.问号后边值的详细处理
let result = {};
let askAry = askText.split('&');
console.log(askAry);
//=>['lx=1', 'name=zhufeng', 'teacher=aaa']
askAry.forEach(item => {
//item:当前从数组中循环的这一项
let n = item.split('=');
console.log(n);
// ['lx', '1']
// ['name', 'zhufeng']
// ['teacher', 'aaa']
let key = n[0];
let value = n[1];
result[key] = value;
});
result['HASH'] = wellText;
console.log(result);
//=>{lx: '1', name: 'zhufeng', teacher: 'aaa', HASH:
'box'} */
/*
queryURLParams:获取URL地址中间问号传参的信息和哈希值
@params
URL[string]要解析的url字符串
@return
[object]包含参数和哈希值信息的对象
by ct on 20230214
*/
/* function queryURLParams(url) {
//1.获取?和#后边的信息
let askIn = url.indexOf('?'),
wellIn = url.indexOf('#'),
askText = '',
wellText = '';
//#不存在
wellIn === -1 ? wellIn = url.length : null;
//?存在
askIn >= 0 ? askText = url.substring(askIn + 1,
wellIn) : null;
wellText = url.substring(wellIn + 1);
//2.获取每部分信息
let result = {};
wellText !== '' ? result['HASH'] = wellText :
null;
if (askText !== '') {
let ary = askText.split('&');
ary.forEach(item => {
let itemAry = item.split('=');
result[itemAry[0]] = itemAry[1];
});
}
return result;
}
*/
//基于正则封装、完美
function queryURLParams(url) {
let result = {},
reg1 = /([^?=&#]+)=([^?=&#]+)/g;
reg2 = /#([^?=&#]+)/;
url.replace(reg1, (n, x, y) => result[x] = y);
url.replace(reg2, (n, x) => result['HASH'] = x);
return result;
}
let url = 'http://www.zhufengpeixun.cn/index.html?lx=1&name=zhufeng&teacher=aaa#box';
let paramsObj = queryURLParams(url);
console.log(paramsObj);
```
> 7.实现一个最low的验证码:数字加字幕共四位
验证码的目的:防止外挂程序恶意批量注入的
```
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>简单的验证码</title>
</head>
<body>
<input type="text" id="codeInp">
<br>
<span id="codeBox">aaaa</span>
<button id="changeCode">看不清,换一张</button>
<!-- import Js -->
<script>
let codeInp = document.getElementById('codeInp'),
codeBox = document.getElementById('codeBox'),
changeCode = document.getElementById(
'changeCode');
/*
queryCode:获取到四位随机验证码,然后放到指定的盒子中
@params
@return
by ct on 20230214
*/
function queryCode() {
let area = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
0123456789";
let result = "";
for (let i = 0; i < 4; i++) {
//每一次循环都获取一个随机的数字索引
let ran = Math.round(Math.random(
) * 61);
//再根据获取的索引从范围字符串中找到对应
的字符,把
找到的字符拼接到最后的结果中
result += area.charAt(ran);
}
//放到盒子里
codeBox.innerHTML = result;
}
//第一次加载页面需要执行方法,让其显示在页面中
queryCode();
//点击看不清按钮,需要重新执行方法生成新的验证码
changeCode.onclick = queryCode;
//文本框失去焦点的时候:验证用户输入法人内容和验证码是否
相同,给予相关的提示,如果不一样需要重新生成验证码
//onblur:文本框失去焦点事件
codeInp.onblur = function () {
//获取用户和验证码内容(表单元素.value / 非表单
元素.innerHTML 获取内容)
let val = codeInp.value,
code = codeBox.innerHTML;
//不区分大小写的验证(都转小写)
if (val.toLowerCase() === code.toLowerCase()) {
alert('温馨提示:验证码输入成功!');
} else {
alert('温馨提示:验证码输入错误,请重新输入!');
codeInp.value = '';
//重新生成验证码
queryCode();
}
}
</script>
</body>
</html>
```
#### 8日期对象的基本操作
```
let time=new Date();
<!--
获取当前客户端(本机电脑)本地的时间
这个时间用户是自己可以修改的,不能作为重要的参
考依据
Wed Feb 15 2023 16:07:27 GMT+0800 (中国标准时间)
获取的结果不是字符串,是对象数据类型的,属于日期对象
(或者说是Date这个类的实例对象)
-->
typeOf time;//=>"object"
```
标砖日期对象中提供了一些属性和方法,供我们操作日期信息
· getFullYear()获取年
· getMonth()获取月 结果是0-11代表第一月到第十二月
· getDate()获取日
· getDay()获取星期 结果是0-6代表周日到周六
· getHours获取时
· getMinutes()获取分
· getSeconds()获取秒
· getMillseconds()获取毫秒
· getTime()获取当前日期距离1970/1/1 00:00:00这个日期之间
的毫秒差
· toLocaleDateString()获取年月日(字符串)
· toLocaleString()获取完整的日期字符串
```
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>小时钟</title>
<!-- import css -->
<style>
* {
margin: 0;
padding: 0;
}
#clockBox {
position: absolute;
right: 0;
top: 0;
padding: 0 15px;
line-height: 50px;
font-size: 20px;
color: black;
/* 设置背景渐变色 */
/* background:lightblue ; */
background: -webkit-linear-gradient(top left,
lightcoral, lightcyan);
}
</style>
</head>
<body>
<div id="clockBox">
2023年02月15日 星期三 16:24:01
</div>
<!-- import JS -->
<script>
let clockBox = document.getElementById('clockBox');
/*
addZero:不足十补领
@params
val需要处理的值
@return
处理后的结果
by ct on 20230215
*/
function addZero(val) {
val = Number(val);
return val < 10 ? '0' + val : val;
}
/*
queryDate:获取当前日期,把其转换为想要的格式
@params
@return
by ct on 20230215
*/
function queryDate() {
//1.获取当前日期及详细信息
let time = new Date(),
year = time.getFullYear(),
month = time.getMonth() + 1,
day = time.getDate(),
week = time.getDay(),
hours = time.getHours(),
minutes = time.getMinutes(),
seconds = time.getSeconds();
//2.拼凑成想要的字符串
let result = year + "年" + addZero(month) +
"月" + addZero(day) + "日";
let weekAry = ['日', '一', '二', '三', '四',
'五', '六'];
result += " 星期" + weekAry[week] + " ";
result += addZero(hours) + ":" + addZero
(minutes) + ":" + addZero(seconds);
//3.把处理好的结果放盒子里
clockBox.innerHTML = result;
}
//加载页面执行方法
queryDate();
//定时器控制运动:设置一个setInterval定时器(到达指定时间
做对应的事的东西就是定时器),每隔1000ms执行queryDate方法
setInterval(queryDate, 1000);
</script>
</body>
</html>
```
> new Date()除了获取本机事件,还可以把一个时间格式字符串转换为标准
的时间格式
```
new Date("2023/2/15");
//=>Wed Feb 15 2023 00:00:00 GMT+0800 (中国标准时间)
<!--
支持的格式
yyyy/mm/dd
yyyy/mm/dd hh:mm:ss
yyyy-mm-dd 这种格式IE不支持
-->
```
#### 9时间字符串格式化案例
```
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>时间格式化</title>
</head>
<body>
<script>
let addZero = val => {
val = Number(val);
return val < 10 ? '0' + val : val;
}
/*
字符串处理
*/
function formatTime(time) {
//1.获取年月日星期
// let ary=time.split(/(?: |-|:)/g);
let ary = time.split(' ');
let aryLeft = ary[0].split('-'),
aryRight = ary[1].split(':');
ary = aryLeft.concat(aryRight);
//=>['2023', '2', '15', '12', '0', '0']
//2.拼接为想用的格式
let result = ary[0] + "年" + addZero(ary[1]) +
"月" + addZero(ary[2]) + "日";
result += " " + addZero(ary[3]) + ":" +
addZero(ary[4]) + ":" + addZero(ary[5]);
return result;
}
let time = '2023-2-15 12:0:0';
//=>"2023年02月15日 12:00:00"
time=formatTime(time);
console.log(time);
//=>2023年02月15日 12:00:00
</script>
</body>
</html>
```
```
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>时间格式化</title>
</head>
<body>
<script>
let addZero = val => {
val = Number(val);
return val < 10 ? '0' + val : val;
}
/*
基于日期对象处理
*/
<!--
function formatTime(time) {
//1.把时间字符串变为标准日起对象
// time = time.replace(/-/g,'/');
time = time.replace('-', '/');
time = time.replace('-', '/');
time = new Date(time);
//2.基于方法获取年月日等信息
let year = time.getFullYear(),
month = addZero(time.getMonth() + 1),
day = addZero(time.getDate()),
hours = addZero(time.getHours()),
minutes = addZero(time.getMinutes()),
seconds = addZero(time.getSeconds());
//3.返回想要的结果
return year+"年"+month+"月"+day+"日"+hours+"时"
+minutes+"分"+
seconds+"秒";
}
let time = '2023-2-15 12:0:0';
//=>"2023年02月15日 12:00:00"
time = formatTime(time);
console.log(time);
//=>2023年02月15日 12:00:00
-->
/*
封装一套公共的时间字符串格式化处理函数
*/
String.prototype.formatTime = function
formatTime(template) {
typeof templete === 'undefined' ?
templete = "{0}年{1}月{2}日 {3}:{4}:{5}" : null;
//this:要处理的字符串
let matchAry = this.match(/\d+/g);
//模板和数据的渲染(引擎机制)
templete = templete.replace(/\{(\d+)\}/g,
(x, y) => {
let val = matchAry[y] || '00';
val.length<2?val='0'+val:null;
return val;
});
return templete;
};
let time = '2023-2-15 12:0:0';
//=>"2023年02月15日 12:00:00"
console.log(time.formatTime());//传一个模板
//=>2023年02月15日 12:00:00
</script>
</body>
</html>
```
#### 10.DOM及其基础操作
> DOM:document object model文档对象模型,提供一些属性和
方法供我们操作页面中的元素
+ 获取DOM元素的方法
- document.getElementById()指定在文档中,基于元素的
ID或者这个元素对象
//为什么getElementById的上下文只能是document?
- [context].getElementByTagName()在指定上下文(容器)
中,通过标签名获取一组元素集合
- [context].getElementByClassName()在指定上下文中,
通过样式类名获取一组元素集合(不兼容IE6-8)
- document.getElementByName()在整个文档中,通过标签
的NAME属性值获取一组元素(节点)集合(在IE中只有表单元素的
NAME才能识别,所以我们一般只应用于表单元素的处理)
- document.head / document.body /
document.documentElement 获取页面中的head/body/HTML三个元素
- [context].querySelector([selector])在指定上下文中,
通过选择器获取指定的元素对象
- [context].querySelectorAll([selector])在指定上下文中,
通过选择器获取指定的元素集合
```
//=>querySelector / queryselectorAll 不兼容IE6-8
let box = document.querySelector('#box');
let links = box.querySelectorAll('a');
//links = document.querySelectorAll('#box a');
let aas = document.querySelectorAll('.aa');
```
### 11.JS中的节点和描述节点之间关系的属性
> 节点:Node(页面中所有的东西都是节点)
> 节点集合:NodeList(getElementsByName / querySelectorAll
获取的都是节点集合)
+ 元素节点(元素标签)
- nodeType:1
- nodeName:大写的标签名
- nodeValue:null
+ 文本节点
- nodeType:3
- nodeName:'#text'
- nodeValue:文本内容
+ 注释节点
- nodeType:8
- nodeName:'#commen'
- nodeValue:注释内容
+ 文档节点(document)
- nodeType:9
- nodeName:'#document'
- nodeValue:null
+ ···
描述这些节点之间关系的属性
+ childNodes:获取所有的子节点
+ children:获取所有的元素子节点(子元素标签集合)
+ parent:获取父亲节点
+ firstChild:获取第一个子节点
+ lastChild:获取最后一个子节点
+ firstElementChild / lastElementChild:获取第一个/
最后一个元素子节点(不兼容IE6-8)
+ previousSibling:获取上一个哥哥节点
+ nextSibling:获取下一个弟弟节点
+ previousElementSibling / nextElementSibling:获取
哥哥和弟弟的元素节点(不兼容IE6-8)
+ ···
```
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>节点操作</title>
</head>
<body>
<ul id="box">
<!-- 课程大纲 -->
<li>GIT和NPM操作</li>
<li>面向对象好原型:研究插件源码,自己写插件</li>
<li>闭包作用域:堆栈内存处理</li>
<li id="fangqi">ES6从入门开始</li>
<li>同步异步编程及核心:微任务、宏任务、事件循环</li>
<li>DOM及事件模型</li>
<li>JQuery及源码分析</li>
<li>设计模式:发布订阅、单例、Promise、PromiseA+</li>
若觉得上边难,下边更难
<li>AJAX及跨域解决方案:封装一款牛*的AJAX库</li>
<li>一入http深似海</li>
<li>性能安全优化</li>
<!-- 以上都是毛毛雨 -->
<li>VUE全家桶:vue-cli\vue\vue-router\vuex\vue
element...</li>
<li>vue和vuex的核心源码</li>
<li>REACT全家桶:create-react-app、antd、antdpro、
react、react-dom、react-native、react-router-dom、redux、
react-redux、dva、redux-sage、mobx...</li>
<li>REACT核心原理</li>
<li>REDUX源码和中间件编写</li>
<!-- 只有这些还不够,增添逼格 -->
<li>webpack</li>
<li>node和express</li>
<li>type script</li>
<li>...</li>
天,知识点好多···
</ul>
<!-- import Js -->
<script src="/11节点操作.js"></script>
</body>
</html>
let box=document.getElementById('box');
//标准浏览器(非IE6-8)中会把空格和换行当做文本节点处理
(childNodes包含所有节点)
// console.log(box.childNodes);
// 只想要元素节点(但是IE6-8下,使用children会把注释也当
做元素节点)
// console.log(box.children.length);
/*
children:获取指定上下文中,所有元素子节点
@params
context[element oblect]指定上下文元素信息
@return
[array]返回所有的元素子节点集合
by ct on 20230216
*/
/* function children(context){
//1.先获取所有的子节点
let res=[],
nodeList=context.childNodes;
//2.循环遍历所有的子节点,找出元素子节点,存储到res中即可
for(var i=0;i<nodeList.length;i++){
var item=nodeList[i];
item.nodeType===1?res.push(item):null;
}
return res;
} */
// console.log(children(box));//jquery中children的源码
//====================================
// console.log(box.firstChild);
// console.log(box.firstElementChild);
var fangqi=document.getElementById('fangqi');
// console.log(fangqi.previousSibling);
// console.log(fangqi.previousElementSibling);
//获取上一个哥哥元素节点
function prev(context){
//先找自己的哥哥
var pre =context.previousSibling;
//如果哥哥不是元素,则找哥哥的哥哥,一直到找到的是元素
节点为止
while(pre.nodeType!==1){
pre=pre.previousSibling;
}
return pre;
}
console.log(prev(fangqi));
//jquery中提供一些方法供我们获取元素:children、prev、
next、prevAll、nextAll、sibling、siblings、index...
```
#### 12.在JS中动态增删改元素
`createElement 创建元素对象`
`createTextNode 创建文本对象`
`appendchild 把元素添加到容器的末尾`
`inserBefore 把元素添加到指定容器中指定元素的前面`
```
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>操作DOM</title>
<style>
.RED {
color: red;
background: blue;
}
</style>
</head>
<body>
<div id="heihei">嘿嘿</div>
<script>
//动态创建一个div元素对象,把其赋给box
let box = document.createElement('div');
box.id = 'boxActive';
box.style.width = '200px';
box.style.height = '30px';
box.className = 'RED';
let text = document.createTextNode('哈哈');
// console.dir(text);
//添加:容器.appendchild(元素)
box.appendChild(text);
// document.body.appendChild(box);
//放到指定元素前:容器.insertBefore([指定元素],
[新增元素])
let heihei=document.getElementById('heihei');
// heihei.parentNode.insertBefore(...)
document.body.insertBefore(box,heihei);
</script>
</body>
</html>
```
`cloneNode(true/false) 克隆元素或者节点`
`removeChild移除容器中的某个元素`
```
<div class="box">
<span>我是中国人1</span>
</div>
<script>
let box1 = document.querySelector('.box');
//克隆第一份(深克隆:子元素及后代都克隆)
let box2 = box1.cloneNode(true);
box2.querySelector('span').innerText='我是中国人2';
//克隆第二份(浅克隆:只克隆子元素)
let box3 = box1.cloneNode(false);
box3.innerHTML="<span>我是中国人3</span>";
document.body.appendChild(box2);
document.body.appendChild(box3);
//========================移除第二个元素
document.body.removeChild(box2);
</script>
```
#### 13.自定义属性
`setAttribute / getAttribute / removeAttribute 设置获取
移除元素的自定义属性信息(这种方式是把自定义属性放到元素结构上)`
```
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>自定义属性</title>
</head>
<body>
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<!-- import JS -->
<script>
var btnList = document.querySelectorAll('button');
for (var i = 0; i < btnList.length; i++) {
//设置自定义属性:元素对象.属性名=属性值(原理是向
元素对象对应的堆内存中添加了一个属性)
// btnList[i].myIndex = i + 1;
//设置自定义属性:基于set-attribute是把属性信息
写到了元素标签的结构上(在结构中可以看到),并没有放到元素对象
对应的堆内存中
btnList[i].setAttribute('data-index',i+1);
btnList[i].onclick = function () {
//获取自定义属性:元素对象.属性名(原理是从堆内存
中获取到对应的属性值)
//alert(this.myIndex);
//基于get-attribute可以吧结构上存储的自定义属性
值获取
alert(this.getAttribute('data-index'));
}
}
</script>
</body>
</html>
```
//1-6index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>11111</title>
</head>
<body>
<script src="js/6-ueryURLPqarameter.js">
</script>
</body>
</html>
//1-math的方法
// console.log(typeof (Math));//=>"object"
// console.dir(Math);
/*
* Math={
* PI:3.141592653589793
* abs:function(){[native code]}
* ceil:function(){[native code]}
* ···
* }
* Math.abs();
* Math.PI;
*/
/*
console.log(Math.abs(-12.5));//=>12.5
console.log(Math.abs(12));//=>12
console.log(Math.abs(0));//=>0
//不是数字类型的值:先基于Number()转换为数字再处理
console.log(Math.abs('-1'));//=>1
console.log(Math.abs('-1px'));//=>NaN
console.log(Math.abs(true));//=>1
*/
/*
console.log(Math.ceil(12));//=>12
console.log(Math.ceil(12.1));//=>13
console.log(Math.ceil(12.9));//=>13
console.log(Math.ceil(-12.1));//=>-12
console.log(Math.ceil(-12.9));//=>-12
console.log(Math.floor(12));//=>-12
console.log(Math.floor(12.1));//=>12
console.log(Math.floor(12.9));//=>12
console.log(Math.floor(-12.1));//=>-13
console.log(Math.floor(-12.9));//=>-13
*/
/*
console.log(Math.round(12));//=>12
console.log(Math.round(12.1));//=>12
console.log(Math.round(12.5));//=>13
console.log(Math.round(12.9));//=>13
console.log(Math.round(-12.1));//=>-12
console.log(Math.round(-12.5));//=>-12(负数中 .5舍)
console.log(Math.round(-12.9));//=>-13
*/
/*
console.log(Math.max(12,5,68,23,45,3,28));//=>68
console.log(Math.min(12,5,68,23,45,3,28));//=>3
*/
/*
console.log(Math.sqrt(9));//=>3
console.log(Math.sqrt(-9));//=>NaN
console.log(Math.pow(2,10));//=>1024
*/
/* for (let i = 0; i <= 10; i++) {
console.log(Math.random());
} */
/*
0.2351119504604302
0.8103880292045642
0.9153034803838505
···
*/
//获取1-10之间的随机整数
// console.log(Math.round(Math.random()*9+1));
/* for (let i = 0; i <= 10; i++) {
let ran = Math.round(Math.random() * (30 - 25) + 25);
console.log(ran);
}
*/
//2-数组的方法
// let ary=[12,23,34,45];
// console.log(typeof(ary));//=>object
// console.dir(ary);
/*
ary{
0:12,
1:23,
2:34,
3:45,
length:4
}
数字作为索引(key属性名)
length代表长度
ary[0]根据索引获取指定项的内容
ary.length 获取数组的长度
ary.length-1最后一项的索引
*/
/*
push:向数组末尾增加内容
参数:@params
多个任意类型
返回值:@return
新增后数组的长度
*/
/* let ary=[10,20];
let res=ary.push(30,'AA');
//基于原生JS操作键值对的方法,也可以向末尾追加一项新的内容
ary[ary.length]=40;
console.log(res,ary); //=>4 [10,20,30,'AA',40]
*/
/*
unshift:向数组开始位置增加内容
参数:@params
多个任意类型
返回值:@return
新增后数组的长度
*/
/* let ary = [10, 20];
let res = ary.unshift(30, 'AA');
//基于原生ES6展开运算符,把原有的ary克隆一份,在新的
数组中创建第一项,其余的内容实用原始ary中的信息即可,
也算实现了向开始追加的效果
ary = [100, ...ary];
console.log(res, ary);//=>4 [30,'AA',10,20] */
/* shift:删除数组中的第一项
参数:@params
返回值:@return
删除的那一项
*/
/* let ary=[10,20,30,40];
let res=ary.shift();
console.log(res,ary);//=> 10 [20,30,40]
//基于原生JS中的delete,把数组当做普通的对象,确实
可以删除某一项内容,但是不会影响数组本身的结构特点
(length长度不会跟着修改),真实项目中杜绝这样的删除使用
delete ary[0];
console.log(res,ary);//=>{1:30,2:40,length:3} */
/*
pop:删除数组中的最后一项
参数:@params
返回值:@return
删除的那一项
*/
/* let ary=[10,20,30,40];
let res=ary.pop();
console.log(res,ary);//=>40 [10,20,30]
//基于原生JS让数组长度删掉一位,默认删除最后一项
ary.length--;//ary.length = ary.length - 1;
console.log(res,ary);//=>40 [10,20] */
/*
splice:实现数组的增加、删除、修改
参数:@params
n,m都是数字 从索引n开始删除m个元素
返回值:@return
把删除的部分用新数组存储起来返回
*/
/* let ary = [10, 20, 30, 40, 50, 60, 70, 80, 90];
let res = ary.splice(2, 4);
console.log(res, ary);//=>[30,40,50,60]
[10,20,70,80,90] */
//基于这种办法可以清空一个数组,把原始数组中的内容以新
数组存储起来(类似数组的克隆:把原始数组克隆一份一模一
样的给新数组)
/* ary.slice(0);
console.log(ary);//[10,20,70,80,90] */
//删除最后一项
/*
ary.splice(ary.length - 1);
console.log(ary);//=>[10,20,70,80]
//删除第一项
ary.splice(0, 1);
console.log(ary);//=>[20,70,80]
*/
/*
splice:实现数组的增加、修改
参数:@params
n,m,x 从索引n开始删除m个元素,用x占用删除的部分
n,0,x 从索引n开始,一个都不删,把x放到索引n的前面
返回值:@return
把删除的部分用新数组存储起来返回
*/
/*
let ary = [10, 20, 30, 40, 50];
let res = ary.splice(1,2,'哈哈哈');
console.log(res, ary);//=>[20,30] [10,'哈哈哈',40,50]
//实现增加
ary.splice(3,0,'嘻嘻')
console.log(ary);//=>[10, '哈哈哈', 40, '嘻嘻',
50]
//向数组末尾追加
ary.splice(ary.length,0,'AAA');
console.log(ary);//=>[10, '哈哈哈', 40, '嘻嘻',
50, 'AAA']
//向数组开端追加
ary.splice(0,0,'BBB');
console.log(ary);//=>['BBB', 10, '哈哈哈', 40,
'嘻嘻', 50, 'AAA']
*/
//=======================================
/*
slice:实现数组的查询
参数:@params
n,m 都是数字 从索引n开始,找到索引为m
的地方(不包含m这一项)
返回值:@return
把找到的内容以一个新数组的形式返回
*/
/*
let ary=[10,20,30,40,50];
let res=ary.slice(-1,-3);
console.log(res);//=>[20,30]
*/
//m不写是找到末尾
// res=ary.slice(1);
// console.log(res);//=>[20,30,40,50]
//数组的克隆,参加0不写也可以
// res=ary.slice(0);
// console.log(res);//=>[10,20,30,40,50]
//思考:
// 1.如果n、m是负数会怎么样?若n>m会怎么样?如果是
小数会怎么样?若是非有效数字会怎么样?若m或n的值比
最大索引都大会怎么样?
// 若n为负,则无论m是正或负,均为空字符串
// 若n为正,
// 2.这种克隆方式叫浅克隆,深克隆如何处理?
/*
concat:实现数组拼接
参数:@params
多个任意类型值
返回值:@return
拼接后的新数组(原来数组不变)
*/
/*
let ary1=[1,2,3];
let ary2=[4,5,6];
let res=ary1.concat('QQQ',ary2);
console.log(res);
*/
/*
tostring:把数组转换为字符串
参数:@params
返回值:@return
转换后的字符串,每一项用逗号分隔(原来数组不变)
*/
/*
let ary=[1,2,3];
let res=ary.toString();
console.log(res); //=>"1,2,3"
console.log([].toString());//=>""
console.log([12].toString());//=>"12"
*/
/*
join:把数组转换为字符串
参数:@params
指定的分隔符(字符串格式)
返回值:@return
转换后的字符串(原来数组不变)
*/
/*
let ary=[1,2,3];
// let res=ary.join('');
// console.log(res); //=>"123"
// let res=ary.join('|');
// console.log(res); //=>"1|2|3"
// let res=ary.join();
// console.log(res);
let res=ary.join('+');
console.log(res);
console.log(eval(res)); //=>eval把字符串变为JS表达式执行
*/
/*
indexOf / lastIndexOf:检测当前项在数组中第一次
或者最后一次出现位置的索引值(在IE6-8中不兼容)
参数:@params
要检索的这一项内容
返回值:@return
这一项出现的位置索引值(数字),如果数组中没
有这一项,返回的结果是-1
原来数组不变
*/
/* let ary = [1, 2, 3, 1, 2, 3];
console.log(ary.indexOf(2));//=>1
console.log(ary.lastIndexOf(2));//=>4
//验证ary中是否包含'哈哈哈'
if (ary.indexOf('哈哈哈') === -1){
//不包含
}
//也可以直接使用ES6新提供的includes方法判断
if(ary.includes(3)){
//包含:如果存在返回的是true
} */
/*
reverse:把数组倒过来排列
参数:@params
返回值:@return
排列后的新数组
原来数组改变
*/
/* let ary = [12, 15, 9, 28, 10, 22];
ary.reverse();
console.log(ary);//=>[22, 10, 28, 9, 15, 12] */
/*
sort :实现数组的排序
参数 :@params
可以没有,也可以是个函数
返回值 :@return
排列后的新数组
原来数组改变
*/
// let ary = [4,7,5,8,3,6,1,9,2];
// ary.sort();
// console.log(ary);//=>[1, 2, 3, 4, 5, 6, 7, 8, 9]
//sort 方法中如果不传递参数,是无法处理10以上数字排序的
(它默认按照每一项第一个字符来排序,不是按照数值大小排的)
/* let ary = [12, 15, 9, 28, 10, 22];
ary.sort();
console.log(ary);//=>[10, 12, 15, 22, 28, 9] */
//实现多位数正常排序,需要给sort传递一个函数,函数中返回
a-b 实现升序,返回b-a 实现降序(? 需了解冒泡排序的机制)
/* let ary = [12, 15, 9, 28, 10, 22];
//ary.sort(function(a,b){return a-b});
//a和b是相邻的两项
ary.sort((a, b) => a - b);
console.log(ary);//=>[9, 10, 12, 15, 22, 28]
*/
/*
forEach :遍历数组中的每一项内容
参数 :@params
回调函数
返回值 :@return
原来数组改变
*/
let ary = [1, 5, 9, 6, 5, 12, 14];
/* //基于原生JS中的循环可以实现
for (let i = 0; i < ary.length; i++) {
//i:当前循环这一项的索引
//ary[i]:根据索引获取循环的这一项
console.log('索引:' + i + '内容:' + ary[i]);
} */
ary.forEach((item, index) => {
// 数组中有多少项,函数就会被默认执行多少次
//每一次执行函数:item是数组中当前要操作的这一项,
index是当前项的索引
console.log('索引:' + index + '内容:' + item);
});
//3-数组去重
// let ary = [1, 2, 3, 1, 2, 1, 2, 3, 2, 1, 2, 3];
//=>[1,2,3]
/*
方案一:
循环原有数组中的每一项,每拿到一项都往新数组中添加
添加之前验证新数组中是否存在这一项,不存在再添加
*/
/* let newAry = [];
for (let i = 0; i < ary.length; i++) {
//循环获取原有数组中的每一项
let item = ary[i];
//验证新数组中是否存在这一项
if (newAry.includes(item)) {
//存在这一项,不再增加到新数组,继续下一轮循环即可
continue;
}
//新数组中不存在这一项,我们加入到新数字即可
newAry.push(item);
}
console.log(newAry); */
/* //方案一优化
let newAry = [];
ary.forEach(item => {
if (newAry.includes(item)) return;
newAry.push(item);
});
console.log(newAry); */
/*
方案二:
先分别拿出数组中的每一项A
用这一项A和它后边的每一项依次进行比较,如果遇到和
当前项A相同的,则在原来数组中把这一项移除掉
不用includes/indexOf,保证兼容性
*/
/* var ary = [1, 2, 3, 1, 2, 1, 2, 3, 2, 1, 2, 3];
for (var i = 0; i < ary.length; i++) {
//item:每一次循环拿出来的当前项
//i:当前项索引
var item = ary[i];
//itemLast:当前项后边所有的内容(新数组)
//var itemLast = ary.slice(i + 1); //创建数组耗性能
//i+1:代表后一项
//让当前项与后边的每一项进行比较(循环)
for (var j = i + 1; j < ary.length; j++) {
//compare:后边需要比较的每一项
var compare = ary[j];
//如果compare和item相等,说明这一项是重复的,把他删掉
if (compare === item) {
//j索引这一项要从数组中移除
ary.splice(j, 1);
//数组塌陷了:j后边的每一项索引都提前了一位,下
一次要比较还是j这个索引的内容
j--;
}
}
}
console.log(ary); */
/* var ary = [1, 2, 3, 1, 2, 1, 2, 3, 2, 1, 2, 3];
for( var i=0;i<ary.length;i++){
//第一轮:
//i=0 item=1 拿到第一项
//第二轮
//i=1 item=2 拿到第二项
var item=ary[i];
for(var j=i+1;j<ary.length;j++){
//j=1 compare=2 2!==1
//j=2 compare=3 3!==1
//j=3 compare=1 1===1 ary.splice(3,1);
[1, 2, 3, (1) 2, 1, 2, 3, 2, 1, 2, 3]
var compare=ary[j];
if(item===compare){
ary.splice(j,1);
j--;
}
}
}
console.log(ary); */
/*
方案三:
*/
/* let ary = [1, 2, 3, 1, 2, 1, 2, 3, 2, 1, 2, 3];
//1.创建一个空对象
let obj = {};
//2.循环数组中的每一项,把每一项向对象中进行存储 =>
item:item
for (let i = 0; i < ary.length; i++) {
let item = ary[i];
//3.存储之前进行判断:验证obj中是否存在这一项
if (obj[item] !== undefined) {
//已经存在这一项
ary.splice(i, 1);
i--;
continue;
}
obj[item] = item;//obj[1]=1;···
}
console.log(ary); */
//基于splice实现删除性能不好:当前项被删后,后面每一
项的索引都要向前提一位,如果后面内容过多,定影响性能
/*
let ary = [1, 2, 3, 1, 2, 1, 2, 3, 2, 1, 2, 3];
let obj = {};
for (let i = 0; i < ary.length; i++) {
let item = ary[i];
if (obj[item] !== undefined) {
ary[i] = ary[ary.length - 1];
ary.length--;
i--;
continue;
}
obj[item] = item;//obj[1]=1;···
}
console.log(ary);
*/
/*
unique:实现数组去重的方法
@params
ary[Array]要去重的数组
@return
[Array]去重后的数组
by ct on 20230214
*/
/* function unique(ary) {
let obj = {};
for (let i = 0; i < ary.length; i++) {
let item = ary[i];
if (obj[item] !== undefined) {
ary[i] = ary[ary.length - 1];
ary.length--;
i--;
continue;
}
obj[item] = item;
}
return ary;
}
let aa = [1, 5, 6, 8, 12, 1, 2, 5, 6, 15, 47, 12, 47];
aa = unique(aa);
aa.sort((a, b) => a - b);
console.log(aa);//=>[1, 2, 5, 6, 8, 12, 15, 47] */
//正则
// let ary = [1, 5, 6, 8, 12, 1, 2, 5, 6, 15, 47, 12, 47];
// ary.sort((a, b) => a - b);
// let str = ary.join('@') + '@';
// let reg = /(\d+@)\1*/g;
// console.log(str.match(reg));
// ary = [];
// str.replace(reg, (n, m) => {
// m = Number(m.slice(0, m.length - 1));
// ary.push(m);
// });
// console.log(ary);//=>[1, 2, 5, 6, 8, 12, 15, 47]
//基于ES6的set(对应的Map)实现去重
let ary = [1, 5, 6, 8, 12, 1, 2, 5, 6, 15, 47, 12, 47];
ary = [...new Set(ary)];
console.log(ary);//=>[1, 5, 6, 8, 12, 2, 15, 47]
数组去重解析一
数组去重解析二
数组去重解析三
// 4-字符串
/* let str = 'hahahahahah';
//循环输出字符串中的每一个字符
for(let i=0;i<str.length;i++){
let char = str[i];
console.log(char);
}
*/
/*
charAt:根据索引获取指定位置的字符
charCodeAt:获取指定字符的ASII码值(Unicode编码值)
@params
n[number] 获取字符指定的索引
@return
返回查找到的字符
找不到返回的是空字符串㐊undefined,或者对应的编码值
*/
/*
let str = 'hahahahahah';
console.log(str.charAt(0)); //=>'h'
console.log(str[0]); //=>'h'
console.log(str.charAt(100)); //=>''
console.log(str[100]); //=>undefined
console.log(str.charCodeAt(0)); //=>104
console.log(String.fromCharCode(str.charCodeAt(0)));
//=>'h'
*/
/*
都是为了实现字符串截取(在原来字符串查找到自己想要的)
substr(n,m):从索引n开始截取m个字符,m不写截取到末尾
(其他的方法也是)
substring(n,m):从索引n开始找到索引m处(不包含m)
slice(n,m):和substring一样,都是找到索引m处,但
slice可以支持负数作为索引,其余两个方法不可以
*/
/*
let str = 'hahahahahaha';
console.log(str.substr(3,7));//=>'ahahaha'
console.log(str.substring(3,7));//=>'ahah'
console.log(str.substr(3));//=>'ahahahaha' 截取
到末尾
console.log(str.substring(3,100));//=>'ahahahaha'
截取到末尾(超过索引的也只截取到末尾)
console.log(str.substring(3,7));//=>'ahah'
console.log(str.slice(3,7));
console.log(str.substring(-7,-3));//=>'' substring
不支持负数索引
console.log(str.slice(-7,-3));//=>'nqit' slice支持
负数索引 快捷查找:负数索引,按照STR.length+负索引的
方式找 =>slice(12-7,12-3) =>slice(5,9) =>ahah
*/
/*
验证字符是否存在
indexOf(x,y):获取x第一次出现位置的索引,y是控制
查找的起始位置索引
lastIndexOf(x):最后一次出现位置的索引
=>没有这个字符,返回的结果是-1
*/
/*
let str = 'hahahahahaha';
console.log(str.indexOf('h'));//=>0
console.log(str.lastIndexOf('h'));//=>10
console.log(str.indexOf('!'));//=>-1 不存在返回-1
if(str.indexOf('!')===-1){
//字符串中不包含!这个字符
}
console.log(str.indexOf('aha'));//=>1 验证整体第一
次出现的位置,返回的索引是第一个字符所在位置的索引值
console.log(str.indexOf('ahan'));//=>-1
console.log(str.indexOf('ha',5));//=>6 查找索引5
及之后的字符串中,ha第一次出现的位置索引
if(!str.includes('!')){
console.log('当前字符串不包含!');
}
*/
/*
字符串中字母的大小写转换
toUpperCase():转大写
toLowerCase():转小写
*/
/*
let str = 'Hahahahahaha';
str = str.toUpperCase();
console.log(str);//=>'HAHAHAHAHAHA'
str = str.toLowerCase();
console.log(str);//=>'hahahahahaha'
//实现首字母大写
str = str.substr(0, 1).toUpperCase() +
str.substr(1);
console.log(str);//=>Hahahahahaha
*/
/*
split([分隔符]):把字符串按照指定的分隔符拆分成
数组(和数组里的join相对应)
split支持传递正则表达式
*/
//需求:把|分隔符变为,分隔符
/*
let str = 'music|movie|eat|sport';
let ary=str.split('|');//=>['music', 'movie',
'eat', 'sport']
console.log(ary);
str=ary.toString();
console.log(str);//=>music,movie,eat,sport
str=ary.join(',');
console.log(str);//=>music,movie,eat,sport
*/
/*
replace(老字符,新字符):实现字符串的替换
(经常伴随着正则使用)
*/
let str='哈喽!你好!是吧?';
/* str=str.replace('!','+');
console.log(str);//=>哈喽+你好!是吧? 在不使用
正则表达式的情况下,执行一次replace只能替换一次字符 */
str=str.replace(/!/g,'-');
console.log(str);//=>哈喽-你好-是吧?
// 5-时间
// let time = '2023-2-14 19:45:45';
//=>变为自己需要呈现的格式,例如:
//"2023年2月14日 19点45分45秒"
//"2023年2月14日"
//"2/14 19:45"
//···
//方案一:
/*
let time = '2023-2-14 19:45:45';
time = time.replace('-', '年').replace('-', '月')
.replace(' ', '日 ').replace(':', '时')
.replace(':', '分') + '秒';
console.log(time);//=>2023年2月14日 19时45分45秒
*/
//方案二:获取年月日时分秒这几个值,按照所想拼出效果
//不足十位补零
/*
let addZero = val => {
if (val.length < 2) {
val = '0' + val;
}
return val;
};
*/
/*
let addZero = val => val.length < 2 ? '0' + val : val;
let time = '2023-2-14 19:45:45';
let ary = time.split(/(?: |-|:)/g);//=>['2023', '2',
'14', '19', '45', '45']
time = ary[0] + '年' + addZero(ary[1]) + '月' +
addZero(ary[2]) + '日';
console.log(time);//=>2023年02月14日
*/
//获取值的方法:基于split一项项拆分
/*
let time = '2023-2-14 19:45:45';
let n = time.split(' ');//=>["2023-2-14" ,"19:45:45"]
let m = n[0].split('-')//=>["2023","2","14"]
let x = n[1].split(':');//=>["19","45","45"]
console.log(x);
*/
//获取值的方法:基于indexOf获取指定符号索引,基于
substring一点点截取
/*
let time = '2023-2-14 19:45:45';
let n = time.indexOf('-');
let m = time.lastIndexOf('-');
let x = time.indexOf(' ');
let y = time.indexOf(':');
let z = time.lastIndexOf(':');
let year = time.substring(0, n);
let month = time.substring(n + 1, m);
let day = time.substring(m + 1, x);
console.log(year, month, day); */
// 6-queryURLParameter
// let url = 'http://www.zhufengpeixun.cn/index.html?lx=1&name=zhufeng&teacher=aaa#box';
/*
结果:{
lx:1,
name:'zhufeng',
teacher:'aaa',
HASH:'box'
}
*/
/* //1.获取问号或者井号后边的值
let askIndex = url.indexOf('?');
let wellIndex = url.indexOf('#');
let askText = url.substring(askIndex + 1, wellIndex);
let wellText = url.substring(wellIndex + 1);
console.log(askText, wellText);
// askText="lx=1&name=zhufeng&teacher=aaa"
// wellText="box"
//2.问号后边值的详细处理
let result = {};
let askAry = askText.split('&');
console.log(askAry);
//=>['lx=1', 'name=zhufeng', 'teacher=aaa']
askAry.forEach(item => {
//item:当前从数组中循环的这一项
let n = item.split('=');
console.log(n);
// ['lx', '1']
// ['name', 'zhufeng']
// ['teacher', 'aaa']
let key = n[0];
let value = n[1];
result[key] = value;
});
result['HASH'] = wellText;
console.log(result);
//=>{lx: '1', name: 'zhufeng', teacher: 'aaa',
HASH: 'box'} */
/*
queryURLParams:获取URL地址中间问号传参的信息和哈希值
@params
URL[string]要解析的url字符串
@return
[object]包含参数和哈希值信息的对象
by ct on 20230214
*/
/* function queryURLParams(url) {
//1.获取?和#后边的信息
let askIn = url.indexOf('?'),
wellIn = url.indexOf('#'),
askText = '',
wellText = '';
//#不存在
wellIn === -1 ? wellIn = url.length : null;
//?存在
askIn >= 0 ? askText = url.substring(askIn + 1,
wellIn) : null;
wellText = url.substring(wellIn + 1);
//2.获取每部分信息
let result = {};
wellText !== '' ? result['HASH'] = wellText : null;
if (askText !== '') {
let ary = askText.split('&');
ary.forEach(item => {
let itemAry = item.split('=');
result[itemAry[0]] = itemAry[1];
});
}
return result;
}
*/
//基于正则封装、完美
function queryURLParams(url) {
let result = {},
reg1 = /([^?=&#]+)=([^?=&#]+)/g;
reg2 = /#([^?=&#]+)/;
url.replace(reg1, (n, x, y) => result[x] = y);
url.replace(reg2, (n, x) => result['HASH'] = x);
return result;
}
let url = 'http://www.zhufengpeixun.cn/index.html?lx=1&name=zhufeng&teacher=aaa#box';
let paramsObj = queryURLParams(url);
console.log(paramsObj);
//7-验证码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>简单的验证码</title>
</head>
<body>
<input type="text" id="codeInp">
<br>
<span id="codeBox">aaaa</span>
<button id="changeCode">看不清,换一张</button>
<!-- import Js -->
<script>
let codeInp = document.getElementById('codeInp'),
codeBox = document.getElementById('codeBox'),
changeCode = document.getElementById('changeCode');
/*
queryCode:获取到四位随机验证码,然后放到指定的盒子中
@params
@return
by ct on 20230214
*/
function queryCode() {
let area = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
0123456789";
let result = "";
for (let i = 0; i < 4; i++) {
//每一次循环都获取一个随机的数字索引
let ran = Math.round(Math.random() * 61);
//再根据获取的索引从范围字符串中找到对应的字符,
把找到的字符拼接到最后的结果中
result += area.charAt(ran);
}
//放到盒子里
codeBox.innerHTML = result;
}
//第一次加载页面需要执行方法,让其显示在页面中
queryCode();
//点击看不清按钮,需要重新执行方法生成新的验证码
changeCode.onclick = queryCode;
//文本框失去焦点的时候:验证用户输入法人内容和验证
码是否相同,给予相关的提示,如果不一样需要重新生成验证码
//onblur:文本框失去焦点事件
codeInp.onblur = function () {
//获取用户和验证码内容(表单元素.value / 非表单
元素.innerHTML 获取内容)
let val = codeInp.value,
code = codeBox.innerHTML;
//不区分大小写的验证(都转小写)
if (val.toLowerCase() === code.toLowerCase()) {
alert('温馨提示:验证码输入成功!');
} else {
alert('温馨提示:验证码输入错误,请重新输入!');
codeInp.value = '';
//重新生成验证码
queryCode();
}
}
</script>
</body>
</html>
//8-小时钟
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>小时钟</title>
<!-- import css -->
<style>
* {
margin: 0;
padding: 0;
}
#clockBox {
position: absolute;
right: 0;
top: 0;
padding: 0 15px;
line-height: 50px;
font-size: 20px;
color: black;
/* 设置背景渐变色 */
/* background:lightblue ; */
background: -webkit-linear-gradient
(top left, lightcoral, lightcyan);
}
</style>
</head>
<body>
<div id="clockBox">
2023年02月15日 星期三 16:24:01
</div>
<!-- import JS -->
<script>
let clockBox = document.getElementById
('clockBox');
/*
addZero:不足十补领
@params
val需要处理的值
@return
处理后的结果
by ct on 20230215
*/
function addZero(val) {
val = Number(val);
return val < 10 ? '0' + val : val;
}
/*
queryDate:获取当前日期,把其转换为想要的格式
@params
@return
by ct on 20230215
*/
function queryDate() {
//1.获取当前日期及详细信息
let time = new Date(),
year = time.getFullYear(),
month = time.getMonth() + 1,
day = time.getDate(),
week = time.getDay(),
hours = time.getHours(),
minutes = time.getMinutes(),
seconds = time.getSeconds();
//2.拼凑成想要的字符串
let result = year + "年" + addZero(month)
+ "月" + addZero(day) + "日";
let weekAry = ['日', '一', '二', '三', '四',
'五', '六'];
result += " 星期" + weekAry[week] + " ";
result += addZero(hours) + ":" +
addZero(minutes) + ":" + addZero(seconds);
//3.把处理好的结果放盒子里
clockBox.innerHTML = result;
}
//加载页面执行方法
queryDate();
//定时器控制运动:设置一个setInterval定时器
(到达指定时间做对应的事的东西就是定时器),每隔1000ms
执行queryDate方法
setInterval(queryDate, 1000);
</script>
</body>
</html>
//9-时间格式化
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>时间格式化</title>
</head>
<body>
<script>
let addZero = val => {
val = Number(val);
return val < 10 ? '0' + val : val;
}
/*
字符串处理
*/
/* function formatTime(time) {
//1.获取年月日星期
// let ary=time.split(/(?: |-|:)/g);
let ary = time.split(' ');
let aryLeft = ary[0].split('-'),
aryRight = ary[1].split(':');
ary = aryLeft.concat(aryRight);
//=>['2023', '2', '15', '12', '0', '0']
//2.拼接为想用的格式
let result = ary[0] + "年" + addZero(ary[1])
+ "月" + addZero(ary[2]) + "日";
result += " " + addZero(ary[3]) + ":"
+ addZero(ary[4]) + ":" + addZero(ary[5]);
return result;
}
let time = '2023-2-15 12:0:0';
//=>"2023年02月15日 12:00:00"
time = formatTime(time);
console.log(time);
//=>2023年02月15日 12:00:00*/
/*
基于日期对象处理
*/
/* function formatTime(time) {
//1.把时间字符串变为标准日起对象
// time = time.replace(/-/g,'/');
time = time.replace('-', '/');
time = time.replace('-', '/');
time = new Date(time);
//2.基于方法获取年月日等信息
let year = time.getFullYear(),
month = addZero(time.getMonth() + 1),
day = addZero(time.getDate()),
hours = addZero(time.getHours()),
minutes = addZero(time.getMinutes()),
seconds = addZero(time.getSeconds());
//3.返回想要的结果
return year+"年"+month+"月"+day+"日"+hours+"时"+minutes+"分"+
seconds+"秒";
}
let time = '2023-2-15 12:0:0';
//=>"2023年02月15日 12:00:00"
time = formatTime(time);
console.log(time);
//=>2023年02月15日 12:00:00*/
/*
封装一套公共的时间字符串格式化处理函数
*/
String.prototype.formatTime = function
formatTime(template) {
typeof templete === 'undefined' ?
templete = "{0}年{1}月{2}日 {3}:{4}:{5}" : null;
//this:要处理的字符串
let matchAry = this.match(/\d+/g);
//模板和数据的渲染(引擎机制)
templete = templete.replace(/\{(\d+)\}/g,
(x, y) => {
let val = matchAry[y] || '00';
val.length<2?val='0'+val:null;
return val;
});
return templete;
};
let time = '2023-2-15 12:0:0';
//=>"2023年02月15日 12:00:00"
console.log(time.formatTime());//传一个模板
//=>2023年02月15日 12:00:00
</script>
</body>
</html>
//10-获取元素
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>获取元素</title>
</head>
<body>
<!-- <div class="tabBox" id="tabBox">
<ul class="tab" id="tab">
<li>第1个页卡</li>
<li>第2个页卡</li>
<li>第3个页卡</li>
</ul>
<div>
第1个要展示的内容
<ul class="news">
<li>热门新闻1</li>
<li>热门新闻2</li>
<li>热门新闻3</li>
<li>热门新闻4</li>
<li>热门新闻5</li>
</ul>
</div>
<div>
第2个要展示的内容
<div class="detail"></div>
</div>
<div>第3个要展示的内容</div>
</div> -->
<div class="formBox">
性别:
<!-- name在表单中是用来分组的 -->
<input type="radio" name="sex" value="男" checked>男
<input type="radio" name="sex" value="女" >女
<input type="radio" name="sex" value="未知">未知
<button id="submit">点击获取选中的是谁?</button>
</div>
<!-- import js -->
<script src="/10获取元素.html"></script>
</body>
</html>
//10获取元素js
// let tabBox=document.getElementById('tabBox');
//基于getElementByTagName / getElementsByClassName
获取到的元素集合,想要操作某个元素需要在集合中根据索引取
出来才可以使用
// let tabBox = document.getElementsByClassName
('tabBox')[0];
//querySelector获取的是一个元素对象,哪怕页面中有多个
符合的,也只获取第一个
//querySelectorAll获取的是一个集合,那怕只有一个符合,
也是一个集合,集合中只有一项
// let tabBox = document.querySelector('.tabBox');
//getElementsByTagName是获取指定上下文后代中所有的标签
名为N的元素集合
// let navList=tabBox.getElementsByTagName('li');
// let navList=tab.getElementsByTagName('li');
// let navList=tabBox.querySelectorAll('.tab li');
// let navList = document.querySelectorAll('.tab li');
// let divList = document.querySelectorAll('.tabBox>div');
// jquery:一个操作DOM元素的类库
// var $navlist=$('.tab li');
// var $divList=$('.tabBox>div');
// console.log($navList,$divList);
//===========================
var sexList=document.getElementsByName('sex');
var submit=document.getElementById('submit');
// var sexList = document.querySelectorAll('[name=sex]');
// var submit = document.querySelector('#submit');
console.log(sexList,submit);
submit.onclick=function(){
var res=null;
for(var i=0;i<sexList.length;i++){
var item=sexList[i];
if(item.checked){
//被选中
res=item.value;
break;
}
}
alert(res);
}
//11节点操作
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>节点操作</title>
</head>
<body>
<ul id="box">
<!-- 课程大纲 -->
<li>GIT和NPM操作</li>
<li>面向对象好原型:研究插件源码,自己写插件</li>
<li>闭包作用域:堆栈内存处理</li>
<li id="fangqi">ES6从入门开始</li>
<li>同步异步编程及核心:微任务、宏任务、事件循环</li>
<li>DOM及事件模型</li>
<li>JQuery及源码分析</li>
<li>设计模式:发布订阅、单例、Promise、PromiseA+</li>
若觉得上边难,下边更难
<li>AJAX及跨域解决方案:封装一款牛*的AJAX库</li>
<li>一入http深似海</li>
<li>性能安全优化</li>
<!-- 以上都是毛毛雨 -->
<li>VUE全家桶:vue-cli\vue\vue-router\vuex\vue
element...</li>
<li>vue和vuex的核心源码</li>
<li>REACT全家桶:create-react-app、antd、antdpro
、react、react-dom、react-native、react-router-dom、
redux、react-redux、dva、redux-sage、mobx...</li>
<li>REACT核心原理</li>
<li>REDUX源码和中间件编写</li>
<!-- 只有这些还不够,增添逼格 -->
<li>webpack</li>
<li>node和express</li>
<li>type script</li>
<li>...</li>
天,知识点好多···
</ul>
<!-- import Js -->
<script src="/11节点操作.js"></script>
</body>
</html>
//节点操作js
let box=document.getElementById('box');
//标准浏览器(非IE6-8)中会把空格和换行当做文本节点处理
(childNodes包含所有节点)
// console.log(box.childNodes);
// 只想要元素节点(但是IE6-8下,使用children会把注释也
当做元素节点)
// console.log(box.children.length);
/*
children:获取指定上下文中,所有元素子节点
@params
context[element oblect]指定上下文元素信息
@return
[array]返回所有的元素子节点集合
by ct on 20230216
*/
/* function children(context){
//1.先获取所有的子节点
let res=[],
nodeList=context.childNodes;
//2.循环遍历所有的子节点,找出元素子节点,存储到res中即可
for(var i=0;i<nodeList.length;i++){
var item=nodeList[i];
item.nodeType===1?res.push(item):null;
}
return res;
} */
// console.log(children(box));//jquery中children的源码
//====================================
// console.log(box.firstChild);
// console.log(box.firstElementChild);
var fangqi=document.getElementById('fangqi');
// console.log(fangqi.previousSibling);
// console.log(fangqi.previousElementSibling);
//获取上一个哥哥元素节点
function prev(context){
//先找自己的哥哥
var pre =context.previousSibling;
//如果哥哥不是元素,则找哥哥的哥哥,一直到找到的是
元素节点为止
while(pre.nodeType!==1){
pre=pre.previousSibling;
}
return pre;
}
console.log(prev(fangqi));
//jquery中提供一些方法供我们获取元素:children、prev、
next、prevAll、nextAll、sibling、siblings、index...
//12DOM动态操作
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>操作DOM</title>
<style>
.RED {
color: red;
background: blue;
}
.box {
margin-top: 10px;
width: 200px;
height: 100px;
background-color: lightblue;
}
.box span {
color: red;
font-size: 18px;
}
</style>
</head>
<body>
<!-- <div id="heihei">嘿嘿</div> -->
<div class="box">
<span>我是中国人1</span>
</div>
<script>
let box1 = document.querySelector('.box');
//克隆第一份(深克隆:子元素及后代都克隆)
let box2 = box1.cloneNode(true);
box2.querySelector('span').innerText='我是中国人2';
//克隆第二份(浅克隆:只克隆子元素)
let box3 = box1.cloneNode(false);
box3.innerHTML="<span>我是中国人3</span>";
document.body.appendChild(box2);
document.body.appendChild(box3);
//========================移除第二个元素
document.body.removeChild(box2);
</script>
<script>
/* //动态创建一个div元素对象,把其赋给box
let box = document.createElement('div');
box.id = 'boxActive';
box.style.width = '200px';
box.style.height = '30px';
box.className = 'RED';
let text = document.createTextNode('哈哈');
// console.dir(text);
//添加:容器.appendchild(元素)
box.appendChild(text);
// document.body.appendChild(box);
//放到指定元素前:容器.insertBefore([指定元素],[新增元素])
let heihei=document.getElementById('heihei');
// heihei.parentNode.insertBefore(...)
document.body.insertBefore(box,heihei); */
</script>
</body>
</html>
//13自定义属性
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>自定义属性</title>
</head>
<body>
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<!-- import JS -->
<script>
var btnList = document.querySelectorAll('button');
for (var i = 0; i < btnList.length; i++) {
//设置自定义属性:元素对象.属性名=属性值
(原理是向元素对象对应的堆内存中添加了一个属性)
// btnList[i].myIndex = i + 1;
//设置自定义属性:基于set-attribute是把
属性信息写到了元素标签的结构上(在结构中可以看到),并
没有放到元素对象对应的堆内存中
btnList[i].setAttribute('data-index',i+1);
btnList[i].onclick = function () {
//获取自定义属性:元素对象.属性名(原理是从
堆内存中获取到对应的属性值)
//alert(this.myIndex);
//基于get-attribute可以吧结构上存储的自定义
属性值获取
alert(this.getAttribute('data-index'));
}
}
</script>
</body>
</html>