WebAPI
一、webAPI的基本认识
作用:
就是使用JS去操作 html 和浏览器
分类:
DOM(文档对象模型)、BOM(浏览器对象模型)
什么是DOM
DOM(Document Object Model——文档对象模型) :是用来呈现以及与任意 HTML 或 XML文档交互的API 白话文:DOM是浏览器提供的一套专门用来 操作网页内容 的功能 DOM作用: 开发网页内容特效和实现用户交互
DOM树
DOM树是什么? 将 HTML 文档以树状结构直观的表现出来,我们称之为文档树或 DOM 树 描述网页内容关系的名词 作用:文档树直观的体现了标签与标签之间的关系
DOM对象【重要】
DOM对象:浏览器根据html标签生成的 【JS对象】
所有的标签属性都可以在这个对象上面找到 修改这个对象的属性会自动映射到标签身上
DOM的核心思想
把网页内容当做对象来处理
document对象
是 DOM 里提供的一个对象 所以它提供的属性和方法都是用来访问和操作网页内容的 例:document.write() 网页所有内容都在document里面
二、获取DOM对象
1、选择匹配的第一个元素
语法:
document.querySelector('css选择器')
// k可以直接对获取到的元素直接进行修改
参数:
包含一个或多个有效的CSS选择器 字符串
返回值:
CSS选择器匹配的第一个元素,一个 HTMLElement对象。 如果没有匹配到,则返回null。
2、选择匹配的多个元素
语法:
document.querySelectorAll('css选择器')
document.querySelectorAll('ul li')
// 需要通过遍历的方式,依次给里面的元素做修改
参数:
包含一个或多个有效的CSS选择器 字符串
返回值:
CSS选择器匹配的NodeList 对象集合[伪数组]
得到的是一个伪数组: 有长度有索引号的数组 但是没有 pop() push() 等数组方法
3、其他获取DOM元素方式
<div id="nav">id nav</div>
<p>这个是p标签</p>
<div class="container">div container</div>
<script>
// 根据Id获取页面元素
let nav = document.getElementById('nav');
// 根据标签名 获取页面一组元素
let ps = document.getElementsByTagName('p')
// 根据 类名 获取页面一组元素
let divs = document.getElementsByClassName('container')
</script>
三、设置/修改DOM元素内容
1、document.write() 方法
只能将文本内容追加到 前面的位置 文本中包含的标签会被解析
// 永远都是追加操作,且只能在</body>前
document.write('Hello World!')
document.write('<h3>你好,世界!</h3>')
2、对象.innerText 属性
将文本内容添加/更新到任意标签位置 文本中包含的标签不会被解析
document.querySelector('li:nth-child(2)').innerText = '<button>按钮</button>'
3、对象.innerHTML 属性
将文本内容添加/更新到任意标签位置 文本中包含的标签会被解析
document.querySelector('li:nth-child(3)').innerHTML = `<button>按钮</button>`
四、设置/修改DOM元素属性
DOM元素属性:属性都是以键值对的形式
如:src、title、alt等都是属性
<img src="" title="" alt="" class="" id=""/>
1、设置/修改元素 常用 属性
语法:
对象.style.样式属性 = 值
// 1、获取dom元素
let div = document.querySelector('div')
// 2、开始修改
div.style.fontSize = '50px'; // 修改字体大小为50px
div.style.backgroundColor = 'red';
div.style.width = '500px'
div.style.margin = '100px auto';
div.style.border = '5px solid black'
// 会出现 单词写错或者 值写错 写漏
// 那段代码没有效果 就去看那段代码
注意:
修改样式通过style属性引出 如果 属性有-连接符 ,需要转换为 小驼峰 命名法 赋值的时候,需要的时候不要忘记加 css单位
2、设置/修改元素 样式 属性
1️⃣通过className操作类
语法:
// active 是一个类名
元素.className = 'active'
注意:
直接使用 className 赋值会覆盖以前的类名
如果想要同时设置多个 class 以空格做分割即可
2️⃣通过classList操作类
语法:
// 追加一个类
对象.classList.add('类名')
// 删除一个类
对象.classList.remove('类名')
// 切换一个类
对象.classList.toggle('类名')
let divDom = document.querySelector('div')
// 添加一个类
/* divDom.classList.add('d2')
divDom.classList.add('d3') */
// 一次添加多个类
divDom.classList.add('d2','d3','d4')
// 删除一个类
// divDom.classList.remove('d3')
// 一次删除多个类
divDom.classList.remove('d3','d2')
// 切换 , 如果有就删掉,如果没有就添加
divDom.classList.toggle('d4')
3、设置/修改 表单元素 属性
获取: DOM对象.属性名
设置: DOM对象.属性名 = 新值
设置文本内容
DOM对象.value= 值
<input class="username" type="text">
<script>
let username = document.querySelector('.username')
// 设置文本框的文本内容
username.value = '我的用户名';
</script>
设置勾选上
DOM对象.checked = true/false
是否同意协定
<input class="isarg" type="checkbox" checked>
<script>
// 复选框
let isarg = document.querySelector('.isarg')
// 设置勾选上
isarg.checked = true;
// 不勾选
isarg.checked = false;
</script>
设置按钮禁用
button.disabled = true/false
<button class="code">按钮</button>
<script>
// 按钮
let btn = document.querySelector('.code')
// disabled 禁用
btn.disabled = true; // 禁用
btn.disabled = false; //启用
</script>
设置下拉列表选中
option.selectd = true
<select class="sel">
<option>小日本</option>
<option>泡菜国</option>
<option>老美</option>
</select>
<script>
// selected 选中
let option = document.querySelector('option:nth-child(4)')
// option.select = true // 错误的单词
option.selected = true
</script>
文本域标签
获取值
想要获取内容
.value 原样的内容
.innerHTML 获取的内容如果包含html会转换
<textarea>你好</textarea>
<script>
// 获取文本域标签
// 属于表单元素 又是双标签
let textarea = document.querySelector('textarea')
// 获取文本域中的值
console.log(textarea.value); // 可以获取 ,原样输出
console.log(textarea.innerText); // 不可获取
console.log(textarea.innerHTML); // 不可获取,会解析符号
</script>
设置值
// 通过js的方法设置内容 都是原样的输出
textarea.value = `<h1>标题</h1>`
textarea.innerText = `<h1>标题</h1>`
textarea.innerHTML = `<h1>标题</h1>`
五、定时器-间歇函数
基本使用
1、开启定时器
setInterval(函数,间隔时间)
作用:每隔一段时间调用这个函数 间隔时间单位是毫秒
// 函数 负责 定时执行任务
function repeat() {
console.log('MkrYYDS');
}
// 每个一秒执行一次函数
// 时间单位 毫秒 1000毫秒 = 1秒
setInterval(repeat, 1000) // 里面的函数不需要写()
注意: 函数名字不需要加括号 定时器返回的是一个id数字
2、关闭定时器
let 变量名 = setInterval(函数,间隔时间)
clearInterval(变量名)
延时器
setTimeout(函数,间隔时间)
作用:隔一段时间调用这个函数,间隔单位是毫秒(只调用一次)
// 延时器 + 递归创建定时器
let index = 1
function func () {
console.log(index)
index++
setTimeout(func,1000)
}
func()
六、事件
1、什么是事件
事件是在编程时系统内发生的动作或者发生的事情 比如用户在网页上单击一个按钮
※2、什么是事件监听
就是让程序检测是否有事件产生,一旦有事件触发,就立即调用一个函数做出响应,也称为 注册事件
语法:
元素.addEventListener(事件类型,要执行的函数)
事件监听三要素:
1、事件源
dom元素被事件触发了,要获取dom元素
2、事件类型
用什么方式触发,比如鼠标单击 click、鼠标经过 mouseover 等
3、事件处理程序
要做什么事
3、给DOM元素添加事件
<button>按钮</button>
<script>
// 1、获取dom元素,作为事件源
let btn = document.querySelector('button')
// 2、事件监听(注册事件)
btn1.addEventListener('click', function () {
// 每点击一次就执行一次
alert('被点击了')
})
</script>
注意:
1、事件类型要加引号 2、函数是点击之后再去执行,每次点击都会执行一次
4、事件监听版本
DOM L0
事件源.on事件 = function() { }
<button>点击</button>
<script>
// 获取button元素
let btn = document.querySelector('button')
btn.onclick = function () {
console.log('事件被我触发了');
}
</script>
DOM L2
事件源.addEventListener(事件, 事件处理函数)
<button>按钮</button>
<script>
// 1、获取dom元素,作为事件源
let btn = document.querySelector('button')
// 2、事件监听(注册事件)
btn1.addEventListener('click', function () {
// 每点击一次就执行一次
alert('被点击了')
})
</script>
区别:
1、on也可以在 行内 不推荐
2、addEventListener 可以对一个事件类型 绑定多个处理函数
on + 事件 对一个事件类型 只能绑定一个处理函数
5、事件类型
事件 | 触发条件 |
---|---|
click | 鼠标点击时触发 |
focus | 获取焦点时触发(用于表单) |
blur | 失去焦点时触发(用于表单) |
mouseenter | 鼠标经过是触发 |
mouseleave | 鼠标离开时触发 |
keydown | 键盘按下时触发(通常是给body加) |
keyup | 键盘弹起时触发(通常是给body加) |
input | 用户输入时触发(用于表单) |
6、取消绑定事件
语法:
dom.removeEventListener('click',事件处理函数名)
dom.addEventListener('click',func)
function func () {
xxx
}
dom.removeEventListener('click',func)
addEventListener可以绑定多个同名事件,addEventListener('click')
只有绑定事件时写的具名函数才能取消绑定
七、排他思想及this
1、先通过for循环获取所有人,并统一设置成一个样式
2、再找到自己单独设置
案例
<script>
let tab_item = document.querySelectorAll('.tab-item')
let main = document.querySelectorAll('.main')
for (let index = 0; index < tab_item.length; index++) {
tab_item[index].addEventListener('click', function () {
// 排他思想
for (let j = 0; j < tab_item.length; j++) {
tab_item[j].classList.remove('active')
}
this.classList.add('active')
for (let k = 0; k < main.length; k++) {
main[k].classList.remove('active')
/* if(index === k) {
main[k].classList.add('active')
} */
}
// li 和 div长度都是4,li显示的时候,div也要显示
main[index].classList.add('active')
})
}
</script>
this
全局都有一个共同的对象window
this指向:谁调用我,我就是谁。
哪个元素绑定了事件,哪个元素就是this
八、节点操作
DOM元素中(DOM树)每一个内容都是节点
1、节点类型
※元素节点
所有的标签,比如body、div。html是根节点
属性节点
所有的属性 比如标签内的,href , class等
文本节点
标签内的文本
其他节点
空格,注释等
2、查找节点
父节点
查找最近一级的父节点,没有返回null
语法:
元素.parentNode
let btn = document.querySelector('button')
console.log(btn.parentNode);
子节点
1、childNodes
查找所有子元素,包括空格,文字,注释,标签等,返回一个伪数组
父元素.childNodes
let ul = document.querySelector('ul')
console.log(ul.childNodes);
2、children
查找子元素(标签),返回的是一个伪数组,即使没有也返回一个空数组
父元素.children
let ul = document.querySelector('ul')
console.log(ul.children);
兄弟节点
1、nextElementSibling
下一个兄弟元素(获取不到就报错)
let lis = document.querySelectorAll('li')
lis.nextElementSibling.style.backgroundColor = 'red'
2、previousElementSibling
上一个兄弟元素(获取不到就报错)
let lis = document.querySelectorAll('li')
lis.previousElementSibling.style.backgroundColor = 'blue'
3、创建节点
创建元素节点
document.createElement('节点')
let li = document.creatElement('li')
创建文本节点
document.createTextNode('内容')
let text = document.createTextNode('文本')
4、增加节点
1、appendChild
插入到父元素的最后一个子元素
// 插入到这个父元素的最后
父元素.appendChild(要插入的元素)
let li = document.querySelector('.left li:first-child')
let rightUl = document.querySelector('.right')
// 把li标签移动到到右边ul中
rightUl.appendChild(li)
// 一次插入多个
rightUl.append(li,li,li)
2、insertBefore
插入到父元素中某个子元素的前面
// 插入到某个子元素的前面
父元素.insertBefore(要插入的元素,在哪个元素前面)
// 把c插入到2之前
let c = document.querySelector('.left li:nth-child(3)')
let two = document.querySelector('.right li:nth-child(2)')
let right = document.querySelector('.right')
// 父元素.insertBefore(要插入的元素,哪个元素上面)
right.insertBefore(c,right.children[0])
共同点
appendChild(元素)、父元素.insertBefore(要插入的元素,在哪个元素前面)
如果该元素是已经存在,那他的作用是 剪切/移动
5、克隆节点
复制某个节点
元素.cloneNode(布尔值)
true 表示深克隆,连同子节点一起克隆
false 表示浅克隆,只克隆自己【默认值】
let box = document.querySelector('.box')
let newBox = box.cloneNode() // 浅克隆
let newBox2 = box.cloneNode(true) // 深克隆
6、删除节点
在 JavaScript 原生DOM操作中,要删除元素必须通过父元素删除
语法:
删除指定元素
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script>
父元素.removeChild(要删除的元素)
let ul = document.querySelector('ul')
let li = document.querySelector('li:first-child')
// 删除指定元素
ul.removeChild(li)
</script>
删除自己
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script>
// 删除自己
// 元素.remove()
ul.remove()
</script>
九、时间对象
1、实例化
let date = new Date() // 获取当前时间
let date = new Date('1949-10-01')
2、时间对象方法
方法 | 作用 | 说明 |
---|---|---|
getFullYear() | 获得年份 | 获取四位年份 |
getMonth() | 获得月份 | 取值为 0 ~ 11 |
getDate() | 获取月份中的每一天 | 不同月份取值也不相同 |
getDay() | 获取星期 | 取值为 0 ~ 6 |
getHours() | 获取小时 | 取值为 0 ~ 23 |
getMinutes() | 获取分钟 | 取值为 0 ~ 59 |
getSeconds() | 获取秒 | 取值为 0 ~ 59 |
let date = new Date() // 实例化一个时间对象
let year = date.getFullYear() // 获取当前年
let mouth = date.getMonth() + 1 // 获取当前月份 0-11,所以 + 1
let day = date.getDate() // 获取几号
let week = date.getDay() // 获取星期几 0-6 0是星期天
let hour = date.getHours() // 时 0-23
let minute = date.getMinutes() // 分 0-59
let second = date.getSeconds() // 秒 0-59
3、时间戳
方式一:
let date = new Date()
console.log(date.getTime());
方式二:
console.log(+ new Date());
方式三:
console.log(Date.now());
十、事件对象
事件对象是什么?
也是对象,这个对象里有事件触发时的相关信息
如何获取
事件绑定的回调函数的第一个参数就是事件对象
一般命名为event、ev、e
元素.addEventListener('click',function(e){ // e就是事件对象
})
事件对象常用属性
1、鼠标
const div = document.querySelector('div')
div.addEventListener('click',function (event) {
// clientX clientY 相对于浏览器窗口 左上角 获取鼠标的坐标
// offsetX offsetY 相对触发事件的元素 左上角 获取鼠标的坐标
console.log(event.clientX,event.clientY);
console.log(event.offsetX,event.offsetY);
})
2、键盘
document.body.addEventListener('keydown',function (event) {
// event.key 获取键盘按下的哪个按钮
console.log(event.key);
})
十一、事件流(事件传播)
1、事件流是什么?
事件流指的是事件完整执行过程中的流动路径
说明:假设页面里有个div,当触发事件时,会经历两个阶段,分别是捕获阶段、冒泡阶段 简单来说:捕获阶段是 从父到子 冒泡阶段是从子到父
事件冒泡(子到父)
事件冒泡是浏览器默认存在的
当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发
简单理解:当一个元素触发事件后,会依次向上调用所有父级元素的同名事件
事件捕获(父到子)
从DOM的根元素开始去执行对应的事件 (从外到里)
开启捕获
DOM.addEventListener(事件类型,事件处理函数,true)
c.addEventListener('click', function (event) {
alert('我是c')
event.cancelBubble
},true)
2、阻止事件流动
语法:【捕获和冒泡皆有效】
事件对象.stopPropagation()
c.addEventListener(
'click',
function (event) {
p.style.backgroundColor = 'red';
p.innerText = +p.innerText + 100;
console.log('c');
// 阻止冒泡 两种方法都可
event.stopPropagation()
// event.cancelBubble = true
}
);
3、阻止默认行为
阻止默认行为,比如链接点击不跳转,表单域的不提交
语法:
event.preventDefault()
btn.addEventListener('click',function (event) {
console.log('button');
event.preventDefault()
})
十二、事件委托
事件委托是利用事件流的特征解决一些开发需求的技巧
优点: 给父级元素加事件(可以提高性能)
原理: 事件委托其实是利用事件冒泡的特点, 给父元素添加事件,子元素可以触发
实现: 事件对象.target 可以获得真正触发事件的元素
十三、滚动事件
事件名:scroll
作用:监听整个页面滚动
语法:
div.addEventListener('scroll',function (event) {
console.log('我开始滚了');
console.log(event.target.scrollHeight);
})
监听某个元素的内部滚动直接给某个元素加即可
获取页面滚动距离
// 固定写法
document.documentElement.scrollTop
十四、页面加载事件
1、load
页面所有的资源加载完毕,包含外联css,jss,外部资源等,全部加载完成才运行
// load 等待外联css js 外部资源加载才显示 给window添加
window.addEventListener('load',function () {
console.log('load 全部资源加载完成就执行我');
})
2、DOMContentLoaded
页面所有的标签加载完毕,就运行
/ DOMContentLoaded 给document添加
// 页面的标签 都加载完毕就触发了,不需要等待标签的内容回来
document.addEventListener('DOMContentLoaded',function () {
console.log('DOMContentLoaded 页面标签加载完了就执行我');
})
十五、scroll、offset、client三家族
1、scroll
属性 | 含义 |
---|---|
scrollHeight | 高度可滚动的区域大小,不包含滚动条 |
scrollWidth | 宽度可滚动的区域大小,不包含滚动条 |
scrollTop | 垂直方向的滚动距离 |
scrollLeft | 水平方向的滚动距离 |
2、offset
属性 | 含义 |
---|---|
offsetWidth | 获取元素的宽度,包含padding和border |
offsetHeight | 获取元素的高度,包含padding和border |
offsetTop | 元素距离带有定位的最近父元素的垂直距离 |
offsetLeft | 元素距离带有定位的最近父元素的水平距离 |
3、client
属性 | 含义 |
---|---|
clientWidth | 获取可视区域的宽度,包含padding,不包含滚动条 |
clientHeight | 获取可视区域的高度,包含padding,不包含滚动条 |
clientTop | 上边框的大小 |
clientLeft | 左边框的大小 |
十六、屏幕大小改变事件
resize
屏幕大小发生改变就执行
// 当页面大小改变时就会触发的事件 resize 给window绑定
window.addEventListener('resize',function () {
// 移动端屏幕适配 rem 淘宝js库,flexible.js 作用 设置html的字体大小 为当前页面的宽度的十分之一
console.log(document.body.offsetWidth);
console.log(document.documentElement);
document.documentElement.style.fontSize = document.body.offsetWidth / 10 + 'px'
// 把body的宽度赋值给width
const width = document.body.offsetWidth
const title = document.querySelector('title')
if(width > 1200){
title.innerHTML = '大屏幕'+width
} else if(width>992) {
title.innerHTML = '中等屏幕' + width
} else if (width > 768) {
title.innerHTML = '小屏幕' + width
} else {
title.innerHTML = '极小屏幕' + width
}
})
BOM
BOM(Browser Object Model ) 是浏览器对象模型
window 是浏览器内置中的全局对象,我们所学习的所有 Web APIs 的知识内容都是基于 window 对象实现的 window 对象下包含了 navigator、location、document、history、screen 5个属性,即所谓的 BOM (浏览器对象模型) document 是实现 DOM 的基础,它其实是依附于 window 的属性。 注:依附于 window 对象的所有属性和方法,使用时可以省略 window
location
location 的数据类型是对象,它拆分并保存了 URL 地址的各个组成部分
属性/方法 | 作用 |
---|---|
location.href = 'www.baidu.com' | 属性获取完整的 URL 地址,对其赋值时用于地址的跳转 |
location.reload(true) | 强制刷新,true可选 |
location.search | 获取URL ? 后面的一串字符,包括 ? |
location.hash | 获取URL # 后面的一串字符,包括# |
navigator
navigator的数据类型是对象,该对象下记录了浏览器自身的相关信息
// 检测 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,后退一个页面 |
本地存储
1、数据存储在用户浏览器中 2、设置、读取方便、甚至页面刷新不丢失数据 3、容量较大,sessionStorage和localStorage约 5M 左右
localStorage
存储数据
localStorage.setItem(key,value)
localStorage.setItem('date',new Date())
获取数据
// localStorage.getItem('date')
const date = localStorage.getItem('date')
删除数据
localStorage.removeItem(key)
localStorage.removeItem('date')
删除全部
localStorage.clear()
sessionStorage
存储数据
sessionStorage.setItem(key,value)
sessionStorage.setItem('date',new Date())
获取数据
// sessionStorage.getItem('date')
const date = sessionStorage.getItem('date')
删除数据
sessionStorage.removeItem(key)
sessionStorage.removeItem('date')
删除全部
sessionStorage.clear()
十七、自定义属性
1、获取自定义属性
getAttribute('属性名')
getAttribute('hello')
2、设置自定义属性
setAttribute('属性名','属性值')
setAttribute('hello','123')
3、删除自定义属性
removeAttribute('属性名')
removeAttribute('hello')
4、h5建议自定义属性
dom.dataset.index
<a href="#" data-index='1'></a>
<script>
a.dataset.index
</script>
十八、重绘和回流
浏览器是如何进行界面渲染的
解析(Parser)HTML,生成DOM树(DOM Tree) 同时解析(Parser) CSS,生成样式规则 (Style Rules) 根据DOM树和样式规则,生成渲染树(Render Tree) 进行布局 Layout(回流/重排):根据生成的渲染树,得到节点的几何信息(位置,大小) 进行绘制 Painting(重绘): 根据计算和获取的信息进行整个页面的绘制 Display: 展示在页面上
回流(重排) 当 Render Tree 中部分或者全部元素的尺寸、结构、布局等发生改变时,浏览器就会重新渲染部分或全部文档的过程称为 回流。 重绘 由于节点(元素)的样式的改变并不影响它在文档流中的位置和文档布局时(比如:color、background-color、outline等), 称为重绘。
重绘不一定引起回流,而回流一定会引起重绘。
十九、正则表达式
1、边界符
^梅 必须以梅开头
$梅 必须以梅结束
2、量词
名称 | 作用 |
---|---|
* | 表示可以出现0次或多次 |
+ | 表示可以出现1次或多次 |
? | 表示可以出现0次或1次 |
{n} | 表示可以出现n次 |
{n,} | 表示最少出现n次,或者多次 |
{n,m} | 表示最少出现n次,最多出现m次 |
3、字符
名称 | 作用 |
---|---|
. | 表示任意字符,除了空格 |
\d | 表示数字 |
\D | 除了数字 |
\w | 数字字母下划线 |
\W | 除了数字字母下划线 |
\s | 匹配空格 |
\S | 匹配非空格 |
[a-z] | 匹配a-z的小写字母 |
[A-Z] | 匹配A-Z的大写字母 |
[0-9] | 匹配数字0-9 |
[a-zA-Z0-9] | 匹配大小写字母和数字 |
二十、JSON
1、JSON.stringify(数据)
转成JSON格式数据
2、JSON.parse(JSON数据)
把JSON格式数据转成非JSON格式