1.前面知识小结
动态的生成html标签
需要: 空字符串
然后 ,遍历数据; 字符串拼接标签
模板字符串 ` `
变量 ${ }
var a = 'hello' ;
// document.write('<h1>' + a + '</h1>')
document.write(`<h1>${a}</h1>`)
对象的遍历 for(var key in obj) key字符串
对象属于引用数据类型
对象的深复制和浅复制,函数的引用传递:
深复制在于创建了一个新的空对象,再将被复制的对象的内容拿过来赋给这个对象,即复制了它的全部属性,浅复制跟数组类似只复制了地址(共享地址)
数组和对象的比较:
数组存储同一种类型的数据,它具有有序性,存数据
对象存储不同数据类型,它具有无序性,它也是对一类事物的描述
2.多维数组的深复制
//声明一个数组
var arr = [1,2,3,4,[ 2,5, [7,8] ] ] ;
//截取数组中的所有值,得到新的数组
var arr01 = arr.slice() ;
//函数封装它
function deepArr(arr){
//定义一个新的空数组
var newArr = [] ;
for(var i = 0 ; i < arr.length ; i++) {
//newArr.push(arr[i]) 这个arr[i]有可能是一个数组
if(Array.array(arr[i])) {
//继续遍历数组 , 还是得到一个数组
var list = deepArr(arr[i]) ;
//再把得到的数组放入newArr
newArr.push(list);
}
else {
newArr.push(arr[i]) ;
}
}
return newArr ;
}
console.log(despArr([1,2,3,4,[5,6]])) ;
var res = deepArr(arr) ;
res[4].push('a') ;
console.log(res) ;
console.log(arr) ;
3.字符串
字符串创建方式有2种
角标和长度
字符串的长度和角标只能读取,不能改写
var str = 'hello' //这是string类型
var str2 = new String('hello ') ; //这是object
console.log(typeof str2);
//坐标和长度
console.log(str.length) ;
console.log(str[0]);
//字符串的长度和角标只能读取 ,不能改写
//str[5] = 'w' ; //无效,加不了
str += 'w' ;
console.log(str);
4.字符串方法
includes 判断字符串中是否存在某个值
indexOf 判断字符串中是否存在某个值,存在就返回角标,不存在就返回-1
lastIndexOf 判断字符串中是否存在某个值,返回最后一次出现的下标
concat 字符串拼接
slice 截取字符串中的值,返回新的字符串
charAt() 访问角标对应的值
charCodet() 访问角标对应的值得ASCII值
String.fromCharCode() 把ASCII值转成对应的字符
substring(i , i)
substr(i , 数量)
trim() 去掉首位的空格
split() 把字符串切割成数组
replace(old , new) 替换(默认只会替换第一个)
toUpperCase() 大写
toLowerCase() 小写
var str = 'hello world' ;
// includes 判断字符串中是否存在某个值
console.log(str.includes('o'));
// indexOf 判断字符串中是否存在某个值,存在就返回角标,不存在就返回-1
console.log(str.indexOf('e'));
console.log(str.indexOf('x'));
// lastIndexOf
console.log(str.lastIndexOf('l'));
var str2 = 'rong' ;
// concat 字符串拼接
console.log(str.concat(str2));
console.log(str[0]); // h
// charCodeAt() 访问角标对应的值的ASCII值
console.log(str.charAt(1)); //e
// String.fromCharCode() 把ASCII值转成对应的字符
console.log(str.charCodeAt(1)); //101
// String.fromCharCode() 把ASCII值转成对应的字符
console.log(String.fromCharCode(97)); //a
console.log(String.fromCharCode(100)); //d
// substring(i , i) 截取角标到角标之间的内容,包前,但是不包后面
console.log(str.substring(1,3)); //el
// substr(i , 数量) 取从角标i开始的内容后边的部分根据给出数量来
console.log(str.substr(1,3)); //ell
// trim() 去掉首尾的空格
var str2 = ' wwww bai du ' ;
console.log(str2); // wwww bai du 空格也在控制台被打印
console.log(str2.trim()); //wwww bai du 首位空格被去掉
// split() 把字符串切割成数组
var str3 = 'rong=ren=qian=qqq' ;
console.log(str3.split('=')); // ['rong', 'ren', 'qian', 'qqq']
console.log(str3.split(''));// ['r', 'o', 'n', 'g', '=', 'r', 'e', 'n', '=', 'q', 'i', 'a', 'n', '=', 'q', 'q', 'q']
// replace(old , new) 替换(默认只会替换第一个)
var str = '就这,也就那样吧,就这啊' ;
console.log(str.replace('就这' ,'**'));
var res = str.replace('就这' , '**' );
document.write(res);
// toUpperCase() 大写
// toLowerCase() 小写
var str = 'baby';
var str2 = 'BABY' ;
//不分大小写 都转为大写或者小写然后再做比较
if(str.toLocaleLowerCase === str2.toLocaleLowerCase) {
document.write('<br>')
document.write('不愧是你') ;
}
5.随机验证码
<style>
#code{
display: inline-block;
background-color: #ddd;
padding: 4px;
letter-spacing: 2px;
font-style: italic;
}
</style>
<input type="text" id="inp">
<span id="code">dwef</span>
<span id="msg">验证码不分大小写</span>
<br>
<button id="btn">验证</button>
<script>
var numArr = [] ;
for(var i = 0 ; i < 10 ; i++) {
numArr.push(i + '') ;
}
console.log(numArr);
var smallArr = [] ;
for(var i = 97 ; i <= 122 ; i++) {
smallArr.push(String.fromCharCode(i))
}
console.log(smallArr);
var bigArr = [] ;
for(var i = 65 ; i <= 90 ; i++) {
bigArr.push(String.fromCharCode(i))
}
console.log(bigArr);
var allArr = numArr.concat(smallArr , bigArr) ;
console.log(allArr);
// 第一个参数是最大值,第二个参数是最小值,最小值默认是0
function rand(max , min) {
min = min || 0 ;
return parseInt(Math.random() * (max - min) + min)
}
// console.log(rand(100 ,10));
function randCode(n) {
n = n || 4 ;
var res = '' ;
res += numArr[rand(numArr.length)] ;
res += smallArr[rand(smallArr.length)] ;
res += bigArr[rand(bigArr.length)] ;
for(var i = 0 ; i < n - 3 ; i++) {
res += allArr[rand(allArr.length)] ;
}
console.log(res);
// 向打乱字符串的顺序 --- 字符串不能赋值
// 把字符串转数组
var arr = res.split('') ;
console.log(arr);
for(var i in arr) {
// 交换位置
var index = rand(arr.length) ;
var t = arr[i] ;
arr[i] = arr[index] ;
arr[index] = t
}
// 把数组转回字符串
res = arr.join('') ;
// console.log(res);
return res
}
function get(id) {
return document.getElementById(id)
}
// 显示验证码
get('code').innerHTML = randCode()
get('code').onclick = function () {
get('code').innerHTML = randCode()
}
// 验证
get('btn').onclick = function () {
// 获取输入框的值
var str = get('inp').value ;
// 拿到显示的验证码
var str2 = get('code').innerHTML ;
if(str.toLowerCase() === str2.toLowerCase()) {
get('msg').innerHTML = '验证通过';
get('msg').style.color = 'green'
} else {
get('code').innerHTML = randCode()
get('inp').value = ''
get('msg').innerHTML = '验证失败';
get('msg').style.color = 'red'
}
}
</script>
6.注册验证
<p>
请输入用户名:
<input type="text" id="user">
<span id="userSpan">用户名在3-6个字符,且只能是数字,字母组成,数字不能开头</span>
</p>
<p>
请输入密码:
<input type="password" id="pwd">
<span id="pwdSpan">密码在3-6个字符,且只能是数字,字母组成(密码强度验证)</span>
</p>
<p>
请输入验证码:
<input type="password" id="code">
<span id="codeSpan">验证码</span>
</p>
<button id="btn">注册</button>
<script src="../js/tools.js"></script>
<script>
// 那对象
var oUser = get('user') ;
var oUserSpan = get('userSpan') ;
var oBtn = get('btn') ;
var numArr = [] ;
for(var i = 0 ; i < 10 ; i++) {
numArr.push(i + '') ;
}
var smallArr = [] ;
for(var i = 97 ; i <= 122 ; i++) {
smallArr.push(String.fromCharCode(i))
}
var bigArr = [] ;
for(var i = 65 ; i <= 90 ; i++) {
bigArr.push(String.fromCharCode(i))
}
var allArr = numArr.concat(smallArr , bigArr) ;
oBtn.onclick = function () {
// 验证用户名 -- 去掉首尾空格
var username = oUser.value.trim() ;
// 为空
if(username.length === 0) {
oUserSpan.innerHTML = '输入不能为空'
oUserSpan.style.color = 'red'
// 直接结束函数
return
}
// 验证长度
if(username.length < 3 || username.length > 6) {
oUserSpan.innerHTML = '长度不对'
oUserSpan.style.color = 'red'
return
}
// 数字不能开头
// 判断是不是数字
// >=0 <= 9
// !isNaN()
// numArr.includes()
if(numArr.includes(username.charAt(0))) {
oUserSpan.innerHTML = '数字不能开头'
oUserSpan.style.color = 'red'
return
}
// 不能有非法字符
// 遍历用户名
for(var i = 0 ; i < username.length ; i++) {
// 只要有一个不在allArr里面,就非法
if(!allArr.includes(username[i])) {
oUserSpan.innerHTML = '用户名只能是数字或者字母'
oUserSpan.style.color = 'red'
return
}
}
oUserSpan.innerHTML = '√'
oUserSpan.style.color = 'green'
}
7.切割地址栏
var url = 'file:///C:/Users/1/Desktop/wh2114%E4%BA%8C%E9%98%B6%E6%AE%B5/day10/%E8%AF%BE%E5%A0%82%E4%BB%A3%E7%A0%81/html/07%E5%88%87%E5%89%B2%E5%9C%B0%E5%9D%80%E6%A0%8F.html?username=yy&password=123&email=23%40qq.com' ;
// [
// ['username' , 'yy'],
// ['password' , '123'],
// ['email' , '23@qq.com']
// ]
var arr = url.split('?') ;
console.log(arr);
var str = arr[1] ; // 'username=yy&password=123&email=23%40qq.com'
var arr = str.split('&') ;
console.log(arr); // ['username=yy', 'password=123', 'email=23%40qq.com']
// 遍历数组
var res = [] ;
for(var i = 0 ; i < arr.length ; i++) {
var list = arr[i].split('=');
console.log(list);
res.push(list)
}
console.log(res);
另一种方法实现:
var str = url.split('?')[1] ;
console.log(str);
var arr = str.split('&') ;
console.log(arr);
var res = arr.map(function (v) {
return v.split('=')
})
console.log(res);
// [
// {username : 'yy'},
// {password : '123'},
// {email : '23@qq.com'}
// ]
console.log(arr); // ['username=yy', 'password=123', 'email=23%40qq.com']
var res = arr.map(function (v) {
// return ({
// 此处语法报错,因为键名必须是字符串(字符串中不能有非法字符),不能是变量
// v.split('=')[0] : v.split('=')[1]
// })
var obj = {} ;
var list = v.split('=') ;
obj[list[0]] = list[1] ;
return obj
})
console.log(res);
8.过滤数据
var arr = ['hello' , 'hi' , 'hei' , 'hehe' , 'xixi' , 'pupu'];
// 找到包含 h的
var res = arr.filter(function (v) {
return v.includes('h')
})
console.log(res);
var data = [
{
img : 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/6d0a3e7acc3e91e2cfd83dbbe1d1c029.jpg?thumb=1&w=400&h=400&f=webp&q=90' ,
title : '小米11' ,
content : '轻薄5G,内外兼修' ,
price : 1999
},
{
img : 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/6d0a3e7acc3e91e2cfd83dbbe1d1c029.jpg?thumb=1&w=400&h=400&f=webp&q=90' ,
title : '小米青春版2' ,
content : '轻薄5G,内外兼修2' ,
price : 1299
},
{
img : 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/6d0a3e7acc3e91e2cfd83dbbe1d1c029.jpg?thumb=1&w=400&h=400&f=webp&q=90' ,
title : '小米家庭11' ,
content : '轻薄5G,内外兼修' ,
price : 1999
}
]
var res2 = data.filter(function (v) {
return v.title.includes('11')
})
console.log(res2);
9.日期对象
日期对象:记录时间
区时
在js里面 1970.1.1 0:0:0 标准时间
日期对象的创建
无参创建 --- 拿到的是电脑的当前时间
数字单参创建,毫秒数 1s = 1000ms
数字多参创建 年月日时分秒
注意:月份是从0开始的,时间可以自动计算
字符串单参创建 年[-*,]月[-*,]日 时:分:秒
时间是正常的,也是不能自动计算的
var date = new Date() ;
console.log(date); // 得到的电脑的当前时间
var date2 = new Date(0) ;
console.log(date2);
var date3 = new Date(1000) ;
console.log(date3);
var date4 = new Date(2020,13,1,1,1,1) ;
console.log(date4);
var date5 = new Date('2021-1-1 1:1:1') ;
console.log(date5);
var date6 = new Date(date2) ;
console.log(date6); // date6 === date2
10.获取具体的日期
var date = formatDate()
document.write(date)
// var date = new Date() ;
// var year = date.getFullYear() ;
// console.log(year);
// // 月份是从0开始的
// var month = date.getMonth() + 1;
// console.log(month);
// var day = date.getDate() ;
// console.log(day);
// // 星期也是从0开始 ,星期天0 0-6
// var week = date.getDay() ;
// console.log(week);
// var hour = date.getHours() ;
// console.log(hour);
// var minute = date.getMinutes() ;
// console.log(minute);
// var second = date.getSeconds() ;
// console.log(second);
// var arr = ['星期天' , '星期一' , '星期二' , '星期三' , '星期四' , '星期五' , '星期六'];
// document.write(year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second + ' ' + arr[week] )
// 星期五
function formatDate() {
var date = new Date() ;
var year = date.getFullYear() ;
// 月份是从0开始的
var month = date.getMonth() + 1;
var day = date.getDate() ;
// 星期也是从0开始 ,星期天0 0-6
var week = date.getDay() ;
var hour = date.getHours() ;
var minute = date.getMinutes() ;
var second = date.getSeconds() ;
var arr = ['星期天' , '星期一' , '星期二' , '星期三' , '星期四' , '星期五' , '星期六'];
return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second + ' ' + arr[week]
}
上个月的天数:
var date = new Date() ;
// 本月的第0天也就是上个月的最后一天
date.setDate(0) ;
console.log(date);
11.设置时间
var date = new Date() ;
date.setFullYear(2020) ;
// 时间可以自动计算
date.setMonth(12)
date.setDate(10)
date.setHours(10)
date.setMinutes(10)
date.setSeconds(1000)
// date.setDay(4); err 星期不能设置
console.log(date);
12.本月的天数
// var date = new Date() ;
// date.setMonth(date.getMonth() + 1) ;
// console.log(date);
// date.setDate(0) ;
// console.log(date);
var date = new Date('2021-1-31') ;
// date.setMonth(date.getMonth() + 1) ; // 2021-3-3
// console.log(date);
// 把日期推到下个月 32-58
date.setDate(33) ; // 2021-1-33 2021-2-2
// 把日期推到第0天,也就是上个月的最后一天
date.setDate(0) ;
console.log(date);
13.定时器
定时器 : 重复的闹钟
每隔一段时间,做一件事
延时器: 一次性闹钟
一段时间之后,做一件事
setInterval(fn , time)
用变量存储定时器的时候,变量存储的是页面当中的第几个定时器
注意:
定时器是异步的(等所有的同步代码执行完毕之后才会执行)
同步和异步
一遍敲代码,一边听歌 异步 (同时干很多事情)
先烧水,再泡面 同步 (先干,再干,再干 --- 排队)
单线程和多线程
单线程:一次干一件事情
多线程:一次干很多事情
js一种单线程的语言
js主要是进行标签操作(无法一边修改标签,一边删除标签)
js代码同步为主的(从上往下一个个的执行代码)
js代码中也存在一些异步程序 事件处理函数,定时器
js代码执行顺序
1 先在主线程上执行同步代码,遇到异步,就放在任务队列中
2 所有的同步执行完毕以后,如果任务队列中有已经到时间了,可以执行了,(这个任务就可以在主线程上执行)
var t = setInterval(function () {
console.log(666);
},0)
var t2 = setInterval(function () {
console.log(777);
},2000)
document.onclick = function () {
console.log(999);
}
console.log(1);
console.log(2);
14.页面停留时间
<h1 id="time"></h1>
<script>
var oH1 = document.getElementById('time') ;
var count = 0 ;
oH1.innerHTML = '你在页面停留了' + count + 's'
setInterval(function () {
count++ ;
// document.write('你在页面停留了' + count + 's')
oH1.innerHTML = '你在页面停留了' + count + 's'
},1000)
</script>
15.走动的时间
<h1 id="time"></h1>
<script>
//获取对象id
var oDate = document.getElementById('time') ;
//让页面一打开就存在内容,不至于有短暂空白期
var res = formatDate();
oDate.innerHTML = res ;
// 让时间走动 setInterval(function(){} , 毫秒 )
setInterval(function () {
var res = formatDate();
oDate.innerHTML = res ;
}, 1000)
function formatDate() {
// 获取到本机电脑的日期
var date = new Date();
//年
var year = date.getFullYear();
// 月份是从0开始的
var month = date.getMonth() + 1;
//日
var day = date.getDate();
//星期
var week = date.getDay();
//小时
var hour = date.getHours();
//分
var minute = date.getMinutes();
//秒
var second = date.getSeconds();
var arr = ['星期天','星期一','星期二','星期三','星期四','星期五','星期六'] ;
return year +'-' +month + '-' + day + ' ' + hour + ':' + minute + ":" + second + ' ' + arr[week] ;
}
</script>
16.倒计时
<h1>距离下课还有<span id="time"></span></h1>
<script>
var oTime = document.getElementById('time') ;
var tt = new Date('2021-12-18 12:0:0')
showDate(tt)
// var allSeconds ;
function showDate(t) {
var future = new Date(t) ;
var now = new Date() ;
// 时间是可以相减的 --- 毫秒数
var gap = future - now ;
console.log(gap);
allSeconds = parseInt(gap / 1000) ;
console.log(allSeconds);
if(allSeconds <= 0) {
oTime.innerHTML = '时间已过期了'
return
}
var h = parseInt(allSeconds / 3600) ;
var m = parseInt(allSeconds % 3600 / 60) ;
var s = allSeconds % 60 ;
oTime.innerHTML = h + ':' + m + ':' + s ;
}
// setInterval的第三个包括后面的参数都是给第一个函数的参数
// var t = setInterval(showDate,1000,tt)
var t = setInterval(function () {
showDate(tt) ;
console.log(allSeconds);
if(allSeconds <= 0) {
console.log(666);
clearInterval(t)
}
},1000)
</script>