回忆DOM:文档对象模型
BOM(Browser Object Model ) :是浏览器对象模型
window 是浏览器内置中的全局对象,我们所学习的所有 Web APIs 的知识内容都是基于 window 对象实现的
JavaScript 内置的一个用来让代码延迟执行的函数,叫 setTimeout只执行一次,所以可以理解为就是把一段代码延迟执行, 平时省略window。
结合递归函数可以使用 setTimeout 实现 setInterval 一样的功能
两种定时器对比:
setInterval 的特征是重复执行,首次执行会延时
setTimeout 的特征是延时执行,只执行 1 次
setTimeout 结合递归函数,能模拟 setInterval 重复执行
clearTimeout 清除由 setTimeout 创建的定时任务
下面两个输出都是1111 3333 2222 2222…;
第一个不难理解,因为定时器要等待一秒,页面一加载就会执行的,所以不会等定时器一秒后而先输出3333;
第二个就是本节知识
- JavaScript 语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。这是因为 Javascript 这门脚本语言诞生的使命所致——JavaScript 是为处理页面中用户的交互,以及操作 DOM 而诞生的。
- 比如我们对某个 DOM 元素进行添加和删除操作,不能同时进行。 应该先进行添加,之后再删除。
- 单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。这样所导致的问题是: 如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。
他们的本质区别: 这条流水线上各个流程的执行顺序不同
同步任务
都在主线程上执行,形成一个执行栈
。
JS 的异步
是通过回调函数实现的。
一般而言,异步任务有以下三种类型:
1、普通事件
,如 click、resize 等
2、资源加载,如load
、error 等
3、定时器
,包括 setInterval、setTimeout 等异步任务相关添加到任务队列中(任务队列也称为消息队列)。
事件循环( event loop)
:执行执行栈里面的任务,执行完毕再去任务队列里面看看是否有任务,如果有,则得到放入执行栈中执行,再次循环。location 的数据类型是对象,它拆分并保存了 URL 地址的各个组成部分
search 属性获取地址中携带的参数,符号 ?后面部分
hash 属性获取地址中的哈希值,符号 # 后面部分
后期vue路由的铺垫,经常用于不刷新页面,显示不同页面,比如 网易云音乐
reload 方法用来刷新当前页面,传入参数 true 时表示强制刷新(相当于刷新按钮)括号参数是默认false表示刷新,true表示强制刷新=ctrl+f5,前者如果进入过网页就直接本地有缓存很快,后者强制从网上加载可能会有空白时刻
navigator的数据类型是对象,该对象下记录了浏览器自身的相关信息,通过 userAgent 检测浏览器的版本及平台,即const userAgent = navigator.userAgent。(代码不用背)
地址换成移动端的地址
作了解
history 的数据类型是对象,该对象与浏览器地址栏的操作相对应,如前进、后退、历史记录等。history 对象一般在实际开发中比较少用,但是会在一些 OA 办公系统中见到。
上面代码两个按钮:
1.前进的用法:在这个初始两按钮界面地址a栏重新输入地址b,然后在浏览器点击后退箭头,这时候回到初始两按钮界面a,可以点击前进按钮前进了,前进到界面b。
2.后退的用法:复制这个初始两按钮的界面地址a,重新在界面地址c删掉那个地址输入初始按钮界面a的地址,然后按钮可以点击后退了,后退到界面c
官网
在线演示demo
基本使用流程
APi文档,配置自己的插件
下载后的swiper打开package里面,一个是压缩过的min,一个是没有压缩的正常js,一般引入min的css和js(本地实例在demos文件夹里面,也可以网页查看),多个swiper同时使用的时候, 类名需要注意区分,且script的js要放在引入插件的下面
随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样的需求,会经常性在
本地存储大量的数据,HTML5规范提出了相关解决方案。 1、数据存储在用户浏览器中
2、设置、读取方便、甚至页面刷新不丢失数据
3、容量较大,sessionStorage和localStorage约 5M 左右
1、生命周期永久生效,除非手动删除 否则关闭页面也会存在
2、可以多窗口(页面)共享(同一浏览器可以共享)
3. 以键值对的形式存储使用
存储数据:
localStorage.setItem(key, value)
获取数据:
localStorage.getItem(key)
删除数据:
localStorage.removeItem(key)
如果直接setItem的话,存储的是一个[object Object]仍然看不懂,需要把数据对象转化为json格式(JSON数据,属性和值都是双引号进行包含),也就是
JSON.stringify转化了就看得到数据对象了
且console.log(typeof localStorage.getItem(‘obj’)) 输出是String
所以用JSON.parse(localStorage.getItem(‘obj’))将字符串转化为对象
1、生命周期为关闭浏览器窗口
2、在同一个窗口(页面)下数据可以共享
3. 以键值对的形式存储使用
4. 用法跟localStorage 基本相同(就把localStorage 换成sessionStorage)
注意是拿数据来增删了再把改了的数据存回去
e.target.tagName
=== ‘A’ 点击了链接才能删(后面的e.target.dataset.id、e.target.id)
学号删了的可以重新排,但是已有的不能因为中间删掉的重新再排了
不允许删除第一条数据
需求:改为本次存储版本的学习信息表
需求①:读取本地存储数据(封装函数)
如果本地存储有数据,则返回 JSON.parse() 之后的对象
如果本地存储没有数据,则默认写入三条数据,注意存储的利用JSON.stringify() 存 储JSON 格式的数据
需求②:渲染模块
先读取本地存储数据,然后渲染
需求③:添加模块
注意,先取的最新的本地存储数据,然后追加
新增了数据,要把新数据存储到本地存储别,忘记转换
需求④:删除模块
注意,先取的最新的本地存储数据,然后追加
新增了数据,要把新数据存储到本地存储别忘记转换
getAttribute(‘属性名’) // 获取自定义属性
setAttribute(‘属性名’, ‘属性值’) // 设置自定义属性
removeAttribute(‘属性名’) // 删除自定义属性
专门的data-自定义属性
在标签上一律以data-开头,在DOM对象上一律以dataset对象方式获取DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Documenttitle>
<link rel="stylesheet" href="css/user.css">
head>
<body>
<h1>新增学员h1>
<div class="info">
姓名:<input type="text" class="uname">
年龄:<input type="text" class="age">
性别: <select name="gender" id="" class="gender">
<option value="男">男option>
<option value="女">女option>
select>
薪资:<input type="text" class="salary">
就业城市:<select name="city" id="" class="city">
<option value="北京">北京option>
<option value="上海">上海option>
<option value="广州">广州option>
<option value="深圳">深圳option>
<option value="曹县">曹县option>
select>
<button class="add">录入button>
div>
<h1>就业榜h1>
<table>
<thead>
<tr>
<th>学号th>
<th>姓名th>
<th>年龄th>
<th>性别th>
<th>薪资th>
<th>就业城市th>
<th>操作th>
tr>
thead>
<tbody>
tbody>
table>
<script>
// 读取本地存储的数据 封装为函数
// 需求1:读取本地存储数据(封装函数)
function getLocalData() {
let data = localStorage.getItem('data')//拿到数据(是JSON字符串类型噢,要parse)
if (data) { // 如果本地存储有数据,则返回 JSON.parse() 之后的对象
return JSON.parse(data)
} else { // 如果本地存储没有数据,则默认写入三条数据,注意存储的利用JSON.stringify() 存 储JSON 格式的数据
let arr = [
{ stuId: 1001, uname: '欧阳霸天', age: 19, gender: '男', salary: '20000', city: '上海' },
{ stuId: 1002, uname: '令狐霸天', age: 29, gender: '男', salary: '30000', city: '北京' },
{ stuId: 1003, uname: '诸葛霸天', age: 39, gender: '男', salary: '2000', city: '北京' },
]
localStorage.setItem('data', JSON.stringify(arr)) //这里如果忘记写JSON.stringify()一定要清缓存
}
}
// 先调用一次(以保证现在有存储的基本数据)
getLocalData()
// 获取元素
let tbody = document.querySelector('tbody')
let add = document.querySelector('.add')
let uname = document.querySelector('.uname')
let age = document.querySelector('.age')
let gender = document.querySelector('.gender')
let salary = document.querySelector('.salary')
let city = document.querySelector('.city')
//let del = document.querySelectorAll('tbody a') //a链接很多,一条数据一个,都要绑定事件
// 渲染函数 把数组里面的数据渲染到页面中
function render(){
let data = getLocalData() //JSON格式的数组
//先清空完页面的数据以便重新渲染
tbody.innerHTML = ''
for(let i = 0; i < data.length; i++){
let tr = document.createElement('tr') //创建元素
//对每一条数据进行渲染
tr.innerHTML = `
${data[i].stuId}
${data[i].uname}
${data[i].age}
${data[i].gender}
${data[i].salary}
${data[i].city}
${i}">删除
`
tbody.appendChild(tr) //加到总的tbody里面
}
}
// 页面加载就调用函数
render()
//点击增加数据操作
add.addEventListener('click', function() {
//获取本地已有的数据
let arr = getLocalData()
//获取当前页面输入的数据,也就是获取那些元素的innerHTML值一律.value
let temp = {
"stuId" : +arr[arr.length - 1].stuId + 1, //最后一个对象的学号(取出来是string)+1
"uname" : uname.value,
"age" : age.value,
"gender" : gender.value,
"salary" : salary.value,
"city" : city.value,
}
arr.push(temp) //增加修改完毕
//存进去
localStorage.setItem('data', JSON.stringify(arr))
//重新渲染
render()
})
// 删除操作, 删除的也是数组里面的数据 , 但是我们用事件委托
tbody.addEventListener('click', function(e) {
//获取本地已有的数据
let arr = getLocalData()
//获取删除的那个元素
if (e.target.tagName === 'A') {
if (e.target.dataset.id === '0') {
alert('当前数据不允许删除操作')
return //退出
}
//console.log(e.target.id)
console.log(e.target.dataset.id)
arr.splice(e.target.dataset.id, 1) //第id个子孩子
}
//存进去
localStorage.setItem('data', JSON.stringify(arr))
//重新渲染
render()
})
//注意如果删完了localStorage里面data存在,是[]这样,再增加数据的时候就拿不到数据的id了,从而不成功
//所以设置第一条数据不可以删除在渲染的a删除里面多加一个data-id="${i}"!!!!!!
script>
body>
html>
旧微博发布案例
其中的增加和删除都可以类似上面的案例表格增删的去改(这里就没有再去改了)
主要修改点:
正则表达式(Regular Expression)是用于匹配字符串中字符组合的模式。在 JavaScript中,正则表达式也是对象
(对象就有属性方法),通常用来查找、替换那些符合正则表达式的文本,许多语言都支持正则表达式。(实际开发不会很严格,且可以参考菜鸟教程所罗列的正则表达式)
1.正则表达式是什么?
是用于匹配字符串中字符组合的模式
2.正则表达式有什么作用?
表单验证(匹配) 、过滤敏感词(替换) 、字符串中提取我们想要的部分(提取)
3.正则表达式使用的步骤:定义正则表达式,检测查找是否匹配
test() 方法 用来查看正则表达式与指定的字符串是否匹配,如果正则表达式与指定的字符串匹配 ,返回true,否则false
exec() 方法 在一个指定字符串中执行一个搜索匹配,如果匹配成功,exec() 方法返回一个数组,否则返回null
正则表达式检测查找 test方法和exec方法有什么区别?
普通字符:
大多数的字符仅能够描述它们本身,这些字符称作普通字符,例如所有的字母和数字。也就是说普通字符只能够匹配字符串中与它们相同的字符。
元字符(特殊字符)是一些具有特殊含义的字符,可以极大提高了灵活性和强大的匹配功能。比如,规定用户只能输入英文26个英文字母,普通字符的话 abcdefghijklm……
但是换成元字符写法: [a-z]
参考文档–MDN
参考文档–正则测试工具
为了方便记忆和学习,我们对众多的元字符进行了分类:
正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符,如果 ^ 和 $ 在一起,表示必须是精确匹配
边界符 | 说明 |
---|---|
^ | 表示匹配行首的文本(以谁开始) |
$ | 表示匹配行尾的文本(以谁结束) |
量词用来 设定某个模式出现的次数,注意: 逗号左右两侧千万不要出现空格
两量词 | 说明 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n次到m次 |
后面的字符串只要包含 abc 中任意一个字符
,都返回 true
!!!!注意如果是^开头的$结尾的,而中括号里面又是多选一,则只表示开头唯一的一个字符,结尾唯一个字符,所以前四个是正确的,最后cc不正确,因为不是唯一。
例如:
[a-z] 表示 a 到 z 26个英文字母都可以
[a-zA-Z] 表示大小写都可以
[0-9] 表示 0~9 的数字都可以
下面表示大小写数字和下划线任意选择一个(但是不能重复噢,重复选需要量词)因为有^$
QQ号的正则表达式:要求第一位不能为0,至少总位数是五位,
量词只针对前面最近的一位的修饰,也就是说{4,}至少4位是指[0-9]这个表达
例如下面的意思是以ab开头,c的位数是一位起步的(+只修饰c)
比如:
[ ^a-z] 匹配除了小写字母以外的字符
注意要写到中括号里面
(下面防止markdown的格式问题^前后可能加了个空格,实际上没有)
说明 | |
---|---|
\d | 匹配0-9之间的任一数字,相当于[0-9] |
\ | 匹配所有0-9以外的字符,相当于[ ^0-9] |
\w | 匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_] |
\W | 除所有字母、数字和下划线以外的字符,相当于[ ^A-Za-z0-9_] |
\s | 匹配空格(包括换行符、制表符、空格符等),相等于[\t\r\n\v\f] |
\S | 匹配非空格的字符,相当于[ ^\t\r\n\v\f] |
修饰符约束正则执行的某些细节行为,如是否区分大小写、是否支持多行匹配等,
i 是单词 ignore 的缩写,正则匹配时字母不区分大小写,g 是单词 global 的缩写,匹配所有满足正则表达式的结果
把textarea里面的激情或者基情替换成**,多个敏感词用单条 | ,后面记得加 g 表示所有的都要替换,否则只会替换第一个。
input
:只要是输入,就不断被触发
blur
:离开表单失去焦点时触发事件
change
:离开表单文本框失去焦点且内容发生改变才触发(比如都是空还没输入即便失去焦点也不会触发)
3个html,因为包含css,所以用百度网盘所有的案例
<script>
// 需求:
// 1. 登录按钮点击的时候,需要先判断
// 如果没有勾选同意,则提示要勾选
let agree = document.querySelector('input[name=agree]') //复选框元素或者.remember也可
let username = document.querySelector('[name=username]')
let password = document.querySelector('[name=password]')
let dl = document.querySelector('button.dl')//.dl登录按钮
let form = document.querySelector('form') //form表单进行提交,而非按钮事件哦
// form.addEventListener('submit', function(e){
// e.preventDefault()
// if(!agree.checked){ //没有选中
// alert('请勾选协议')
// return
// }
// let obj = {
// uname : username.value,
// password: password.value,
// }
// console.log(obj)
// })
//因为只是判断,不用提交表单,所以用click按钮写事件也可以
dl.addEventListener('click', function(e){
e.preventDefault()
if(!agree.checked){ //没有选中
alert('请勾选协议')
return
}
let obj = {
username : username.value,
password: password.value,
}
//console.log(obj)
//存进本地
localStorage.setItem('pink',JSON.stringify(obj))
//跳转页面
location.href = './index.html'
})
//取出来
let obj = JSON.parse(localStorage.getItem('pink'))
//如果有数据,则自动填入和勾选
if(obj){
username.value = obj.username,
password.value = obj.password
//并且默认勾选复选框
agree.checked = true
}
// 如果勾选协议,则记住用户名和密码
// 登录成功则跳转到首页
// 注意,登录按钮需要先阻止默认行为
script>
<script>
// 如果本地存储有数据,则 显示 你好 xxxx
// 否则 显示 请跳转到注册页面
let li = document.querySelector('.xtx_navs li:first-child')
let obj = JSON.parse(localStorage.getItem('pink'))
if (obj) {
li.innerHTML = ` 你好,${obj.username} 欢迎来到小兔鲜世界`
}
script>
- 快捷键ctrl+F搜索,ctrl+H查找所有
- 立即执行函数,括号写里面调用,一定要分号隔开
- nextElementSibiling:下一个兄弟节点。
- css属性选择器属性和值:documen.querySelector(‘[name=username]’)
表示:input 里面 有type属性的背景色变成红色
5.this.classList.toggle(‘icon-queren2’) //切换添加或者不添加
h5新增的属性:加上这个required属性,表示该字段不能为空