作用:使用JS操作html和浏览器
分类:DOM(文档对象模型),BOM(浏览器对象模型)

DOM

  • 定义:与HTML或XML文档交互的API,是浏览器提供的一种专门用来操作网页内容的功能,通过JS让网页元素发生变化(操作标签,让标签滚动;鼠标经过显示,离开隐藏等网页内容特效、交互效果)
  • DOM树:将HTML文档以树状结构直观地表现出来,显示出标签与标签之间的关系
  • html中的所有标签,在JS DOM中都叫做对象。DOM对象就是浏览器根据html标签生成的JS对象
  • 核心思想:把网页内容当作对象处理
  • 页面最大的对象:document 网页所有内容都在document中

获取DOM元素

一、根据CSS选择器获取DOM元素

1.选择匹配的第一个元素
1
document.querySelector('css选择器')

返回值:CSS选择器匹配的第一个元素

1
2
const p = document.querySelector('#nav')
p.style.color = 'red'
2.选择匹配的多个元素
1
document.querySelectorAll('ul li')

返回值:伪数组。要得到其中每一项需要遍历数组

1
2
3
4
5
6
7
8
9
10
11
12
13
<ul class = "nav">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>

<script>
const lis = document.querySelector('.nav li')
for(let i = 0;i < lis.length;i++)
{
console.log(lis[i])
}
</script>

二、其他方式获取DOM元素(了解)

1
2
3
document.getElementById('nav')
document.getElementsByTagName('div')
document.getElementsByClassName('w')

操作元素内容

  • 对象.innerText 属性(不解析标签)
1
2
3
4
5
6
7
8
<body>
<div class="box">文字内容</div>
<script>
const box = document.querySelector('.box')
console.log(box.innerText) /*获取文字内容*/
box.innerText = '修改后的文字'
</script>
</body>
  • 元素.innerHTML 属性(解析标签)
1
box.innerHTML = '<strong>修改后的文字</strong>'

操作元素属性

  • 修改常见属性如src:对象.属性 = 值
  • 通过style修改样式属性:对象.style.样式属性 = 值
    随机更换背景图片
1
2
3
4
5
6
7
8
<script>
function getRandom(N,M)
{
return Math.floor(Math.random() * (M - N + 1)) + N
}
const random = getRandom(1,10)
document.body.style.backgroundImage = `url(./images/desktop_${random}.jpg)`
</script>
  • 通过修改类名(className)一下子修改很多属性(会覆盖之前的类名)
1
2
3
4
5
6
7
<body>
<div class="nav"></div>
<script>
const div = document.querySelector('div')
div.className = 'box'
</script>
</body>
  • 通过classList追加和删除类名
1
2
3
元素.classList.add('类名')
元素.classList.remove('类名')
元素.classList.toggle('类名') /*切换类名*/

获取表单的值

1
2
表单.value = '用户名'
表单.type = 'password'

表单属性如disabled/checked/selected,添加就有效果,移除就没有效果,接受布尔值参数。true表示添加了该属性,false表示移除了该属性。默认值为false(可以理解为默认是不存在该属性时)

1
2
3
4
5
6
7
8
9
<button>111</button>

    <script>

        const button = document.querySelector('button')

        button.disabled = true /*禁用按钮。如果值设为false,则可用。*/

    </script>
1
2
const ipt = document.querySelector('input')
ipt.checked = true //默认勾选

自定义属性

设置自定义属性,data-

1
2
3
4
5
6
7
8
9
10
11
12
<body>
<div data-id="1">1</div>
<div data-id="2">2</div>
<div data-id="3">3</div>
<div data-id="4">4</div>
<div data-id="5">5</div>
<script>
const one = document.querySelector('div')
console.log(one.dataset) //得到所有自定义属性
console.log(one.dataset.id) //得到自定义属性“id”
</script>
</body>

定时器-间歇函数

1.开启定时器
  • 每隔多长时间调用一次这个函数(时间单位:毫秒)
  • 类似“循环”,不设置停止条件就会一直重复执行
  • 第一次执行前也会停顿设置的间隔时间
1
setInterval(函数,间隔时间)
1
2
3
4
5
6
7
8
9
<script>

        setInterval(function(){

            console.log('每秒执行一次')

        },1000)

    </script>
1
2
3
4
5
function fn(){
console.log('一秒执行一次')
}

setInterval(fn,1000)
1
2
3
4
5
6
7
8
9
10
<div id="counter">0</div>
<script>
let i = 0
setInterval(function(){
i++
document.getElementById('counter').innerText = i //数字随时间增大
}, 1000)
</script>
//修改原代码使数字逐渐增多,012345...而不是大数字取代小数字
document.getElementById('counter').innerText += i
2.关闭定时器
1
2
let 变量名 = setInterval(函数,间隔时间)
clearInterval(变量名)

事件监听

1
元素对象.addEventListener('事件类型',要执行的函数)

事件监听三要素:

  • 事件源:哪个dom元素被事件触发了,要获取dom元素
  • 事件类型:用什么方式触发,比如鼠标单击click、鼠标经过mouseover等
  • 事件调用的函数:要做什么事
    事件类型:
  • 鼠标:click mouseenter mouseleave
  • 焦点:focus blur
  • 键盘:keydown keyup
  • 文本:input

事件对象

1
2
3
元素.addEventListener('click',function(e){
...
})

常用属性

  • type获取当前事件类型
  • clientX/clientY获取光标相对于浏览器可见窗口左上角的位置
  • offsetX/offsetY获取光标相对于当前DOM元素左上角的位置
  • key用户按下的键盘键的值
1
2
3
4
5
6
7
8
9
10
11
const input = document.querySelector('input')
input.addEventListener('keyup',function(e){
if(e.key === 'Enter'){
if(tx.value.trim())
{
item.style.display = 'block'
text.innerHTML = tx.value
}
tx.value = ''
}
}) //按下Enter才显示评论,并清空输入评论

环境对象

指的是变量this,受当前环境影响,代表当前函数运行时所处的环境。普通函数里this指向window(直接调用函数)。函数的调用方式不同,this指代的对象就不同。谁调用了这个函数,this就指向谁

1
2
3
4
const btn = document.querySelector('button')
btn.addEventListener('click',function(){
this.style.color = 'red' //this就是button
})

回调函数

如果将函数A作为参数传递给函数B,称函数A为回调函数

事件流

  • 事件流指的是事件完整执行过程中的流动路径
  • 事件冒泡概念:当一个元素的事件被触发后,会依次向上调用所有父级的同名事件
  • 阻止冒泡(阻止传播,冒泡,捕获都有效)
1
事件对象.stopPropagation()
1
2
3
4
son.addEventListener('click',function(e){
alert('儿子')
e.stopPropagation()
})
  • 解绑事件

1.on事件方式,直接用null覆盖

1
2
3
4
btn.onclick = function(){
alert('...')
}
btn.onclick = null

2.addEventListener方式,用事件处理函数removeEventListener(addEventListener方式后面注册的事件不会覆盖前面注册的事件)

1
2
3
4
5
function fn() {
alert('点击了')
}
btn.addEventListener('click',fn)
btn.removeEventListener('click',fn)

匿名函数无法被解绑

事件委托

优点:减少注册次数,提高程序性能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<ul>
<li></li>
<li></li>
<li></li>
<p>不变色</p>
</ul>
<script>
const ul = document.querySelector('ul')
ul.addEventListener('click',function(e){
if(e.target.tagName === 'LI'){ //找到真正触发的元素
e.target.style.color = 'red'
}
})
</script>

阻止元素默认行为

1
e.preventDefault()

页面加载事件

即加载外部资源(图片、外联CSS、JS等)加载完毕时触发的事件

1
2
3
window.addEventListener('load',function(){
//执行的操作
})

把JS写在body最后,不用考虑加载问题,因为所有DOM元素都加载完了。如果把JS写在前面,可以通过页面加载事件先加载,再执行

等图片加载完毕再执行某段代码:

1
2
3
img.addEventListener('load',function(){
...
})
DOMContentLoaded事件

当初始HTML文档被加载和解析完成后即触发,无需等待样式表、图像等完全加载

1
2
3
document.addEventListener('DOMContentLoaded',function(){
...
})

元素滚动事件

滚动条在滚动时持续触发的事件(如固定导航栏、返回顶部)

1
2
3
window.addEventListener('scroll',function(){
...
})
  • scrollLeft,scrollTop属性获取被卷去的大小,获取元素往左、往上滚出去看不到的距离
    页面滚动大于300px显示电梯侧栏
1
2
3
4
5
const elevator = document.querySelector('.xtx-elevator')
window.addEventListener('scroll',function(){
const n = document.documentElement.scrollTop
elevator.style.opacity = n >= 300 ? 1 : 0
})

返回顶部

1
2
3
4
const backTop = document.querySelector('#backTop')
backTop.addEventListener('click',funtion(){
document.dacumentElement.scrollTop = 0
})
  • scrollTo方法可把内容滚动到指定的坐标
1
window.scrollTo(x,y)

页面尺寸事件

  • 会在窗口尺寸改变的时候触发的事件
1
2
3
window.addEventListener('resize',function(){
...
})
  • 检测屏幕宽度
1
2
3
4
window.addEventListener('resize',function(){
let w = document.documentElement.clientWidth
console.log(w)
})
  • 获取元素的可见部分宽高
    1.clientWidth和clientHeight(不包括边框、margin、滚动条等,包括padding)
    2.offsetWidth和offsetHeight(包括边框)
  • 获取元素位置
    offsetLeft和offsetTop以带有定位的父级为准。如果没有父级,以文档左上角为准

日期对象(时间对象)

实例化

在代码中发现了new关键字时,将这个操作称为实例化

  • 创建一个对象并获取当前时间
1
const date = new Date()
  • 指定时间
1
const date1 = new Date('2022-5-1 08:30:00')
日期对象方法

将日期对象返回的数据转化为实际开发中常见的格式

方法 作用 说明
getFullYear() 获得年份 获取四位年份
getMonth() 获得月份 取值0~11
getDate() 获取月份中的每一天 不同月份取值不同
getDay() 获取星期 取值0~6
getHours() 获取小时 取值0~23
getMinutes() 获取分钟 取值0~59
getSeconds() 获取秒 取值0~59
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const div = document.querySelector('div')
function getMyDate(){
let h = date.getHours()
let m = date.getMinutes()
let s = date.getSeconds()
h = h < 10 ? '0' + h : h
m = m < 10 ? '0' + m : m
s = s < 10 ? '0' + s : s
return `今天是:${date.getFullYear()}${date.getFullMonth() + 1}${date.getDate()}${h}:${m}:${date.getSeconds()}`
}

div.innerHTML = getMyDate() //回调函数隔一秒才会调用,去除空隙
setInterval(function(){
div.innerHTML = getMyDate()
},1000)

另一种方式

  • toLocaleString()
  • toLocaleDateString()
  • toLocaleTimeString()
1
2
3
4
5
const div = document.querySelector('div')
setInterval(function(){
const date = new Date
div.HTML = date.toLocaleString()
},1000)
时间戳

毫秒数,一种特殊的计量时间的方式。将来时间戳 - 现在时间戳 = 剩余时间
可以将剩余时间转化成倒计时
三种获取时间戳的方法

  • getTime() 需实例化
  • +new Date() 无需实例化
  • Date.now() 无需实例化。只能返回当前时间戳
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function getCountTime(){
const now = +new Date()
const last = +new Date('2022-4-1 18:30:00')
const count = (last - now) / 1000
let h = parseInt(count / 60 / 60 % 24)
h = h < 10 ? '0' + h : h
let m = parseInt(count / 60 % 60)
m = m < 10 ? '0' + m : m
let s = parseInt(count % 60)
s = s < 10 ? '0' + s : s

document.querySelector('#hour').innerHTML = h
document.querySelector('#minutes').innerHTML = m
document.querySelector('#seconds').innerHTML = s
}

getCountTime() //先调用一次
setInterval(getCountTime,1000)

节点操作

DOM节点

DOM树里的每一个内容都称为节点

  • 元素节点(重要):所有标签如body,div。html是根节点
  • 属性节点:所有属性
  • 文本节点:所有文本
查找节点

父节点:子元素.parentNode 返回最近一级的父节点
子节点:

  • 父元素.childNodes 获得所有子节点
  • 父元素.children 仅获得所有元素节点,返回一个伪数组
    兄弟节点:
  • nextElementSibling 下一个兄弟节点
  • previousElementSibling 上一个兄弟节点
增加节点

步骤:创建一个新的节点、把创建的新的节点放到指定的元素内部

1
2
const div = document.creatElement('div')
document.body.appendChild(div)

追加节点(作为最后一个子元素)

1
2
3
4
const ul = document.querySelector('ul')
const li = document.createElement('li')
li.innerHTML = '我是li'
ul.appendChild(li)

插入到某个子元素前面

1
父元素.insertBefore(要插入的元素,在哪个元素前面)

插入到第一个

1
ul.insertBefore(li,ul.children[0])
克隆节点
1
元素.cloneNode(布尔值)

若为true,包含后代节点一起克隆
若为false,不包含后代节点
轮播图

1
2
const ul = document.querySelector('ul')
ul.appendChild(ul.children[0].cloneNode(true))
删除节点

JS原生DOM操作中,删除元素必须通过父元素删除

1
父元素.removeChild(要删除的元素)

M端事件

触屏 touch 事件 说明
touchstart 手指触摸到一个 DOM 元素时触发
touchmove 手指在一个 DOM 元素上滑动时触发
touchend 手指从一个 DOM 元素上移开时触发
插件官网
https://www.swiper.com.cn/

Window对象

BOM是浏览器对象模型

  • 定时器-延时函数
1
setTimeout(回调函数,等待的毫秒数)

清除延时函数

1
2
let timer = setTimeout(回调函数,等待的毫秒数)
clearTimeout(timer)

定时广告

1
2
3
4
const img = document.querySelector('img')
setTimeout(function(){
img.style.display = 'none'
},3000)
  • JS的执行机制
    浏览器有两个引擎:渲染引擎、JS解析器
    JS语言是单线程的,同一个时间只做一件事
    为了解决阻塞问题,利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JS脚本创建多个线程,诞生了同步与异步
    同步:前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序一致、同步
    异步:做一件事的同时处理其他事情
    JS的异步通过回调函数实现
    JS执行机制:1.执行同步任务2.浏览器处理异步任务,将处理结果放入任务队列中3.同步任务执行完毕后任务队列中的异步任务被读取并结束等待状态,开始执行
  • location对象
    分析并保存了url地址的各个部分。可以得到当前文件url地址
1
console.log(location.href)

可以通过JS方式跳转到目标地址

1
location.href = 'https://www....'

search属性获取地址中携带的参数,符号?后面部分

1
console.log(location.search)

hash属性获取地址中哈希值,符号#后面部分

1
console.log(location.hash)

reload属性用来刷新页面

1
2
3
4
5
6
7
8
9
10
<button>点击刷新</button>

<script>
let btn = document.querySelector('button')

btn.addEventListener('click', function () {
// 强制刷新,效果类似于按下 Ctrl + F5
location.reload(true)
})
</script>
  • navigator对象
    记录浏览器自身的相关信息
    userAgent属性检测浏览器的版本及平台
  • histroy对象
    管理历史记录,与前进、后退、历史记录等操作相对应
history 对象方法 作用 代码示例
back() 可以后退功能 history.back()
forward() 前进功能 history.forward()
go(参数) 前进后退功能。参数如果是 1 前进1个页面,如果是 -1 后退1个页面 history.go(-1)

本地存储localStorage

sessionStorage的用法和localStorage基本相同,但是生命周期为关闭浏览器窗口
存储数据

1
localStorage.setItem(key,value)

获取数据

1
localStorage.getItem(key)

删除数据

1
localStorage.removeItem(key)

存储复杂数据类型,需要将复杂数据类型转换成JSON字符串,再存储到本地

1
2
3
4
5
6
7
8
9
<script>
const obj = {
uname:'1'
age:1
gender:'female'
}
localStorage.setItem('obj',JSON.stringify(obj)) //本地存储理论上只能存储字符串
console.log(JSON.parse(localStorage.getItem('obj'))) //把JSON字符串转换为对象
</script>

数组方法

  • map方法
    可以遍历数组处理数据,并且返回新的数组
1
2
3
4
5
6
7
8
const arr = ['red', 'blue', 'green']
const newArr = arr.map(function (ele, index) {
console.log(ele) // 数组元素
console.log(index) // 数组索引号
return ele + '颜色'
})

console.log(newArr) // ['red颜色', 'blue颜色', 'green颜色']
  • join方法
    把数组中的所有元素转换成一个字符串
1
2
3
const arr = ['red颜色', 'blue颜色', 'green颜色']
// 将数组元素拼接成字符串,中间不加分隔符
console.log(arr.join('')) // red颜色blue颜色green颜色

数组元素是通过参数里面指定的分隔符进行分隔的

正则表达式

正则表达式是用于匹配字符串中字符组合的模式
1.定义规则2.查找
定义正则表达式

1
const 变量名 = /表达式/

判断是否有符合规则的字符串。匹配为true,不匹配为false

1
regObj.test(被检测的字符串)

补充:.exec()类似,找到返回数组,否则为null

元字符

具有特殊含义的字符,提高了灵活性和匹配功能
相关在线资源
MDN 官方文档链接
JavaScript 正则表达式指南: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions
工具类链接
正则表达式测试工具 (OSCHINA): http://tool.oschina.net/regex
第一条链接可以帮助你深入学习 JavaScript 中正则表达式的语法和用法;第二条链接则是一个非常实用的在线测试环境,可以用来验证你编写的正则规则是否正确。

元字符的分类

边界符:表示位置,开头和结尾
边界符 说明
^ 表示匹配行首的文本(以谁开始)
$ 表示匹配行尾的文本(以谁结束)
^ $ 必须精确匹配,从头到尾都相同
量词:表示次数
量词 说明
***** 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复 n 次
{n,} 重复 n 次或更多次
{n,m} 重复 n 到 m 次
字符类:比如\d表示0~9

[] 表示只要包含规定字符串中任意一个字符就可以。只有一个字符!如果想要两个,再加上{2}
[] 里面加上 - 连字符表示一个范围[a-z],[0-9],[a-zA-Z]
用户名/^[a-zA-Z0-9-_]{6,16}$/
QQ 号验证正则 /^[1-9][0-9]{4,}$/
量词 {4,} 只作用于它左边紧挨着的 [0-9],表示这里的数字要出现 4 次或更多次
[] 里面加上^表示取反[^a-z]
.匹配除换行符之外的任何单个字符

  • 预定义指某些常见模式的简写方式
预定义类 说明 相当于
\d 匹配 0-9 之间的任一数字 [0-9]
\D 匹配所有 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]
日期格式:^\d{4}-\d{1,2}-\d{1,2}
  • 修饰符约束正则执行的某些细节行为,如是否区分大小写、是否支持多行匹配等
1
2
console.log(/a/i.test('A'))  //true
//i表示不区分大小写,g表示匹配所有满足正则表达式的结果

替换

1
字符串.replace(/正则表达式/i,'替换的文本')