DOM获取元素
一、Web API 基本认知
1.1 变量声明
let const
建议const优先,有了变量先给const,后面要修改的话再改成let
用const声明变量时需要初始化
对于基本数据类型,用const修饰的变量值不能更改
对于引用数据类型,用const修饰的变量值可以更改,但地址值不能更改(即可以对引用数据类型进行增删改查操作)
建议数组和对象用const声明
1.2 作用和分类
作用:使用js操作html和浏览器
分类:DOM(文档对象模型)(操作网页内容)、BOM(浏览器对象模型)
1.3 DOM树
将HTML文档以树状结构直观的表示出来,体现标签之间的关系
1.4 DOM对象
html里面的标签在js里面叫对象
DOM核心思想:把网页内容当作对象处理
document对象:是DOM里提供的一个对象,它提供的属性和方法都是用来访问和操作网页内容的,网页所有内容都在document里面
二、获取DOM对象
2.1 通过CSS选择器来获取DOM元素
- 选择匹配的单个元素
语法:document.querySelector('css选择器')
参数:包括一个或多个有效的CSS选择器字符串
返回值:CSS选择器匹配的第一个元素,一个HTMLElement对象 - 选择匹配的多个元素
语法:document.querySelectorAll('css选择器')
参数:包括一个或多个有效的CSS选择器字符串
返回值:CSS选择器匹配的NodeList集合
得到的是一个伪数组:① 有长度有索引号的数组 ② 没有pop()、push()方法 ③ for遍历得到里面的每一个对象
【注意】:哪怕只有一个元素,用document.querySelectorAll('css选择器')
获取的也是伪数组
2.2 通过其他方式来获取DOM元素
三、操作元素内容
3.1 元素.innerTest属性
* 将文本内容添加/更新到任意标签位置
* 显示纯文本,**不解析标签**
eg:
const box = document.querySelector('div')
console.log(box.innerText)
3.2 元素.innerHTML属性
* 将文本内容添加/更新到任意标签位置
* 会解析标签,多标签建议使用模板字符
四、操作元素属性
4.1 操作元素常用属性
对象.属性
4.2 操作元素样式属性
通过js设置/修改标签元素的样式属性
-
通过style属性操作CSS
生成的是行内样式表,权重高
语法:对象.style.样式属性 = 值
【注意】- 修改样式通过style属性引出 eg:
div.style.width = '300px'
- 如果属性有连接符,需要转换为小驼峰命名法
- 赋值时用单引号括起来,需要的时候要加css单位
- 修改样式通过style属性引出 eg:
-
操作类名(className) 操作CSS
适合修改样式较多的情况
语法:// active是一个css类名 元素.className = 'active'
【注意】:
- 由于class是关键字,所以使用className代替
- className是用新值换旧值 ,如果需要添加一个类,需要保留之前的类名
-
通过classList操作类控制CSS(重要)
为了解决className容易覆盖以前的类名,可以通过classList方式追加和删除类名
语法:// 追加一个类 元素.classList.add('类名') // 删除一个类 元素.classList.remove('类名') // 切换一个类 元素.classList.toggle('类名') // 检测是否包含一个类 元素.classList.contains('类名')
4.3 操作表单元素属性
获取:DOM对象.属性名
设置:DOM对象.属性名 = 新值
eg:表单.type = 'password'
表单中要展添加就有效果,移除就没有效果时,一律用布尔值表示,为true表示添加了该属性,false代表移除该属性eg:disabled(禁用,默认false即不禁用)、checked、selected
eg:
<input type = "checkbox"></input>
const ipt = document.querySelector('input')
ipt.checked = true
4.4 自定义属性
- 标准属性:标签自带的属性,例如class id title等,可以直接用点语法操作
- 自定义属性:
- 在html5中推出的专门的data-自定义属性
- 在标签开头一律以data-开头
- 在DOM对象上一律以dataset对象方式获取
eg:
4.5 定时器-间歇函数
每隔一段时间自动执行一段代码,不需要手动触发,eg:倒计时
定时器函数可以开启和关闭定时器
- 开启定时器
setInterval(函数名,间隔时间)
【注意】:① 函数可以是匿名函数,也可以是具名函数,使用具名函数时,不要加括号,如果要加括号,必须用引号括起来,eg:'fn()'
② 间隔时间单位是毫秒 ③ 定时器返回的是id号,每个定时器的id都不一样 - 关闭定时器
语法:
let 变量名 = setInterval(函数, 间隔时间)
clearInterval(变量名)
eg:
// 获取定时器的id
let n = setInterval(fn, 1000)
// 关闭
clear Interval(n)
// 再次打开时
n = setInterval(fn, 1000)
DOM事件基础
一、事件监听(绑定)
- 事件:编程时系统内发生的动作,eg:单击按钮切换图片
- 语法:
元素对象.addEventListener('事件类型', 要执行的函数)
- 事件监听三要素:事件源(DOM元素)、事件类型、事件调用的函数
【注意】:① 事件类型要加引号 ② 函数不会立即执行,触发一次执行一次
二、事件类型
- 鼠标事件(鼠标触发)
- 点击:‘click’
- 鼠标经过:‘mouseenter’/‘mouseover’
- 鼠标离开:‘mouseleave’/‘mouseout’
【补充】:
‘mouseover’(鼠标经过)和’mouseout’(鼠标离开)有冒泡效果
‘mouseenter’(鼠标经过)和’mouseleave’(鼠标离开)无冒泡效果
- 焦点事件(表单获得光标)
- 获得焦点:‘focus’
- 失去焦点:‘blur’
- 键盘事件(键盘触发)
- 键盘按下触发:‘Keydown’
- 键盘抬起触发:‘Keyup’
- 文本事件(表单输入触发)
- 用户输入事件:‘input’
- 内容发生了变化:‘change’
三、事件对象
事件对象存储了事件触发时的相关信息,eg:判断用户按下哪个键可以进行相应的操作
在事件绑定的回调函数的第一个参数就是事件对象,一般命名为event、ev、e
- 获取事件对象
使用:事件对象.属性
eg:
部分常用属性:// e就是事件对象 btn.addEventListener('click', function (e) { })
- type:获取当前的事件类型
- clientX/clientY:获取光标相对于浏览器可见窗口左上角的位置
- offsetX/offsetY:获取光标相对于当前DOM元素左上角的位置
- key:用户按下的键盘的值
- target:点击的对象
补充: trim方法:去除内容两侧的空格变量名.trim()
四、环境对象
环境对象指的是函数内部特殊的变量this,它代表当前函数运行时所处的环境
作用:弄清楚this的指向,可以让代码更简洁
【注意】:
- 函数的调用方式不同,this指代的对象也不同
- 判断this指向的粗略规则:谁调用,this就是谁
- 普通函数里面,this指向的是window
五、回调函数
当函数A作为参数传给函数B时,就称A为回调函数
DOM事件进阶
一、事件流
1.1 事件流和两个阶段说明
事件流指事件完整执行过程中的流动路径
触发事件时经历两个阶段:
第一阶段:捕获阶段(从父到子)
第二阶段:冒泡阶段(从子到父)
1.2 事件捕获(了解)
从DOM的根元素开始去执行对应的事件(从外到里)
事件捕获需要对应代码才能看到效果
代码:DOM.addEventListener(事件类型,事件处理函数,是否使用捕获机制)
说明:第三个参数如果是true代表是捕获阶段触发(很少使用),若传入false代表是冒泡阶段触发,默认就是false
1.3 事件冒泡
- 当一个元素的事件被触发时,会依次向上调用所有父级元素的同名事件
- 事件冒泡是默认存在的
- 第三个参数是false(也可以不写第三个参数)
1.4 阻止冒泡
需求:把事件限制在当前元素内
前提:阻止冒泡需要拿到事件对象
语法: 事件对象.stopPropagation()
阻止默认行为:事件对象.preventDefault()
1.5 解绑事件(了解)
用addEventListener方法注册事件时,必须使用:
removeEventListener(事件类型,事件处理函数,[获取捕获或者冒泡阶段])
([]内的参数可写可不写)
eg:
function () {
alert('点击了')
}
// 绑定事件
btn.addEventListener('click',fn)
// 解绑事件
btn.removeEventListener('click',fn)
【注意】:匿名函数无法解绑
二、事件委托
事件委托是利用时间流的特征解决一些开发需求的知识技巧
优点:减少注册次数,提高程序性能
原理:事件委托是利用了事件冒泡的特点(事件写到父级上)
实现:事件对象.target.tagName
可以获得真正触发事件的元素
三、其他事件
3.1 页面加载事件
加载外部资源(如图片、外联CSS和JavaScript等)加载完毕时触发的事件
- 有时候需要等页面资源全部处理完毕再进行一些操作
事件名:load
eg:监听页面所有资源加载完毕:
【注意】:不光可以监听整个页面资源加载完毕,也可以针对某个资源绑定load事件// 页面加载事件 window.addEventListener('load', function () { // 执行的操作 })
- 当初始的HTML文档加载和解析完后,无需等待演示表、图像等完全加载
事件名:DOMContentLoaded
eg:监听页面DOM加载完毕:给document添加DOMContentLoaded事件
3.2 元素滚动事件
- 滚动条再滚动时持续出发的事件
事件名:scroll
eg:监听整个页面滚动:
// 页面滚动事件
window.addEventListener('scroll', function () {
// 执行的操作
})
【注意】:也可以监听某个元素的内部滚动
2. 页面滚动事件————获取位置
scrollLeft和scrollTop(属性)
- 获取被卷去的大小
- 获取元素内容往左、往上滚出去看不到的距离
- 这两个值时可读写的(可以赋值)
- 如果想知道页面滚动了多少像素:document.documentElement.scrollTop
scrollTo(x,y)也可以控制页面滚动
3.3 页面尺寸事件
-
会在窗口尺寸改变的时候出发事件
事件名:resize
eg:window.addEventListener('resize', function () { // 执行的操作 })
-
获取宽高
clientWidth和clientHeight
获取元素可见部分的宽高(不包含边框border、margin、滚动条,包含padding和内容)eg:检测屏幕宽度
window.addEventListener('resize', function () { // w即为页面宽度 let w = document.documentElement.clientWidth })
四、元素的尺寸和位置
通过js的方式获得元素再页面中的位置
- 获取宽高
- offsetWidth和offsetHeight
- 获取元素自身的宽高(包含元素自身设置的宽高、border、padding)
- 获取出来的是数值,方便计算
- 如果盒子是隐藏的,获取的结果是0
- 获取位置
- 获取元素距离自己定位父级元素的左、上距离
- offsetLeft和offsetTop是只读属性
- element.getBoundingClientRect(),该方法返回元素的大小及其相对于视口的位置
【总结】:
综合案例补充:
对页面添加丝滑滚动效果
html { scroll-behavior: smooth; }
DOM节点操作
一、日期对象
1.1 实例化
在代码中发现了new关键字,一般将这个操作成为实例化
创建一个时间对象并获取时间:
获取当前时间:const data = new Date()
获取指定时间:const data = new Date('2024-7-17 08:30:00')
1.2 日期对象方法
【注意】:月份和星期取值都是从0开始的(0表示星期天)
快速获取时间方法:
date.toLocaleString()
使用效果:2024/7/17 15:21:26date.toDateString()
使用效果:Wed Jul 17 2024date.toLocaleDateString()
使用效果:2024/7/17
1.3 时间戳
- 使用场景:如果计算倒计时效果,前面的方法无法直接计算,需要借助时间戳完成
- 时间戳:是指1970年01月01日00时00分00秒到现在的毫秒数,是一种特殊的时间计量方式
- 算法:
- 将来的时间戳 - 现在的时间戳 = 剩余时间毫秒数
- 剩余时间毫秒数转换为剩余时间的‘年月日时分秒’就是倒计时时间
eg:将来的时间戳 2000ms - 现在的时间戳 1000ms = 1000ms,1000ms转换为倒计时就是 0小时0分1秒
- 获取时间戳的方法:
date.getTime()
方法- 简写
+new Date()
无需实例化
eg:console.log(+new Date())
- 使用
Date.now()
无需实例化,但这种方法只能获得当前的时间戳,前面两种方法可以返回指定时间的时间戳,即这种方法不能用于时间戳
二、节点操作
2.1 DOM节点:DOM树每一个内容都称之为节点
- 节点类型:
- 元素节点:所有的标签,html是根节点
- 属性节点:所有的属性,eg:href
- 文本节点:所有的文本
- 其他
- 节点关系:针对的找亲戚返回的都是对象
- 父节点
- 子节点
- 兄弟节点
2.2 查找节点
- 父节点查找
parentNode属性,返回最近一级的父节点, 找不到则返回none
语法:子元素.parentNode
- 子节点查找
- childNodes属性
获得所有子节点,包括文本节点(空格、换行)、注释节点 - children属性
仅获得所有元素节点(仅是最近一级的子节点),返回的是一个伪数组
语法:父元素.children
- childNodes属性
- 兄弟关系查找
- 下一个兄弟
nextElementSibling属性
- 上一个兄弟
previousElementSibling属性
- 下一个兄弟
2.3 增加节点(重要)
- 创建节点
即创造出一个新的网页元素,再添加到网页内,一般先创建节点,然后插入节点
创建元素节点方法:document.createElement('标签名')
eg:const div = document.createElement('标签名')
- 追加节点
要想在界面看到,还要插入到某个父元素中
- 插入到父元素的最后一个子元素:
父元素.appendChild(要插入的元素)
- 插入到父元素某个子元素的前面
父元素.insertBefore(要插入的元素,在哪个元素前面)
eg:插到最前面ul.insertBefore(li,ul.children[0])
- 克隆节点
特殊情况下,需要新增一个原有的节点
语法:元素.cloneNode(布尔值)
cloneNode会克隆出一个跟原标签一样的元素,括号内传入布尔值,若为true则代表克隆时会包含后代节点一起克隆,否则,不包含后代节点,默认为false
2.4 删除节点
删除元素必须通过父元素删除
语法:父元素.removeChild(要删除元素)
【注意】:① 如不存在父子关系则删除不成功 ② 删除节点和隐藏节点(display:none)有区别:隐藏节点还是存在的,但删除是从html中删除节点
三、M端事件
触屏事件 touch
touch对象代表一个触摸点触摸带你可以是一根手指,也可以是一根触屏笔
常见触屏事件: