JavaScript day12
知识点回顾
注册验证
字符串的方法和数组的方法
验证输入是否正确
为空 === '' 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
},0)
}
日历终极版本
*{
padding: 0;
margin: 0;
list-style: none;
}
ul{
display: flex;
width: 560px;
margin: 0 auto;
flex-wrap: wrap;
}
li{
width: 80px;
text-align: center;
line-height: 40px;
background-color: #000;
color: #fff;
}
p{
width: 560px;
display: flex;
justify-content: space-between;
margin: auto;
font-size: 40px;
cursor: pointer;
}
p{
text-align: center;
}
<p id="nowTime"></p>
<p id="changeTime"></p>
<p>
<span id="prev"><span>
<span id="next">>span>
</p>
<ul>
<li>星期一li>
<li>星期二li>
<li>星期三li>
<li>星期四li>
<li>星期五li>
<li>星期六li>
<li>星期天li>
</ul>
<ul id="list"></ul>
// 拿对象
var oList = document.getElementById('list') ;
var oPrev = document.getElementById('prev');
var oNext = document.getElementById('next') ;
var oNow = document.getElementById('nowTime') ;
var oChange = document.getElementById('changeTime') ;
var date = new Date() ;
// 动态生成42个li
getLi(oList)
// 显示年月
oChange.innerHTML = showDate(date)
// 显示当前时间
oNow.innerHTML = formatDate(new Date())
setInterval(function () {
oNow.innerHTML = formatDate(new Date())
// formatDate(new Date())
},1000)
// 上翻页
oNext.onclick = function () {
date.setDate(33) ;
getLi(oList)
oChange.innerHTML = showDate(date)
}
// 下翻页
oPrev.onclick = function () {
date.setDate(0) ;
getLi(oList)
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 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()) ;
// oNow.innerHTML = `${h}:${m}:${s}`
return `${h}:${m}:${s}`
}
// 补零
function addZero(n) {
return n > 9 ? n : '0' + n
}
// 动态生成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>${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> ${i}</li>`
}
// console.log(res);
obj.innerHTML = res ;
}
// 获取本月的天数
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() ;
console.log(week);
// 星期天的时候,week是0 , 但是计算是按7计算
if(week === 0) {
week = 7
}
var list = [] ;
for(var i = maxDay - week + 2 ; i <= maxDay ; i++) {
list.push(i)
}
return list
}
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);
var a = 10 ;
console.log(window.a);
function fn() {
console.log(666);
}
window.fn()
// var arr = [1,2,3] ;
// var arr2 = [5,6,7] ;
// // arr.length
// arr.index = 666 ;
// // arr2.index
BOM的常见属性
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.userAgent);
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('使用的是window系统的电脑');
}
}
console.log(location);
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)
location.reload()
console.log(window);
BOM方法
// open() 打开新的浏览器窗口 网页重定向(默认被拦截)
// close() 关闭本窗口
setTimeout(function () {
// 打开一个新的窗口 --- 网页重定向(默认被拦截)
// open('http://www.baidu.com')
close()
},3000)
BOM事件
body{
height: 3000px;
}
window.onload = function () {
var oDiv = document.getElementById('a') ;
console.log(oDiv);
}
<div id="a">666</div>
// 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)
移动端适配
html{
/* 1rem = 100px */
/* rem是相对于根元素变化的单位 */
/* 移动端适配也就是动态设置根元素的字体大小,然后使用rem做单位 */
/* font-size: calc(100vw / 7.5); */
}
body{
/* font-size: .24rem; */
}
.a{
/* width: 1rem;
height: 1rem;
background-color: #f00; */
}
.a{
width: 2rem;
height: 2rem;
background-color: #f00;
}
// 使用注意事项
// 1 不设置meta 禁止缩放那一段 --- js里面有设置
// 2 计算 1rem = 75px
<script src="../js/flexible.js">script>
<div class="a">呵呵呵div>
高频率触发事件的处理方案
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)
}
}
给多个元素绑定事件
<p class="a">1</p>
<p class="a">2</p>
<p class="a">3</p>
<p class="a">4</p>
<input type="checkbox" id="all">
<br>
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
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
作业
日历
BOM属性和方法
函数防抖和节流
多元素绑定事件
全选和反选