Web APIs

Web APIs

Web APIs

什么是DOM

文档对象 操作网页的内容 实现用户交互

DOM树

wer

标签与标签的关系

DOM对象

把网页内容当对象 , 它提供的属性和方法都是访问和操作网页内容 , 网页所有内容都是document

获取DOM对象

//选择匹配的第一个元素
document.querySelector('css选择器 或 标签');
  • 如果没有找到,返回null
//选择匹配的多个元素
document.querySelectorAll('css选择器 或 标签')
  • 返回对象集合 ,没有找到也返回集合
  • 会得到伪数组 有长度 有索引号 但没有方法

修改样式

//修改css样式
对象.style.属性 = '属性值';
  • 如果属性有 - 符号 把 - 去掉 把后面的首字母大写
  • 例: background-color 改成 backgroundColor

其他获取方法

//根据ID获取
document.getElementById('id');
//根据标签获取
document.getElementsByTagName('div');
//根据类名获取
document.getElementsByClassName('box');

操作类

对象.className = '类名';
  • 在css里面写样式
  • 类名需要加上之前的类 不然会覆盖
//单纯的加一个类
对象.classList.add('类名');
//删除一个类
对象.classList.remove('类名');//返回伪数组
//原来有这个类删除 没有添加
对象.classList.toggle('类名'); //返回伪数组

操作表单元素

// 获取input 的属性
const input = document.querySelector('input')
// 对象.属性 = '属性值'
input.type = 'password'
console.log(input);

定时器

function name() {
console.log('giao')
}
//值1 函数不用加括号 值2 时间 毫秒
setInterval(name, 1000);
//方法二
setInterval(function (){console.log('giao')}, 1000);
  • 隔多少秒调用函数

停止计时器

clearInterval(计时器ID);
//获取计时器ID
let timerId = setInterval(......);

倒计时效果

<input type="button" class="btn" value="已阅读用户协议(5)" id="btn" disabled>
<script type="text/javascript">
let btn = document.querySelector('.btn');
let i = 5;
let timeId = setInterval(function () {
i -- ;
btn.value = `已阅读用户协议(${i})`;
if (i == 0) {
clearInterval(timeId);
btn.disabled = false ;
btn.value = '已阅读用户协议';
}
}, 1000);
</script>

修改元素的内容

对象.innerText = ''

  • 只能获取文本

对象.innerHTML = ''

  • 可以获取所有内容 包括标签 空格
  • 会自动解析标签

保留原内容

  • 对象.innerHTML = '对象.innerHTML + '新内容' '
  • 对象.innerText = '对象.innerText + '新内容' '

事件监听

事件监听定义

监听网页有没有发生这些事情,如果发生了就给一个对应的函数来处理

监听三要素

事件源

  • 发生事情的元素

事件类型

  • 具体发生了什么 是被双击还是鼠标经过...

响应程序

  • 就是函数,事件发生后调用函数

监听语法

标签对象.addEventListener('事件类型',函数);
  • 事件类型需要加引号 函数不用加括号

随机点名

  • 步骤:
    1. 找对应标签(div,开始按钮,结束按钮)
    2. 给开始按钮加点击事件,开启一个定时器,间隔不断的随机出一个下标,再根据下标取出数组里的值,然后把值显示到div里
    1. 给结束按钮加点击事件,需要停止定时器,声明一个全局变量保存定时器的id,在结束里就可以停止定时器了
    2. 要完成点一个少一个,所以需要把随机出来的下标也保存起来,所以把它升级成全局变量,然后在结束的点击事件里根据下标删除数组元素
    1. 在开始的点击事件里一开始就做判断,如果数组长度为1了,就没必要随机了,而是直接取出下标0的值显示到页面,并且把开始和停止两个按钮禁用即可,再return,让后面代码不执行了(不开定时器了)
  • bug1:

    • 连续先点好几下结束按钮,会直接把数组删光
    • 解决办法:判断有定时器才删除,所以就是判断定时器id是否为null,不为null才删除
    • 但是此时会有新bug,只要开一个定时器后,还是能再删数组,所以停止定时器后,需要立即把timerId改为空即可
  • bug2:

    • 点击多次开始按钮,这个时候点击结束按钮,结束不了
    • 原因:多次点击开始,会产生多个定时器,而定时器id只能保存最后一个,所以点击结束时无法全部停掉
    • 解决办法:点击多次开始也只让它产生一个定时器,也就是开启新的定时器之前,先把上一个关掉
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
h2 {
text-align: center;
}
.box {
width: 600px;
margin: 50px auto;
display: flex;
font-size: 25px;
line-height: 40px;
}
.qs {
width: 450px;
height: 40px;
color: red;
}
.btns {
text-align: center;
}
.btns button {
width: 120px;
height: 35px;
margin: 0 50px;
}
</style>
</head>
<body>
<h2>随机点名</h2>
<div class="box">
<span>名字是:</span>
<div class="qs">这里显示姓名</div>
</div>
<div class="btns">
<button class="start">开始</button>
<button class="end">结束</button>
</div>
<script>
// 数据数组
let arr = ['马超', '黄忠', '赵云', '关羽', '张飞']
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
// 找到三个元素
let qs = document.querySelector('.qs')
let start = document.querySelector('.start')
let end = document.querySelector('.end')
// 全局变量timerId:记录定时器的id
let timerId = null
// 全局变量idx:记录当前被点名的下标
let idx = 0
// 给开始加点击事件
start.addEventListener('click', function () {
// 点击开始时要做判断
// 判断数组元素数量是否只有1个了,如果只有一个了,就不要开定时器
// 把按钮给禁用了
if (arr.length == 1) {
// 把最后这个名字直接显示到页面
qs.innerText = arr[0]
// 让开始和停止两个按钮的disabled都为true
start.disabled = end.disabled = true
return // 后面代码不执行了
}
// 每次开新的定时器之前需要把上一次的定时器给停止掉
clearInterval(timerId)
// 把产生随机名字的代码,放到定时器里
timerId = setInterval(function () {
// 产生一个随机下标
idx = getRandom(0, arr.length - 1)
// 根据随机下标取出数组里的数据赋值给qs去显示
qs.innerText = arr[idx]
}, 25)
})
// 给结束按钮加点击事件
end.addEventListener('click', function () {
// 有定时器才停止定时器,并删除数组
if (timerId != null) {
// 停止定时器
clearInterval(timerId)
// 停止定时器后,马上把定时器id改为null
// 避免下次还能再点
timerId = null
// 点一个少一个,也就是删掉数组里出现的元素
arr.splice(idx, 1)
}
})
</script>
</body>
</html>

监听事件

  • 事件源.on事件 = function () {}
    • 写两个一样的会覆盖
  • 事件源.addEventListener(事件,函数)
    • 写两个一样的不会覆盖

事件类型

鼠标事件

  • click 鼠标单击
  • mouseenter 鼠标经过
  • mouseleave 鼠标离开

焦点事件

  • focus 获取焦点
  • blur 失去焦点

键盘事件

  • Keydown 键盘按下触发
  • Keyup 键盘抬起触发

表单输入

  • input 用户输入 一边输入 一遍触发

高阶函数

函数表达式

let fn = function (){
consolg.log('giao');
};
//表达式名 + () 调用方法
fn();

回调函数

function fn1(fn2){
console.log(fn2);
}
function fn2(){
console.log('giao');
}
//fn2 就是回调函数 把函数当数据传给传递
//函数当值的时候不用加()
fn1(fn2);

环境对象 - this

  • 指函数里的this
  • 谁调用的函数this就是谁

节点

节点简介

  • 元素节点:指的标签
  • 属性节点:指的属性
  • 文本节点:指的文本
  • 其他节点:注释,document

父节点与子节点

  • 父节点:包括别的节点
  • 子节点:被包含的节点

查找父节点

元素.parentNode

  • 找到父元素

查找子节点与子元素

子节点

元素.childNodes

  • 找的节点:包括标签,文本,注释

子元素

元素.children

  • 找的标签

注意:找到的都属伪数组

查找兄弟节点与元素

上一个兄弟

元素.previousSibling

  • 上一个节点
  • 找的节点:包括标签,文本,注释

元素.previousElementSibling

  • 找到上一个标签

下一个兄弟

元素.nextSibling

  • 下一个节点
  • 找的节点:包括标签,文本,注释

元素.nextElementSibling

  • 找到下一个标签

创建元素

let 名字 = document.createElement('标签名'); // 只能是标签名
//元素默认看不到,变成被人的子元素
名字.innerText = '内容'
//在父元素的最后添加名字
父元素.appendChild(名字);

添加元素

//在元素最后添加
父元素.appendChild(名字);
//在指定的位置添加
//如果第二个参数传入的是null或者undefined,那也是添加到最后
父元素.insertBefore(要添加的元素, 在哪个子元素的前面);
//插入到最前面
父元素.insertBefore( 要添加的元素, 父元素.children[0] )
例如:ul.insertBefore(li, ul.children[0])

克隆元素

元素.cloneNode();
  • 克隆出元素
  • 浅克隆
  • 只会克隆所有的行内属性,但不会克隆出内容
元素.cloneNode(true);
  • 克隆出元素
  • 深克隆
  • 克隆出所有的内容

两种克隆都不会包含元素的事件监听

行内事件

<div onclick="alert('123')">
盒子
</div>
  • 克隆会包含行内事件,因为行内事件相当于行内属性

删除元素

父元素.removeChild(删除的子元素);
  • 常用的方法
删除的元素.remove();
  • 新浏览器可以调用remove

去除两端空格

元素.trim();

重绘和重排(回流)

  1. 解析HTML生成DOM树
  2. 同时解析CSS生成样式规则
  3. 根据DOM树和样式规则生成渲染树
  4. 进行重排得到几何信息(位置,大小)
  5. 进行绘制进行整个页面的绘制
  6. 展示页面

重排(回流)

  • 当渲染树发生尺寸,结构,布局改变的时候会进行重排

重绘

  • 当节点元素的样式改变,并不影响在文档流中的位置就会重绘

导致重排的一些操作

  • 页面的首次刷新

  • 浏览器的窗口大小发生改变

  • 元素的大小或位置发生改变

  • 改变字体的大小

  • 内容的变化(如:input框的输入,图片的大小)

  • 激活css伪类 (如::hover)

  • 脚本操作DOM(添加或者删除可见的DOM元素)

  • 总结:影响到布局的会有重排

导致重绘的一些操作

  • 背景颜色改变

  • 字体颜色改变

  • ......

  • 总而言之:如果只是不影响布局的,那就只有 重绘 没有 重排

事件对象

事件对象与获取

触发事件时,浏览器自动帮我们产生一个对象

  • 如何拿到

    对象.addEventListener('click',function (形参){
    //这个形参就是事件对象
    })

事件对象常用的属性

type

  • 获取事件类型 比如会得到 click dblckick

pageX / pageY

  • 获取元素到页面文档左上角的x,y距离

clientX / clientY

  • 获取元素到可视区域左上角的x,y距离

offsetX / offsetY

  • 获取鼠标位置到触发元素自身左上角的x,y距离

key

  • 按下按键时获取键盘按钮

事件流

事件流三大阶段

  • 捕获阶段:从document开始一级一级往下
  • 目标阶段:触发事件的元素
  • 冒泡阶段:从触发事件的元素一级一级往上返

为什么会流动

因为当一个div被点击,其实最早并不是由div先发现的,而是先由浏览器发现的,所以需要一级一级往下找到真正触发事件元素,再处理事件,处理完再一级一级往上依次反馈

事件冒泡

当一个元素的事件出发后,会一级一级往上调用父级元素的同名事件,直到document

事件捕获

元素.addEventListener('事件类型', 回调函数, true)
  • 默认看不到,必须写上面代码

    要想看到事件捕获,必须用 L2 事件注册语法,且第三个参数要传true

    L0只有冒泡没有捕获

阻止流动

事件对象(函数里的参数).stopPropagation()
  • 一定要获取事件对象
  • 不光能阻止冒泡还能阻止捕获

mouseover与mouseout

  • 鼠标移入和移出(不推荐)
  • 他从父到子也会触发移入移出,效率不高

mouseenter与mouseleave

  • 鼠标移入移出
  • 不会叠加冒泡

阻止事件默认行为

例如a标签点击之后不跳转

  • 事件对象.perventDefault()

事件委托

冒泡默认存在,所有不管哪个子元素都会触发父元素

很多时候不希望所有子元素都触发,所有在父元素上判断

事件元素.target 获取真正触发的元素
事件元素.target.tagName 获取的都是大写

滚动事件

滚动事件

scroll 只要滚动就会触发 window对象,代表浏览器 ,如果要监听浏览器滚动,就要给window加scroll事件

window.addEventListener('scroll', function () {
// 页面资源加载完毕才调用
})
//也可以给元素加 谁有滚动给谁加
div.addEventListener('scroll', function () {
// 页面资源加载完毕才调用
})

页面加载事件

当页面所有资源加载完毕之后调用

window.addEventListener('load', function () {
// 页面资源加载完毕才调用
})

dom加载事件

等dom加载完毕就调用

document.addEventListener('DOMContentLoaded', function () {
// dom加载完毕调用
})

scroll家族

  • scrollWidth 和 scrollHeight

    获得 内容 + padding + 溢出 就是元素的宽高

  • scrollLeft 和 scrollTop
    ○ 是内容往左边滚出去看不到的距离(scrollLeft)
    ○ 是内容往上边滚出去看不到的距离(scrollTop)
    ○ 这两个属性可以改,改了就代表设置滚动条滚出去的距离
    ○ 可以把scrollLeft和scrollTop设置的超出它最大的滚动距离,那样也只是帮你滚到最后
    ○ 所以如何让垂直滚动条能滚到最后?

    元素.scrollTop = 元素.scrollHeight

页面滚出去的距离

document.documentElement

  • 获取html

document.documentElement.scrollTop

  • 获取HTML向上的距离 可以赋值

offset家族

  • offsetWdith 和 offsetHeight 获取的是盒子实际占用宽度高度
  • offsetLeft 和 offsetTop 获取的是盒子到定位自己的父级 左或上 距离

client家族

  • clientWidth 和 clientHeight

    获得的是边框里面的内容

    可视区

  • 作用:方便根据视口大小做响应式开发

JS执行

定时器-延时执行

setTimeout(function(){},1000)

  • 1秒之后执行一次,只一次

递归函数

函数自己调用自己 , 一级一级递过去,又一级一级归来

JS执行机制

同步与异步

  • 同步:

    • 就像在超市结账,只有一个收银口,大家依次排队,上一个结算完了再结算下一个
    • 所谓同步:就是从上往下依次执行(像排队一样)
  • 异步:

    • 就像在超市结账,只有一个收银口,其中有个人结账时对质量不满意,那么就先把这个人带去跟部门经理沟通,收银口继续对下一个客户进行结算,等部门经理沟通完了,这个人再来排队买单
    • 像这种情况在代码中有一个专业名词叫 异步
    • JS中,异步任务一般是通过 回调函数 实现的,一般可能需要耗时的代码都是异步代码
      • 例如:定时器可能要耗时,例如事件可能要耗时
      • 异步代码是通过 回调函数 来实现的
  • setInterval(回调函数) // 异步代码
    setTimeout(回调函数) // 异步代码
    btn.addEventListener('click', 回调函数) // 异步代码
    // 包括后面要学的ajax(发网络请求,网络可能会耗时,所以它也是异步代码)

执行图

图

  • 异步进入Event Table(事件表)区分异步 然后进入 Event Queue(事件队列),主线程执行完毕就会去Event Queue(事件队列)读取异步函数,会重复不断执行,也就是Event Loop(事件循环)

window对象

  • navigator 对象
  • location 对象
  • document 对象
  • history 对象
  • screen 对象

location对象

  • 代表浏览器的地址栏
  • 属性
    • href
      • 可以获取当前浏览器的网址
      • 也可以设置网址
    • search
      • 获取浏览器上 ?+后面的部分内容(获取查询)
      • 例如 ?.sht
    • hash
      • 获取浏览器上 #+后面的内容
      • 例如 #23th
  • 检查浏览器信息 判断PC还是移动
// 检测 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'
}
})()

history对象

  • 代表浏览器的历史记录

  • history.forward(); 前进

  • history.back(); 后退

  • go(number);

    • 正数代表前进,负数代表后退
    • 正1:代表前进1个,正2,代表前进2个,以此类推
    • 负1:代表后退1个,负2,代表后退2个,以此类推

JSON字符串

本质是一种字符串

  • 作用:前后端传递数据

  • 规则:

    • [] 表示的是数组, {} 表示的是对象
    • 如果用 {} 表示对象,那么键必须用双引号 包起来
    • 字符串最外层要么是 [] 要么是 {}
  • 把json字符串转换为JS

    • JSON.parse( json字符串 );
    • JSON.stringify( js数据 )

localStorage

本地储存 , 把数据储存到浏览器,永久储存 , 只要不删就一直存在

是按域名保存的,域名A下域名A自己的数据,域名B的网站是访问不了域名的A的数据的,同样域名A也访问不了域名B的数据

setltem

localStorage.setItem(参数1(key),参数2(值);
  • 保存数据
  • 如果保存相同的key,后面的覆盖前面的

getItem

localStorage.getItem(参数(key));
  • 获取参数
  • 如果数据不存在,得到null

removeItem

localStorage.removeItem(参数(key));
  • 删除数据

clear

localStorage.clear();

在浏览器找到 localStorage 保存的数据

hh

  • localStorage只能保存字符串数据,如果你传入了非字符串数据,那它也强制把数据转成了字符串再保存的

  • 如何保存复杂类型?(对象、数组那些)

    • 把复杂类型转成JSON格式的字符串保存起来
    • 然后取出来的时候,再把它按JSON字符串转成JS数据

sessionStorage

会话存储 ,只要页面关闭数据就没了

其他属性和localStorage一样

自定义属性

  • 一种是系统属性 系统自带 例如 href target等等

  • 自定义属性就是自己添加的,原本没有

  • 区分自定义属性

    • h5后新增规范
    • 一般在定义属性前 data-自定义名字

    • 可以用 元素.dataset 操作属性

    • // html元素 <textarea id="address" data-name="yyy" data-role="xxx"></textarea>
      let dom = document.querySelector("#address")
      // 获取元素节点的所有 data-* 属性
      console.log(dom.dataset) // {name: 'yyy', role: 'xxx'}
      // 删除 data-name 属性
      delete dom.dataset.name
      // 添加/修改 data-test 属性
      dom.dataset.名字 = '值'
  • 自定义属性,在js中无法通过 点语法 直接操作的

  • 如果要操作属性

    • 元素.getAttribute('属性');

      获取元素

    • 元素.setAttribute('属性','属性值');

      设置属性

    • 元素.removeAttribute('属性');

      删除属性

window对象是JS里的顶级对象

所有window的属性可以理解为是全局变量

<script>
function fn () {
window.age = 999 // 相当于是全局变量
console.log(age) // 999
}
fn() // 也可以完整写成 window.fn,因为这相当于是window的方法
console.log(age) // 999
</script>

正则

正则表达式

  • 描述字符串的特征

查找字符串有没有'字符'

/字符/.test(字符串范围(例如:input.value));
  • 判断字符串范围有没有字符
  • 有 返回 true
  • 没有 返回 false

元字符-边界符

  • ^ 以什么内容开头
  • $ 以什么内容结尾
/^内容/ // 内容XXX
/内容$/ // XXX内容
  • 结合在一起就是精确匹配 必须是 内容

元字符-量词

量词 说明
* 出现0或多次
+ 出现1次或多次
? 出现0次或1次
出现n次
出现至少n次
出现至少n次,最大m次
  • 这些量词只修饰它左边的那一个字符,所以要修饰整体,记得内容加小括号包起来

元字符-字符类

  • | 要么左 要么右

    • a | b | c 要么a 要么b 要么c 任意一个
  • []

    • 匹配字符集合 括号中任意一个都可以
    • [abc123] 要么a 要么b 要么c 要么1 要么2 要么3
  • [-]

    • 表示范围 [起点-终点]

    • [a-z] // a-z中的任意一个
      [0-9] // 0-9中的任意一个
      [A-Z] // A-Z中的任意一个
      [a-zA-Z0-9] // 代表任意一个大小写字母或者任意一个数字
  • [^]

    • 表示非
    • [^0-9] // 除了0-9 的任意一个
  • .

    • 除了\r\n 以外的任意数

注意 : 不加严格匹配代表只要有即可 加了严格匹配代表只能是某个格式

匹配中文

/[\u4e00-\u9fa5]/
  • \u4e00 就是第一个汉字

  • \u9fa5 就是最后一个汉字

元字符-预定义类

  • 预定义类:就是正则里用特殊符号来标识它属于哪一类数据
预定义类 说明
\d\d 匹配数字
\D 匹配非数字
\w 匹配文本字符,也就是任意字母、数字、下划线
\W 匹配非文本字符,也就是除了字母、数字、下划线
\s 匹配不可见字符
\S 匹配可见字符

正则修饰符

/正则内容/修饰符
例如 /[a-z]/ig 忽略大小写全局匹配
  • i 忽略大小写
  • g 全局匹配 可以找到所有匹配的内容
  • 两个一起写 代表 既忽略大小写,也全局匹配

替换

  • 内容.replace(表达式,要替换的内容)
str.replace(正则表达式, 要替换的内容)
// 例
let str = 'oooOOO哈哈哈OOOooo'
str = str.replace(/o/ig, '') // 把所有的o不区分大小写全部替换成空字符串
console.log(str) // 哈哈

正则本质

  • 正则本质上就是一个对象, /规则/ 这种写法是字面量表示法
  • 也可以用构造函数创建出一个正则
  • 传两个参数 规则(必须有),修饰符(可不写)

let 对象名 = new RegExp('规则', '修饰符')

let reg = new RegExp('sb', 'ig') // 代表忽略大小写而且全局的找sb
// 如果要找字母数字下划线怎么写? 字面量:/\w/
let reg2 = new RegExp('\\w', '修饰符')
  • 注意:如果要写预定义类,要多加一个\,例如\\w\\d,因为 \ 在js字符串中是转义的意思,所以要写 \ 就必须写 \\

如何用敏感词库

  • 先把敏感词库的数组转成字符串(用 |
  • 再然后用 new RegExp 来创建正则对象
let words = ['sb', '激情', '政府', '警察' ]
let str = words.join('|')
let reg = new RegExp(str, 'ig')
console.log( "今天大家都很sb,也很有激情,大家要爱护警察,支持政府!".replace(reg, '**') )

正则的exec方法(了解)

  • 正则对象除了 test 方法,还有一个方法叫 exec ,就是用来做提取内容的
/哈哈/.exec('你好啊,哈哈');
  • 得到数字

gg

邮箱验证

  • 前一段是允许字母,数字,下划线 至少1位最多18位
  • 后面接一个@
  • @后面接 字母数字,至少1位
  • 后面接一个 .
  • 点后面接英文字母,至少2位,最多4位
  • .com或.cn 可能出现多次,但至少要一次
  • 正则如下
/^\w{1,18}@[a-z0-9]+(\.[a-z]{2,4})+$/i
  • 点前面的 \ 是转义因为 . 有特殊含义
posted @   rain_sparse  阅读(28)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示