文章目录
- 一、事件监听、事件类型、事件对象
- 二、事件流、阻止冒泡、事件委托
- 三、M端事件
- [四、windows对象 js组成](#四、windows对象 js组成)
- 五、本地存储(重点)
-
-
- 1.localStorage(重点)
- [2.sessionStorage 了解](#2.sessionStorage 了解)
- [3.localStorage 存储复杂数据类型](#3.localStorage 存储复杂数据类型)
- [4.数组map 方法](#4.数组map 方法)
- 5.数组join方法
- [6.change 事件](#6.change 事件)
- 7.判断是否有类
-
提示:以下是本篇文章正文内容,下面案例可供参考
一、事件监听、事件类型、事件对象
1.回调函数
**回调函数:**当一个函数当做参数
来传递给另外一个函数的时候,这个函数就是回调函数(回头调用
的函数)
html
<script>
// 1. 定时器间隔函数,里面第一个参数又是函数,这个匿名函数就是回调函数
setInterval(function () {
console.log('我是回调函数')
}, 1000)
// 2. addEventListener 函数的第二个参数也是函数,这个匿名函数也是回调函数
btn.addEventListener('click', function () {
console.log('我是回调函数')
})
</script>
2.焦点事件
主要是针对于表单是否获得光标的事件, 获得焦点 focus 、失去焦点 blur
自动获取焦点:比如百度搜索页自动获取焦点
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>焦点事件</title>
<style>
[type=text] {
width: 245px;
height: 50px;
padding-left: 20px;
border: 1px solid #ccc;
font-size: 17px;
outline: none;
}
</style>
</head>
<body>
<input type="text" class="search-text">
<input type="text" class="search">
<script>
// 1. 焦点事件(手动触发)
const search_text = document.querySelector('.search-text')
// 1.1 获得焦点 focus
search_text.addEventListener('focus', function () {
console.log('获得了焦点')
})
// 1.2 失去焦点 blur
search_text.addEventListener('blur', function () {
console.log('失去了焦点')
})
// 2. 拓展 自动获得焦点 focus() 自动失去焦点 blur()
// 2.1 语法: 元素.focus() 比如百度首页搜索框自动获得焦点
const search = document.querySelector('.search')
search.focus()
</script>
</body>
</html>
3.事件对象
- 也是个对象,这个对象里有事件触发时的相关信息,包含属性和方法
- 例如:鼠标点击事件中,事件对象就存了鼠标点在哪个位置等信息
html
<body>
<div class="box"></div>
<textarea id="tx" placeholder="发一条友善的评论" rows="2"></textarea>
<script>
// 事件对象
const box = document.querySelector('.box')
box.addEventListener('click', function (e) {
console.log(e)
})
const tx = document.querySelector('#tx')
tx.addEventListener('keyup', function (e) {
// e 就是事件对象
// console.log(e)
// console.log(e.key) // a
// 用户如果按下的是回车键,则弹出框提示按下了回车键
if (e.key === 'Enter') {
alert('您按下了回车键')
}
})
</script>
</body>
二、事件流、阻止冒泡、事件委托
1.为什么要学习事件流?
- 可以帮我们解决一些疑惑,比如点击子盒子会会弹出2次的问题
事件流指的是事件完整执行过程中的流动路径
当触发事件时,会经历两个阶段,分别是捕获阶段
、冒泡阶段
事件捕获概念:
当一个元素的事件被触发时,会从DOM的根元素开始依次调用同名事件 (从外到里)
html
<body>
<div class="father">
父盒子
<div class="son">子盒子</div>
</div>
<script>
// 事件流
const father = document.querySelector('.father')
const son = document.querySelector('.son')
// 1. 事件捕获
// // 点击父盒子
father.addEventListener('click', function () {
alert('我是爸爸')
}, true) // 事件捕获
// 点击子盒子
son.addEventListener('click', function () {
alert('我是儿子')
}, true) // 事件捕获
</script>
</body>
说明:
- addEventListener第三个参数传入 true 代表是捕获阶段触发(很少使用)
- 若传入false代表冒泡阶段触发,默认就是 false
2. 事件冒泡概念:
当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程被称为事件冒泡
- 简单理解:当一个元素触发事件后,会依次向上调用所有父级元素的
同名事件
- 事件冒泡是
默认
存在的,或者第三个参数传入false
都是冒泡 实际工作都是使用事件冒泡为主
3.阻止冒泡
**问题:**因为默认就有冒泡阶段的存在,所以容易导致事件影响到父级元素(祖先元素)
**需求:**若想把事件就限制在当前元素内,就需要阻止事件冒泡
前提:
阻止事件冒泡需要拿到事件对象
html
<body>
<div class="father">
父盒子
<div class="son">子盒子</div>
</div>
<script>
// 事件流
const father = document.querySelector('.father')
const son = document.querySelector('.son')
// 1. 事件冒泡
// 点击父盒子
father.addEventListener('click', function () {
alert('我是爸爸')
})
// 点击子盒子
son.addEventListener('click', function (e) {
alert('我是儿子')
// 1.1 先获取事件对象
// 1.2 事件对象.stopPropagation() 注意是个方法
e.stopPropagation()
})
</script>
</body>
结论:事件对象中的 ev.stopPropagation
方法,专门用来阻止事件冒泡(事件传播)
鼠标经过事件:
mouseover 和 mouseout 会有冒泡效果
mouseenter 和 mouseleave 没有冒泡效果 (推荐)
4.事件委托
事件委托(EventDelegation):是JavaScript中注册事件的常用技巧,也称为事件委派、事件代理
简单理解:原本需要注册在子元素的事件委托给父元素,让父元素担当事件监听的职务
为什么要用事件委托呢?
- 如果同时给多个元素注册事件,还需要利用循环多次注册事件
- 大量的事件监听是比较耗费性能的,
事件委托是利用事件流的特征解决一些开发需求的知识技巧
- 优点:减少注册次数,可以提高程序性能
- 原理:事件委托其实是利用事件冒泡的特点
- 给父元素注册事件,当我们触发子元素的时候,会冒泡到父元素身上,从而触发父元素的事件
利用事件委托方式如何得到当前点击的元素呢?
- 实现:事件对象.target. tagName 可以获得真正触发事件的元素
html
<body>
<ul>
<li>第1个孩子</li>
<li>第2个孩子</li>
<li>第3个孩子</li>
<li>第4个孩子</li>
<li>第5个孩子</li>
</ul>
<script>
// 需求: 点击每个小li都会有弹窗效果
// 1. 获取父元素ul
const ul = document.querySelector('ul')
// 2. 给ul注册点击事件
ul.addEventListener('click', function (e) {
// alert('我会弹窗')
// 3. 利用事件对象.target 得到目标元素
// console.log(e.target)
// e.target.style.color = 'pink'
// 需求2:点击哪个小li,对应的li变色
// console.dir(e.target.tagName) 可以得到目标元素的标签名
if (e.target.tagName === 'LI') {
e.target.style.color = 'pink'
}
})
</script>
5.阻止默认行为
阻止元素发生默认的行为
例如:
- 当点击提交按钮时阻止对表单的提交
- 阻止链接的跳转等等
html
事件对象.preventDefault()
6.页面加载事件
加载外部资源(如图片、外联CSS和JavaScript等)加载完毕时触发的事件
为什么要学?
- 有些时候需要等页面资源全部处理完了做一些事情
- 老代码喜欢把 script 写在 head 中,这时候直接找 dom 元素找不到
事件名:load
监听页面所有资源加载完毕:
html
window.addEventListener('load', function() {
// xxxxx
})
当初始的 HTML 文档被完全加载和解析完成之后就触发,而无需等待样式表、图像等完全加载
事件名:DOMContentLoaded
html
document.addEventListener('DOMContentLoaded', function() {
// xxxxx
})
7.元素滚动事件
滚动条在滚动的时候持续触发的事件
为什么要学?
- 很多网页需要检测用户把页面滚动到某个区域后做一些处理,比如固定导航栏,比如返回顶部
事件名:scroll
监听整个页面滚动:
html
window.addEventListener('scroll', function() {
// xxxxx
})
三、M端事件
M端(移动端)有自己独特的地方。比如触屏事件 touch
(也称触摸事件),Android 和 IOS都有。
touch 对象代表一个触摸点。触摸点可能是一根手指,也可能是一根触摸笔。触屏事件可响应用户手指(或触控笔)对屏幕或者触控板操作。
常见的触屏事件如下:
html
<body>
<div class="box"></div>
<script>
// 触摸事件
const box = document.querySelector('.box')
// 1. 手指触屏开始事件 touchstart
box.addEventListener('touchstart', function () {
console.log('我开始摸了')
})
// 2. 手指触屏滑动事件 touchmove
box.addEventListener('touchmove', function () {
console.log('我一直摸')
})
// 3. 手指触屏结束事件 touchend
box.addEventListener('touchend', function () {
console.log('我摸完了')
})
</script>
</body>
四、windows对象 js组成
1.JavaScript的组成
-
ECMAScript:
- 规定了js基础语法核心知识。
- 比如:变量、分支语句、循环语句、对象等等
-
Web APIs :
- DOM 文档对象模型, 定义了一套操作HTML文档的API
- BOM 浏览器对象模型,定义了一套操作浏览器窗口的API
2.window对象
BOM (Browser Object Model ) 是浏览器对象模型
- window对象是一个全局对象,也可以说是JavaScript中的顶级对象
- 像document、alert()、console.log()这些都是window的属性,基本BOM的属性和方法都是window的
- 所有通过var定义在全局作用域中的变量、函数都会变成window对象的属性和方法
- window对象下的属性和方法调用的时候可以省略window
3.定时器-延迟函数
JavaScript 内置的一个用来让代码延迟执行的函数,叫 setTimeout
语法:
html
setTimeout(回调函数, 延迟时间)
setTimeout 仅仅只执行一次,所以可以理解为就是把一段代码延迟执行, 平时省略window
间歇函数 setInterval : 每隔一段时间就执行一次, , 平时省略window
清除延时函数:
html
clearTimeout(timerId)
注意点
- 延时函数需要等待,所以后面的代码先执行
- 返回值是一个正整数,表示定时器的编号
4.location对象
location (地址) 它拆分并保存了 URL 地址的各个组成部分, 它是一个对象
5.navigator对象
navigator是对象,该对象下记录了浏览器自身的相关信息
6.histroy对象
history (历史)是对象,主要管理历史记录, 该对象与浏览器地址栏的操作相对应,如前进、后退等
html
<body>
<button class="back">←后退</button>
<button class="forward">前进→</button>
<script>
// histroy对象
// 1.前进
const forward = document.querySelector('.forward')
forward.addEventListener('click', function () {
// history.forward()
history.go(1)
})
// 2.后退
const back = document.querySelector('.back')
back.addEventListener('click', function () {
// history.back()
history.go(-1)
})
</script>
</body>
五、本地存储(重点)
本地存储:将数据存储在本地浏览器中
常见的使用场景:
https://todomvc.com/examples/vanilla-es6/ 页面刷新数据不丢失
好处:
1、页面刷新或者关闭不丢失数据,实现数据持久化
2、容量较大,sessionStorage和 localStorage 约 5M 左右
1.localStorage(重点)
作用: 数据可以长期保留在本地浏览器中,刷新页面和关闭页面,数据也不会丢失
**特性:**以键值对的形式存储,并且存储的是字符串, 省略了window
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>本地存储-localstorage</title>
</head>
<body>
<script>
// 本地存储 - localstorage 存储的是字符串
// 1. 存储
localStorage.setItem('age', 18)
// 2. 获取
console.log(typeof localStorage.getItem('age'))
// 3. 删除
localStorage.removeItem('age')
</script>
</body>
</html>
2.sessionStorage 了解
特性:
- 用法跟localStorage基本相同
- 区别是:当页面浏览器被关闭时,存储在 sessionStorage 的数据会被清除
存储:sessionStorage.setItem(key,value)
获取:sessionStorage.getItem(key)
删除:sessionStorage.removeItem(key)
3.localStorage 存储复杂数据类型
**问题:**本地只能存储字符串,无法存储复杂数据类型.
**解决:**需要将复杂数据类型转换成 JSON字符串,在存储到本地
**语法:**JSON.stringify(复杂数据类型)
JSON字符串:
- 首先是1个字符串
- 属性名使用双引号引起来,不能单引号
- 属性值如果是字符串型也必须双引号
html
<body>
<script>
// 本地存储复杂数据类型
const goods = {
name: '小米',
price: 1999
}
// localStorage.setItem('goods', goods)
// console.log(localStorage.getItem('goods'))
// 1. 把对象转换为JSON字符串 JSON.stringify
localStorage.setItem('goods', JSON.stringify(goods))
// console.log(typeof localStorage.getItem('goods'))
</script>
</body>
**问题:**因为本地存储里面取出来的是字符串,不是对象,无法直接使用
**解决: **把取出来的字符串转换为对象
**语法:**JSON.parse(JSON字符串)
html
<body>
<script>
// 本地存储复杂数据类型
const goods = {
name: '小米',
price: 1999
}
// localStorage.setItem('goods', goods)
// console.log(localStorage.getItem('goods'))
// 1. 把对象转换为JSON字符串 JSON.stringify
localStorage.setItem('goods', JSON.stringify(goods))
// console.log(typeof localStorage.getItem('goods'))
// 2. 把JSON字符串转换为对象 JSON.parse
console.log(JSON.parse(localStorage.getItem('goods')))
</script>
</body>
4.数组map 方法
使用场景:
map 可以遍历数组处理数据,并且返回新的数组
html
<body>
<script>
const arr = ['red', 'blue', 'pink']
// 1. 数组 map方法 处理数据并且 返回一个数组
const newArr = arr.map(function (ele, index) {
// console.log(ele) // 数组元素
// console.log(index) // 索引号
return ele + '颜色'
})
console.log(newArr)
</script>
</body>
5.数组join方法
**作用:**join() 方法用于把数组中的所有元素转换一个字符串
语法:
html
<body>
<script>
const arr = ['red', 'blue', 'pink']
// 1. 数组 map方法 处理数据并且 返回一个数组
const newArr = arr.map(function (ele, index) {
// console.log(ele) // 数组元素
// console.log(index) // 索引号
return ele + '颜色'
})
console.log(newArr)
// 2. 数组join方法 把数组转换为字符串
// 小括号为空则逗号分割
console.log(newArr.join()) // red颜色,blue颜色,pink颜色
// 小括号是空字符串,则元素之间没有分隔符
console.log(newArr.join('')) //red颜色blue颜色pink颜色
console.log(newArr.join('|')) //red颜色|blue颜色|pink颜色
</script>
</body>
6.change 事件
给input注册 change 事件,值被修改并且失去焦点后触发
7.判断是否有类
元素.classList.contains() 看看有没有包含某个类,如果有则返回true,么有则返回false