WebAPI的基本学习
WebAPI的基本学习
JinwebAPI的基本学习
- 作用:使用JS操作html和浏览器
- 分类:DOM(文档对象模型)、BOM(浏览器对象模型)
DOM的内容
- DOM(Document Object Model——文档对象模型)是用来呈现以及与任意 HTML 或 XML文档交互的API
- 简单来说:DOM是浏览器提供的一套专门用来 操作网页内容 的功能
- 作用:开发网页内容特效和实现用户交互
DOM树
内容:将HTML以树状的内容直观显示出来,也称文档树
作用:直观体现出标签与标签的关系
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
文本
<a href="">链接</a>
<h1 class="" id=""></h1>
</body>
</html>
获取DOM元素
CSS选择器 匹配到第一个元素,返回一个HTMLElement对象
//语法 document.querySelector('CSS选择器')
匹配多个选择器,返回NodeList对象集合,得到是一个伪数组
document.querySelectorAll('CSS选择器')
其他方法
document.getElementByid('id名') document.getElementByTagName('标签名') document.getElementByClassName('类名')
设置和修改DOM元素
修改标签文本内容
//语法: 元素.innerText='' //只能识别内容,不能解释标签 //可以解析标签 即: 元素.innerHTML='<h3>会对html标签进行解析</h3>'
设置与修改DOM元素的属性
语法:
对象.属性=值
,最常见的属性比如: href、title、src 等//例子 let pic =document.querySelector('img') pic.src='./images/pic2.jpg'
通过style修改CSS属性
let box =document.querySelector('div') box.style.width='300px' box.style.paddingLeft ='300px' //注:有链接-符号的需要转换为小驼峰命名法 //即:padding-left-->paddingLeft
修改标签类名
元素.clssName='新类名' //注:直接使用 className 赋值会覆盖以前的类名 //保留可写 元素.clssName='旧类名 新类名'
通过clssList操作css类名
//增加一个类名 元素.classList.add('类名') //删除一个类 元素.classList.remove('类名') //切换一个类,存在就删除,不存在就增加 元素.classList.toggle('类名')
修改表单属性
作用:表单很多情况,也需要修改属性,比如点击眼睛,可以看到密码,本质是把表单类型转换为文本框
获取:DOM对象.属性名;设置:DOM对象.属性名=新值
表单.value='用户名' 表单.type='password'
表单属性中添加就有效果,移除就没有效果,一律使用布尔值表示 如果为true 代表添加了该属性 如果是false 代表移除了该属性
比如: disabled、checked、selected
定时器-setInterval() 间歇函数
开启定时器
setInterval(函数,间隔时间) //时间也毫秒为单位,1秒==1000ms
关闭定时器
let timer =setInterval(函数,间隔时间) clearInterval(timer)
事件
事件是在编程时系统内发生的动作或者发生的事情,比如用户在网页上单击一个按钮
事件监听
让程序检测是否有事件产生,一旦有事件触发,就立即调用一个函数做出响应,也称为 注册事件
语法:元素.addEventListener('事件',要执行的函数)
//获取元素
let btn=document.querySelector('button')
//事件监听
btn.addEventListener('click',function(){
alert('被点击了')
})
事件监听三要素:
- 事件源:那个dom元素被事件触发了,要获取dom元素
- 事件:有什么方式触发,比如鼠标点击click
- 事件触发时调用的函数
版本
DOM L0
语法:
事件源.on事件=function(){}
btn.onclick=function(){ alert('点击') }
DOM L2 :star:
语法:
事件源.addEventlistener(事件,事件处理函数)
btn.addEventListener('click',function(){ alert('点击') })
事件类型
高阶函数
高阶函数可以被简单理解为函数的高级应用,JavaScript 中函数可以被当成【值】来对待,基于这个特性实现函数的高级应用
函数表达式
let counter=function(x,y){
return x+y
}
//调用
let result=counter(1,2)
回调函数
如果将函数A当作参数传递给函数B时,我们称函数A为回调函数
回调函数本质还是函数,只不过把它当成参数使用
使用场景
定时器setInterval() 间歇函数
function fn(){ alert('我是回调函数') } //fn传递了给setInterval ,fn就是回调函数 setInterval(fn,1000)
事件监听
btn.addEventListener('click',function(){ alert('我是回调函数') })
环境变量
环境对象指的是函数内部特殊的变量 this ,它代表着当前函数运行时所处的环境
作用:弄清楚this的指向,可以让我们代码更简洁
- 函数的调用方式不同,this 指代的对象也不同
- 【谁调用, this 就是谁】 是判断 this 指向的粗略规则
- 直接调用函数,其实相当于是 window.函数,所以 this 指代 window
编程思想
排他思想
当前元素为A状态,其他元素为B状态
使用:
- 干掉所有人
使用for循环 - 复活他自己
通过this或者下标找到自己或者对应的元素
//给点击的li加上pink类
<li class='pink'>第一个</li>
<li>第二个</li>
<li>第三个</li>
let lis = document.querySelectorAll('li')
for (let i = 0; i < lis.length; i++) {
lis[i].addEventListener('click', function () {
// 干掉所有人
for (let j = 0; j < btns.length; j++) {
btns[j].classList.remove('pink')
}
//复活自己
this.classList.add('pink')
//==================分割线===========================
//高级做法
// 我只需要找出那个唯一的 pink类,删除
document.querySelector('.pink').classList.remove('pink')
// 我的
this.classList.add('pink')
})
}
DOM结点
DOM树里每一个内容都称之为节点
结点类型
元素结点 :star:
所有的标签:比如
body
div
,html
是根节点属性结点
所有的属性,比如
herf
文本结点
所有的文本
结点的查找
结点的关系:父节点,子节点,兄弟节点
父节点的查找
使用
parentNode
属性,返回最近一级的父节点,找不到返回null语法:
子元素.parentNode
子结点的查找
childNodes
- 获得所有的子节点,包括文本节点(空格、换行)、注释节点等chilrden
:star: -获得所有元素节点,返回的还是一个伪数组兄弟结点的查找
nextElementSibling
查找下一个兄弟结点previousElementSibling
查找上一个兄弟节点
结点的增加
一般情况下,我们新增节点,按照如下操作
1创建一个新的节点
2把创建的新的节点放入到指定的元素内部
创建结点
documnet.createElement('标签名')
追加结点
//插入父元素的最后 父元素.appendChild(要插入的元素) //插到某个子元素的前面 父元素.insertBefore(要插入的元素,在哪个元素的前面)
结点的克隆
cloneNode会克隆出一个跟原标签一样的元素,括号内传入布尔值
若为true,则代表克隆时会包含后代节点一起克隆
若为false,则代表克隆时不包含后代节点
默认为false
语法:元素.cloneNode(布尔值)
结点的删除
删除节点和隐藏节点(display:none) 有区别的: 隐藏节点还是存在的,但是删除,则从html中删除节点在 JavaScript 原生DOM操作中,要删除元素必须通过父元素删除
语法:父元素.removeChild(要删除的元素)
重绘和回流
浏览器进行界面渲染
- 解析(Parser)HTML,生成DOM树(DOM Tree)
- 同时解析(Parser) CSS,生成样式规则 (Style Rules)
- 根据DOM树和样式规则,生成渲染树(Render Tree)
- 进行布局 Layout(回流/重排):根据生成的渲染树,得到节点的几何信息(位置,大小)
- 进行绘制 Painting(重绘): 根据计算和获取的信息进行整个页面的绘制
- Display: 展示在页面上
回流(重排)
当 Render Tree 中部分或者全部元素的尺寸、结构、布局等发生改变时,浏览器就会重新渲染部分或全部文档的过程称为回流,简单理解影响到布局了,就会有回流
会导致回流的操作
- 页面的首次刷新
- 浏览器的窗口大小发生改变
- 元素的大小或位置发生改变
- 改变字体的大小
- 内容的变化(如:input框的输入,图片的大小)
- 激活css伪类 (如::hover)
- 脚本操作DOM(添加或者删除可见的DOM元素)
重绘
由于节点(元素)的样式的改变并不影响它在文档流中的位置和文档布局时(比如:color、background-color、
outline等), 称为重绘
注:重绘不一定引起回流,而回流一定会引起重绘。
练习:
let s = document.body.stlye
s.padding = '2px' //重排 + 重绘
s.border = '1px solid red' // 重排 + 重绘
s.color = 'red'//重绘
s.backgroundColor = '#666' //重绘
s.fontSize= "14px" // 重排 + 重绘
事件高级
事件对象
内容:事件对象是个对象,这个对象里有事件触发时的相关信息
例如:鼠标点击事件中,事件对象就存了鼠标点在哪个位置等信息
获取方法:
在事件绑定的回调函数的第一个参数就是事件对象
一般命名为 even 、ev 、e
元素.addEventListener('click',function(e){ //e就是事件对象 })
常用事件对象的属性
type
:获取当前事件类型clientX
/clientY
:获得光标相对于浏览器可见窗口左上角的位置offsetX
/offsetY
: 获取光标相对于当前DOM元素左上角的位置key
:用户按下的键盘的值,现在不提倡用 keyCode
事件流
事件流指的是事件完整执行过程的流动路径,两个阶段:事件捕获和事件冒泡
说明:假设页面里有个div,当触发事件时,会经历两个阶段,分别是捕获阶段、冒泡阶段
简单来说:捕获阶段是 从父到子 冒泡阶段是从子到父
事件冒泡
当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发
简单理解:当一个元素触发事件后,会依次向上调用所有父级元素的同名事件
事件冒泡是默认存在的
事件捕获
从DOM的根元素开始去执行对应的事件 (从外到里)
说明:
- addEventListener第三个参数传入true代表是捕获阶段触发(很少使用)
- 若传入false代表冒泡阶段触发,默认就是false
- 若是用 L0 事件监听,则只有冒泡阶段,没有捕获
阻止事件流动
- 因为默认就有冒泡模式的存在,所以容易导致事件影响到父级元素
- 若想把事件就限制在当前元素内,就需要阻止事件流动
- 阻止事件流动需要拿到事件对象
- 语法:
事件对象.stopProagation()
- 此方法可以阻断事件流动传播,不光在冒泡阶段有效,捕获阶段也有效
鼠标经过事件:
mouseover
和mouseout
会有冒泡效果mouseenter
和mouseleave
没有冒泡效果(推荐)
两种注册事件的区别:
传统on注册(L0)
- 同一个对象,后面注册的事件会覆盖前面注册(同一个事件)
- 直接使用null覆盖偶就可以实现事件的解绑
- 都是冒泡阶段执行的
事件监听注册(L2)
语法: addEventListener(事件类型, 事件处理函数, 是否使用捕获)
后面注册的事件不会覆盖前面注册的事件(同一个事件)
可以通过第三个参数去确定是在冒泡或者捕获阶段执行
必须使用removeEventListener(事件类型, 事件处理函数, 获取捕获或者冒泡阶段)
匿名函数无法被解绑
事件委托
事件委托其实是利用事件冒泡的特点, 给父元素添加事件,子元素可以触发
优点:给父级元素加事件(可以提高性能)
实现:
事件对象.target
可以获得真正触发事件的元素
滚动事件
作用:很多网页需要检测用户把页面滚动到某个区域后做一些处理, 比如固定导航栏,比如返回顶部
事件名 scroll
//可以给window或document添加滚动事件来监听整个页面
window.addEventListener('scroll',function(){
//要执行的操作
})
加载事件
load 事件
加载外部资源(如图片、外联CSS和JavaScript等)加载完毕时触发的事件
为什么要学?
- 有些时候需要等页面资源全部处理完了做一些事情
- 老代码喜欢把 script 写在 head 中,这时候直接找 dom 元素找不到
事件名:
load
监听页面所有资源加载完毕:
给 window 添加 load 事件
window.addEventListener('load',function(){ //要执行的操作 })
注意:不光可以监听整个页面资源加载完毕,也可以针对某个资源绑定load事件
DOMContentLoaded
当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表全加载
事件名:
DOMContentLoaded
监听页面DOM加载完毕:
给 document 添加 DOMContentLoaded 事件
document.addEventListener('DOMContentLoaded',function(){ //要执行的操作 })
元素大小和位置
三大家族
- scroll家族
- offest家族
- client家族
scroll家族
作用:检测页面滚动的距离
获取宽高
- 获取元素的内容总宽高(不包含滚动条)返回值不带单位
- scrollWidth 和 scrollHeight
获取位置(属性可修改)
- 获取元素内容往左、往上滚出去看不到的距离
- scrollLeft和scrollTop
div.addEventListener('scroll',function(){ console.log(this.scrollTop) })
注:
document.documentElement
:HTML 文档返回对象为HTML元素
offest家族
- 获取宽高
- 获取元素的自身宽高、包含元素自身设置的宽高、padding、border
- offsetWidth 和 offsetHeight
- 获取位置(只读,不可修改)
- 获取元素距离自己定位父级元素的左、上距离
client家族
- 获取宽高
- 获取元素的可见部分宽高(不包含边框,滚动条等)
- clientWidth和clientHeight
- 位置
- clientLeft和clientTop 注意是只读属性
resize
事件
- 改变窗口大小的时候触发的事件,类似css3媒体查询
Window对象
BOM
浏览器对象模型
window 是浏览器内置的全局对象,我们所学习的 web apis 的知识内容都是基于 window 对象实现的
window 对象下包含了
navigator
、location
、doucment
history
、srceen
5个属性,即 BOMdocument 是实现 DOM 的基础,它其实是依附于 window 的属性
依附于 window 对象的所有属性和方法,使用时可以省略 window
定时器-延时函数
JavaScript 内置的一个用来让代码延迟执行的函数,叫 setTimeout
语法:setTimeout(回调函数,等待的毫秒数)
setTimeout 仅执行一次,简单来说把一段代码延迟执行
清除延时函数语法 :clearTimeout(延时函数的id)
结合函数的递归可以实现 setInterval 间歇函数 一样的功能
function myInterval(){
let d=new date();
//写入页面
clock.innertext=d.toLocaleString();
//调用自己 一直循环,倒计时效果
setTimeout(myInterval,1000);
}
myInterval();
JS执行机制 (面试):star
JavaScript 语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。。这是因为 Javascript 这
门脚本语言诞生的使命所致——JavaScript 是为处理页面中用户的交互,以及操作 DOM 而诞生的。比
如我们对某个 DOM 元素进行添加和删除操作,不能同时进行。 应该先进行添加,之后再删除。
单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。这样所导致的问
题是: 如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。
同步和异步
为了解决这个问题,利用多核 CPU 的计算能力,HTML5 提出 Web Worker 标准,允许
JavaScript 脚本创建多个线程。于是,JS 中出现了同步和异步。
同步
- 前一个任务执行完才执行后一个任务,程序执行的顺序和代码排列顺序一样
异步
执行一个某个任务费很长时间,在做这个任务的同时,还可以去处理其他的任务
比如:做饭时,等水开的期间可以去其他事,比如切菜
他们的本质区别: 这条流水线上各个流程的执行顺序不同。
同步任务
- 同步任务都在主线程上执行,形成一个执行栈。
异步任务
JS 的异步是通过回调函数实现的
一般来说异步任务有以下三种类型
1、普通事件,如 click、resize 等
2、资源加载,如 load、error 等
3、定时器,包括 setInterval、setTimeout 等异步任务相关会添加的任务队列(消息队列)中
执行机制
- 先执行执行栈里面的同步任务
- 异步任务放在消息队列中
- 一旦执行栈的执行任务完毕,系统会依次读取消息队列里的异步任务,被读取的异步任务
结束等待状态,进入执行栈,开始执行
事件循环(event loop)
由于主线程不断的重复获得任务、执行任务、再获取任务、再执行,所以这种机制被称为事件循环( event loop)
location对象
location 的数据类型是对象,它拆分并保存了 URL 地址的各个组成部分
常用属性和方法:
- href 属性获取完整的 URL 地址,对其赋值时用于地址的跳转
- search 属性获取地址中携带的参数,符号 ?后面部分
- hash 属性获取地址中的啥希值,符号 # 后面部分
- reload 方法用来刷新当前页面,传入参数 true 时表示强制刷新
语法:loaction.属性
loactiom.方法()
navigator对象
navigator的数据类型是对象,该对象下记录了浏览器自身的相关信息
常用属性和方法: 通过 userAgent 检测浏览器的版本及平台
// 检测 userAgent(浏览器信息)
!(function () {
const userAgent = navigator.userAgent
// 验证是否为Android或iPhone
const android = userAgent.match(/(Android);?[\s\/]+([\d.]+)?/)
const iphone = userAgent.match(/(iPhone\sOS)\s([\d_]+)/)
// 如果是Android或iPhone,则跳转至移动站点
if (android || iphone) {
location.href = 'http://m.itcast.cn'
}
})()
histroy对象
history 的数据类型是对象,该对象与浏览器地址栏的操作相对应,如前进、后退、历史记录等
history对象和方法 | 作用 |
---|---|
back() | 可以后退功能 |
forward() | 可以前进功能 |
go(参数) | 前进,后退功能,参数决定,-1后退,1前进 |
本地存储
随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样的需求,会经常性在
本地存储大量的数据,HTML5规范提出了相关解决方案
- 数据存储在用户浏览器中
- 设置、读取方便、甚至页面刷新不丢失数据
- 容量较大,sessionStorage和localStorage约 5M 左右
localStorage
- 生命周期永久生效,除非手动删除 否则关闭页面也会存在
- 可以多窗口(页面)共享(同一浏览器可以共享)
- 以键值对的形式存储使用
语法
- 存储数据:
localStorage.setItem(key, value)
- 获取数据:
localStorage.getItem(key)
- 删除数据:
localStorage.removeItem(key)
存储复杂数据类型存储:
本地只能存储字符串,无法存储复杂数据类型.需要将复杂数据类型转换成JSON字符串,在存储到本地
JSON.stringify(复杂数据类型) :
将复杂数据转换成JSON字符串 存储 本地存储中
JSON.parse(JSON字符串):
将JSON字符串转换成对象 取出 时候使用
sessionStorage(了解)
- 生命周期为关闭浏览器窗口
- 在同一个窗口(页面)下数据可以共享
- 以键值对的形式存储使用
- 用法跟localStorage 基本相同
自定义属性
固有属性:
标签天生自带的属性 比如class id title等, 可以直接使用点语法操作
自定义属性:
由程序员自己添加的属性,在DOM对象中找不到, 无法使用点语法操作,必须使用专门的API
- 获取自定义属性 :
getAttribute('属性名')
- 设置自定义属性:
setAttribute('属性名', '属性值')
- 删除自定义属性:
removeAttribute('属性名')
data-自定义属性:
传统的自定义属性没有专门的定义规则,开发者随意定值,不够规范,所以在html5中推出来了专门的data-自定义属性 在标签上一律以data-开头
在DOM对象上一律以dataset对象方式获取
正则表达式
正则表达式(Regular Expression)是用于匹配字符串中字符组合的模式。在 JavaScript中,正则表达式也是对象
正则表达式在 JavaScript中的使用场景:
- 例如验证表单:用户名表单只能输入英文字母、数字或者下划线, 昵称输入框中可以输入中文(匹配)
- 比如用户名:
/^[a-z0-9_-]{3,16}$/
- 过滤掉页面内容中的一些敏感词(替换),或从字符串中获取我们想要的特定部分(提取)等 。
语法
使用:
- 定义规则
- 查找
语法:let 变量名=/表达式/
- / / 是正则表达式字面量,比如 :
let reg=/abc/
判断:
test() 方法 用来查看正则表达式与指定的字符串是否匹配 ,返回 false 或 true
let str = 'hello ,world' let reg = /hello/ console.log(reg.test(str)) //true
exec() 方法 在一个指定字符串中执行一个搜索匹配
如果匹配成功,exec() 方法返回一个数组,否则返回null
元字符
是一些具有特殊含义的字符,可以极大提高了灵活性和强大的匹配功能。
比如,规定用户只能输入英文26个英文字母,普通字符的话 abcdefghijklm…..
但是换成元字符写法: [a-z]
方便记忆和学习,众多的元字符进行了分类:
边界符(表示位置,开头和结尾,必须用什么开头,用什么结尾)
正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符
注意:如果
^
和$
在一起,表示必须是精确匹配。量词 (表示重复次数)
量词用来 设定某个模式出现的次数
注意: 逗号左右两侧千万不要出现空格
字符类 (比如
\d
表示 0~9)-
连字符使用连字符
-
表示一个范围比如:
- [a-z] 表示 a 到 z 26个英文字母都可以
- [a-zA-Z] 表示大小写都可以
- [0-9] 表示 0~9 的数字都可以
[ ] 里面加上
^
取反符号
比如:[^a-z]
匹配除了小写字母以外的字符
注意要写到中括号里面.
匹配除换行符之外的任何单个字符预定义:指的是某些常见模式的简写方式
修饰符
修饰符约束正则执行的某些细节行为,如是否区分大小写、是否支持多行匹配等
语法:
/表达式/修饰符
i 是单词 ignore 的缩写,正则匹配时字母不区分大小写
g 是单词 global 的缩写,匹配所有满足正则表达式的结果console.log(/a/i.test('a')) //true console.log(/a/i.test('A')) //true
替换 replace 替换:(过滤敏感词)
字符串.replace(/正则表达式/,'替换的文本')