一、知识点回顾
注册验证
字符串的方法和数组的方法
验证输入是否正确
为空 === ‘’ length === 0 trim() 去掉首尾空格
长度 length
数字开头 第一位是不是数字[0,1,2,3,4,5,6,7,8,9]
非法 把所有合法或者不合法的列举出来
强度验证 1个组合 2个组合 3个组合
判断是否有小写,是否有大写,是否有数字
flag1+flag2+flag3
全局变量
小广告
定时器
延时器 可以当做定时器使用 写递归
不做区分(编号,清除)
bug 定时器叠加
解决:
1. 每次点击的时候,先清除,再启动定时器 --- 保证只有一个定时器
2. 点完之后禁用,一段时间之后(事情完成以后)解除禁用 --- 验证码
60s倒计时
异步
代码的执行顺序
谁才是真正的异步
绑定onclick是同步 函数是异步
setTime(fn) fn才是异步的
for(var i = 0 ; i < 10 ; i++){
console.log(i); // 0 - 9
setTimeout(function(){
console.log(i); // 10个10 函数是异步的,最后执行,因此此时循环已经结束 i为10
},0)
}
二、日历终极版
var oList = document.getElementById('list')
var oPrev = document.getElementById('prev')
var oNext = document.getElementById('next')
var oNowtime = document.getElementById('nowtime')
var oChange = document.getElementById('changeTime')
var date = new Date();
// 显示年月
oChange.innerHTML = showDate(date)
//显示改变的日期
function showDate(d){
var date = new Date(d);
var y = date.getFullYear();
var m = addZero(date.getMonth()+1)
return y + '-' + m
}
//补零
function addZero(n){
return n > 9 ? n : '0' + n
}
// 格式化时分秒
function formatDate(d){
var date = new Date(d)
var h = date.getHours()
h = addZero(h)
var m = date.getMinutes()
m = addZero(m)
var s = addZero(date.getSeconds())
return `${h}:${m}:${s}`
}
// 显示当前时间
oNowtime.innerHTML = formatDate(new Date())
setInterval(function(){
oNowtime.innerHTML = formatDate(new Date())
},1000)
// 获取本月的天数
function getNowDays(time){
var date = new Date(time);
// 日期推到下个月
date.setDate(33);
// 日期推到下个月的第0天,也就是本月的最后一天
date.setDate(0);
// 拿到本月的最后一天
var maxDay = date.getDate();
var list = [];
for(var i = 1; i <= maxDay ; i++){
list.push(i)
}
return list
}
// 获取上个月的天数
function getPrevDays(time){
var date = new Date(time);
// 日期推到本月的第0天,也就是上个月的最后一天
date.setDate(0);
// 拿到上个月的最后一天
var maxDay = date.getDate();
// 日期回到本月
date.setDate(33);
// 日期回到本月的一天
date.setDate(1);
// 获取本月的第一天是星期几
var week = date.getDay();
// 星期天的时候,week是0,但是计算是按7计算
if(week === 0){
week = 7
}
var list = [];
for(var i = maxDay - week + 2 ; i <= maxDay ; i++){
list.push(i)
}
return list
}
// 动态生成42个li
getLi(oList)
// 动态生成42个li
// 上个月 + 本月 + 下个月
function getLi(obj) {
// 这里是当前的年月日
var dd = new Date();
var y = dd.getFullYear();
var m = dd.getMonth();
var d = dd.getDate();
// date是改变后的时间
var y2 = date.getFullYear();
var m2 = date.getMonth();
var d2 = date.getDate();
var res = ''
// 获取上个月天数
var prevDays = getPrevDays(date);
for(var i = 0 ; i < prevDays.length ; i++){
res += `<li style = 'color:#666;'>${prevDays[i]}</li>`
}
// 获取这个月天数
var nowDays = getNowDays(date);
for(var i = 0 ; i < nowDays.length ; i++)
if(y === y2 && m === m2 && nowDays[i] === d) {
res +=`<li style="color:yellow;">${nowDays[i]}</li>`
}else{
res += `<li>${nowDays[i]}</li>`
}
// 获取下个月的天数
for(var i = 1 ; i <= 42 - prevDays.length - nowDays.length ; i++){
res += `<li style = 'color:#666;'>${i}</li>`
}
obj.innerHTML = res ;
}
// 上翻页
oNext.onclick = function(){
date.setDate(33);
getLi(oList)
oChange.innerHTML = showDate(date)
}
// 下翻页
oPrev.onclick = function(){
date.setDate(0);
getLi(oList)
oChange.innerHTML = showDate(date)
}
三、js的三大组成
js:ECMAScript + BOM + DOM
BOM: browser object model //浏览器对象模型
DOM: document object model //文档对象模型
四、BOM
BOM: 浏览器对象模型
每个浏览器窗口都是一个window对象
var window = new Window() 每一次打开了一个页面的时候就默默创建了一个
window对象
每一个页面不共享window
每次创建的全局变量的函数都是属于window对象的属性和方法
console.log(window); // window
var a = 10
console.log(window.a); // 10
function fn() {
console.log(666); // 666
}
window.fn()
五、BOM的常见属性
navigator
userAgent 会详细的显示浏览器的版本信息
location 地址栏
href 整个网址
host 域名+端口号
hostname 域名
port 端口号
protocal 协议 (http / https)
search 问号后面的一串 表单提交的数据
hash 井号后面的一串 锚点
assign() 跳转至新的页面
replace() 替换当前页面 --- 不会被历史记录
reload() 刷新页面
history 历史记录
length 在同一个窗口打开过几个页面
forward() 前进
back() 后退
go(1 / -1) 可进可退
document 文档 DOM实际上是BOM的一部分
console.log(navigator);
console.log(navigator.userAgent);
console.log(location);
function sheBei(){
if(navigator.userAgent.includes('iPhone')){
console.log('使用的是苹果手机');
//处理对应的兼容问题
document.body.background = 'black'
return
}
if(navigator.userAgent.includes('Android')){
console.log('使用的是安卓手机');
return
}
if(navigator.userAgent.includes('win64')){
console.log('使用的是windows系统的电脑');
}
}
sheBei()
setTimeout(function(){
// 获取或者设置新的地址
location.href = 'http://www.baidu.com'
location.search = '?username=yy&password=123'
设置新的地址
location.assign('http://www.baidu.com')
替换新的地址 --- 替换了所有的历史记录
location.replace('http://www.baidu.com')
},3000)
六、BOM方法
open() 打开新的浏览器窗口 网页重定向(默认被拦截)
close() 关闭本窗口
setTimeout(function () {
// 打开一个新的窗口 --- 网页重定向(默认被拦截)
// open('http://www.baidu.com')
close()
},3000)
七、BOM事件
load事件:等待页面资源加载完毕之后执行
scroll 页面滚动时触发这个事件 --- 高频率触发事件
resize 窗口大小发生改变时触发此事件 --- 高频率触发的事件
window.onscroll = function(){
console.log(666);
}
var t ;
window.onresize = function(){
// console.log(888);
clearTimeout(t)
t = setTimeout(function(){
console.log(888);
},300)
}
window.onblur = function(){
console.log('你失去了我');
}
window.onfocus = function(){
console.log('你又关注了我');
}
setInterval(function(){
// DOM会有延迟
// 页面在获取焦点的时候,会优先使用现有的资源
// 而失去焦点的页面的资源会延后---不等于不处理
document.write(6);
},1000)
八、移动端适配
使用注意事项
1 不设置meta 禁止缩放那一段 --- js里面有设置
2 计算 1rem = 75px
1rem = 100px
rem是相对于根元素变化的单位
移动端适配也就是动态设置根元素的字体大小,然后使用rem做单位
font-size:calc(100vw / 7.5)
九、高频率触发事件的处理方案
onscroll / onresize 是高频率触发事件
函数的防抖和节流
干啥的?解决高频率触发事件
函数防抖(debounce): 触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件
再次被触发,则重新计算时间。--- 每次点击,就重做
函数节流(throttle): 高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的
执行频率。 --- 点击一次,就把事情干完,没干完之前点击没用。
点了一次之后,一段时间不能再点,事情干完之后可以再点 函数节流
点了以后立即清除定时器 函数防抖
// 函数防抖举例:
// var t
// window.onscroll = function(){
// clearTimeout(t);
// t = setTimeout(function(){
// console.log(888);
// },300)
// }
// 函数节流
//
// var oBtn = document.getElementById('btn');
// oBtn.onclick = function(){
// oBtn.disabled = true
// var count = 6;
// oBtn.innerHTML = count +'s之后可以再次获取验证码'
// var t =setInterval(function(){
// count--
// oBtn.innerHTML = count +'s之后可以再次获取验证码'
// if(count <= 0){
// clearTimeout(t);
// oBtn.disabled = false;
// oBtn.innerHTML = '获取验证码'
// }
// },1000)
// }
var oBtn = document.getElementById('btn');
var flag = true ; // 判断可不可以点击
oBtn.onclick = function(){
if(flag){
flag = false ;
var count = 6
oBtn.innerHTML = count +'s之后可以再次获取验证码'
var t = setInterval(function(){
count--
oBtn.innerHTML = count +'s之后可以再次获取验证码'
if(count <= 0){
clearTimeout(t);
flag = true
oBtn.innerHTML = '获取验证码'
}
},1000)
}
}
十、给多个元素绑定事件
var oPs = document.getElementsByClassName('a')
console.log(oPs);
// oPs[0].onclick = function () {
// console.log(666);
// }
// oPs[1].onclick = function () {
// console.log(666);
// }
// oPs[2].onclick = function () {
// console.log(666);
// }
// oPs[3].onclick = function () {
// console.log(666);
// }
for(var i = 0 ; i < oPs.length ; i++){
oPs[i].onclick = function(){
// console.log(666);
// console.log(i); // 4
// this在事件处理函数中使用,代表点击的那个对象
console.log(this);
}
}
var oAll = document.getElementById('all')
oAll.checked = true