事件对象:包含了和这次事件相关的一系列信息
比如:鼠标点击事件中,事件对象就存了鼠标点在哪个位置等信息
使用场景
可以判断用户按下哪个键,比如按下回车键可以发布新闻
可以判断鼠标点击了哪个元素,从而做相应的操作
在事件绑定的回调函数的第一个参数就是事件对象
一般命名为event,ev,e
type:获取当前的事件类型
clientX/clientY(右为正,下为正,左上角为0,0)
获取光标相对于浏览器可视窗口左上角的位置
offsetX/offsetY
获取光标相对于当前DOM元素左上角的位置
key
用户按下的键盘键的值
现在不提倡使用keyCode
//右为正,下为正,左上角为0,0
div.addEventListener('click', function (event) {
console.log(event.clientX)
console.log(event.offsetX)
console.log(event.key)//按得键是哪个
})
// 对于普通函数而言,函数体内部的this,就代表了这个函数的调用者
function fn() {
// arguments 是可以直接在函数内部使用的,包含了所有的实参
// this 也是可以直接在函数内部使用的,它所代表的意思,这个fn函数是由谁调用的
console.log(this)
}
// window是一个浏览器的顶级对象
fn()
window.document.querySelector()
window.setTimeout()
window.setInterval()
// 在js代码中,函数的使用非常的灵活:
// 1.函数可以作为参数
// 2.将函数作为返回值传递
// 在js代码中,函数的使用非常的灵活:
// 1.函数可以作为参数
// 2.将函数作为返回值传递
function fn1(cb) {
cb()
console.log('fn1被调用了')
}
fn1(function () {
console.log('实参作为函数被调用了...')
})
setInterval(function () { }, 1000)
setTimeout(function () { }, 1000)
btn.addEventListener('click', function () { })
let arr = [1, 2, 3]
arr.map(function () { })
arr.forEach(function () { })
arr.filter(function () { })
arr.some(function () { })
arr.every(function () { })
小技巧: 我们想使用is代码去模拟一个事件的产生元素对象.事件类型()
<input type="text">
<button>aniu</button>
<script>
const btn = document.querySelector('button')
const input = document.querySelector('input')
btn.addEventListener('click', function () {
// input.focus()
})
</script>
事件流:时间是会流动的
方向:默认是从子元素流向父元素的 冒号false
即 冒泡
修改流动方向: 父元素---->子元素 捕获true
// 改变方向 利用addEventListener(参数1,参数2,参数3) 第3个参数
// true: 捕获
// false: 冒泡
// 只有一个方向 默认冒泡
// 元素对象.on事件类型 = function(){} 这种绑定方式,只能是冒泡
// 事件委托: 委托父元素处理子元素中的事件
<div id="div1">
<div id="div2">
<div id="div3"></div>
</div>
</div>
<script>
// 点击div3, 到底是点击了谁? div3在div2的范围, 所以是不是也可以认为点中了div2, div2又在div1的范围, 是不是可以认为点中了div1?
document.querySelector('#div1').addEventListener('click', function () {
console.log('111')
}true / false)
// 事件流:事件是会流动的
// 方向:默认是从子元素流向父元素的 冒号 false
//即 冒泡
// 修改流动方向: 父元素---->子元素 捕获true
// 改变方向 利用addEventListener(参数1,参数2,参数3) 第3个参数
// true: 捕获
// false: 冒泡
// 只有一个方向 默认冒泡
// 元素对象.on事件类型 = function(){} 这种绑定方式,只能是冒泡
// 事件委托: 委托父元素处理子元素中的事件
</script>
// 事件委托: 委托父元素处理子元素中的事件
// 事件委托,由于委托给了父元素,就造成范围被扩大了,我们在事件处理函数中,需要对元素进行筛选
const ul = document.querySelector('ul')
ul.addEventListener('click', function (e) {
// 对产生事件的元素进行筛选
// e.target//这次真正产生事件的那个元素
if (e.target.tagName === 'LI') {
//对li进行操作
}
})
子元素监听事件 父元素也监听了事件
时候我们很讨厌事件冒泡,所以我们需要在某个地方,阻止事件冒泡是事件冒泡有时候可以帮助我们做一些事情:事件委托
1.需要绑定的元素特别多的时候
2.给动态创建的元素绑定事件的时候
mouseover
mouseout
元素.addEventListener(‘scroll’,函数) I页面的滚动事件监听: window.addEventlistener(‘scroll’,函数)document.addEventListener(‘scroll’,雨数)
页面加载的事件: 页面的所有元素加载完成,会执行的事件处理函数
// 给window增加load的事件
// Ioad的事件,什么时候才会执行: 页面加载完成
// 页面加载完成:1.页面的元素结构加载完成 2.这个页面需要的外部资源加载完成
DOMContentLoaded:界面的基本结构加载完成,和外部资源没有关系
//DOMContentLoaded:
document.addEventListener('DOMContentLoaded', function(){
console .log('DOMContentLoaded...')
const div = document.querySelector( 'div')
console.log(div)
})
// 给window增加load的事件
window.addEventListener("load", function () {
console.log("load...")
const div = document.querySelector('div')
console.log(div)
})
1.具备固定的宽度或者高度
2.内容会超过这个元素的宽度或者高度
3.要给这个元素设置overflow:auto/scroll
window.addEventListener('load'function(){
const div = document.querySelector('div')
// 稍微滚动div一点点,就会触发很多次scro11事件
div.addEventListener('scrol1', function(){
console.log('scroll...')
})
})
div.addEventListener('scroll', function(){
// 这个元素滚出去了多少距离
console.log(div.scrollTop)
})
页面的滚动:不断在页面中放置元素,让元素在一屏下展示不下
window.addEventListener('scroll', function(){
console.log(document.documentElement.scrollTop)
})
滚动的单词: scroll
1.监听滚动事件xxx.addEventListener(‘scroll’,function(){})
元素: 元素对象
页面: window/document
2.滚出去的距离
xxx.scrollTop元素: 元素对象
页面:document.documentElement
3.设置元素滚出去的距离
xxx.scrollTop = 值
元素: 元素对象
页面: document.documentElement
XXX.scrollTo(x,y)
元素:元素对象
页面:window document.documentElement
window中的resize事件
对整个窗口进行大小尺寸变化的监听
window.addEventListener(‘resize’,函数)
scroll系列 scrollWidth/scrollHeight (可读不可写) 元素内容的宽度和高度
包含了padding 不包含border 包含超出内容的那一部分 不包含滚动条的区域
offset系列 offsetWidth/offsetHeight (可读不可写) 元素的宽度和高度
包含了padding 包含border 不包含需要滚动的那一部分 不包含滚动条的区域
client系列 clientWidth/clientHeight (可读不可写) 元素的宽度和高度
包含了padding 不包含border 不包含需要滚动的那一部分 不包含滚动条的区域
scroll系列 scrollLeft/scrollTop (可读可写) 这个元素滚出的距离
offset系列offsetLeft/offsetTop (可读不可写) 距离带定位父元素左侧和顶部的距离
client系列 clientLeft/clientTop (可读不可写) 元素左边框和上边框的宽度
元素.scrollTop=值
元素.scrollTo(x,y)
设置行内样式 left
设置行内样式 margin-left
设置行内样式 transform: translate(x px, y px)
const fn=function(){}
绑定事件:元素对象.addEventListener(‘click’,fn)
元素对象.on事件类型 = function(){}
解绑事件:元素对象.removeEventListener(‘click’,你绑定事件时的那个函数)
解绑事件:元素对象.removeEventListener(‘click’,fn)
函数在解绑时,不能使用匿名函数function(){}
元素.addEventListener(‘click’,fn)
元素.removeEventListener(‘click’, fn)
补充:
元素对象.on事件类型 = function(){}
解绑事件:元素对象.on事件类型=null
① document.querySelector(选择器)
ID选择器 类选择器 后代选择器 属性选择器 nth选择器
② document.querySelectorAll(选择器)[下标]
③ document.body–body元素
④ document.documentElement----html元素
⑤时间对象e.target—产生事件的元素–事件委托时进行元素筛选–if(e.target.tagName===‘LI’){}
⑥事件处理函数中的this—绑定事件的元素—事件处理函数的this,表示绑定事件的那个元素
e.target/this在事件委托的时候,这两个表示的不一样
⑦利用元素与元素之间的关系
父元素 元素对象.parentNode
子元素们 元素对象.children
哥哥元素 元素对象.previousElenmentSibiling
弟弟元素 元素对象.nextElementSibiling
⑧利用节点与节点之间的关系来获取元素
元素 父元素 元素对象.parentNode
子元素 元素对象.children 伪数组
兄弟元素 上边的兄弟 previousElementsibling
下边的兄弟 nextElementsibiling
⑨document.createElement(‘标签名’) 创建的是新元素,在界面看不到,需要的放到界面才能看得到
⑩ 元素对象.cloneNode(true) 创建的是新元素,在界面看不到,需要的放到界面才能看得到
2.1 操作元素的内容
获取 元素对象.innerHTML
修改 元素对象.innerHTML=值
2.2 操作元素的常规属性
id
href
value
type
src
checked
disabled
…
获取 元素对象.属性
设置 元素对象.属性=值
2.3 操作元素样式属性
①style属性(行内样式) 元素对象.style.样式属性
②class属性 classList add()
remove()
toggle() 切换 (有则去掉.没有则加)
contains()
2.4 操作元素自定义属性
元素对象.dataset.xxx
xxx是date-后面所写的东西
2.5 绑定元素的事件
元素对象.addEventListener(事件类型,函数)
事件类型 click
鼠标移入移除 mouseenter/mouseleave不会冒泡,所以不能事件委托
鼠标移入移除 mouseover/mouseout不会冒泡,所以不能事件委托
键盘按下/抬起 keydown/keyup
焦点事件 focus/blur
输入事件 input
页面加载完成事件 load------window
DOMContentLoaded—document
滚动事件 scroll
元素滚动 元素对象.addEventListener(‘scroll’,函数)
页面滚动 window.addEventListener(‘scroll’,函数)
窗口变化大小事件 resize-----window
表单提交事件 submit 阻止表单提交的默认行为
重置form表单 form表单元素.reset()
移动端触摸相关事件 touchstart
touchmove
touchend
…
2.6 解绑元素的事件
元素对象.removeEventListener( 事件类型,绑定时的那个函数fn() )
2.7 模拟事件
轮播图模拟点击实现自动轮播
3.1 时间会流动
子—>父 冒泡 阻止冒泡 e.stopPropagation()
事件委托 ①需要绑定事件的元素很多
②需要给动态创建的元素绑定事件(未来元素)
DOM树里面每一个内容的都成为节点
其他方式获取元素
利用节点与节点之间的关系来获取元素
元素 父元素 元素对象.parentNode
子元素 元素对象.children 伪数组
兄弟元素 上边的兄弟 previousElementsibling
下边的兄弟 nextElementsibiling
整个页面的根节点(.parentNode) document
方式1 innerHTML其实也可以帮助我们创建出新的标签
方式2 document.createElement()
方式3 已经存在的元素对象.cloneNode()
//创建出新的li标签对象
const newLi=document.createElement('li')
newLi.innerHTML=inout.value//给刚创建出来的li添加内容
ul.appendChild(newLi)//这行代码才能让刚创建出来的元素显示在页面中
//appendChild是把一个元素放到指定目标内部中(ul)最末尾处
<body>
<ul>
<li>我是老大</li>
</ul>
<button id="btn1">按钮1</button>
<button id="btn2">按钮2</button>
<script>
// 点击按钮1, 给ul末尾增加新的li子元素,li的内容是: 我是尾部li元素
// 点击按钮2, 给ul头部增加新的li子元素,li的内容是: 我是头部li元素
const btn1 = document.querySelector('#btn1')
const btn2 = document.querySelector('#btn2')
const ul = document.querySelector('ul')
btn1.addEventListener('click', function () {
const newli = document.createElement('li')
newli.innerHTML = "我是尾部li元素"
ul.appendChild(newli)
})
btn2.addEventListener('click', function () {
// ul.innerHTML = "我是头部li元素 " + ul.innerHTML
const newli = document.createElement('li')
newli.innerHTML = '我是头部li元素'
ul.insertBefore(newli, ul.children[0])
})
</script>
//以li为模板,克隆一份新的li标签
const newli=li1.cloneNode()//默认是浅拷贝
const newli=li1.cloneNode(true)//深拷贝 不写默认是false 浅拷贝
无论是浅拷贝还是深拷贝,都是创建新的元素
真正的把元素在整个页面中移除掉
①div.remove()
②父元素.removeChild(子元素)
div.parentNode.removeChild(div)
mobile
触屏事件touch(触摸事件) Android和IOS都有
touch对象代表一个触摸点 触摸可能是一根手指,也可以是一根触摸笔
常见的触屏事件:
touchstart 手指触摸到一个DOM元素时触发
touchmove 手指在一个DOM元素上滑动时触发
touchend 手指从一个DOM元素上移开时触发
clientX 坐标 页面滚动 距离屏幕的距离
pageX 坐标 页面滚动 距离页面的距离
screenX距离整个屏幕的坐标
插件
插件:就是别人写好的·些代码,我们只需要复制对应的代码,就可以直接实现对应的效果
学习插件的基本过程
熟悉宜网,了解这个插件可以完成什么需求
https://www.swiper. com. cn/
看在线演示,找到符合自己需求的
demohttps://www.swiper.com, cn/demo/index.html
查看基本使用流程https://www.swiper.com.cn/usage/index.html
查看APi文档,去配置自己的插件https://www.swiper.com.cn/api/index.html
注意:多个swiper同时使用的时候,类名需要注意区分
html字符串
布局部分的字符串-> 把每一个元素生成工个DOM对象,再把每一个DOM对象之间的关系连接起来,形成了DOM树
css部分的字符串–>把所有的css样式都生成对应的样式规则对象
js部分的字符串
// 元素对象.innerHTML =字符串
// 元素对象.appendChild(新的元素对象)
// 到底谁的效率会更高一些
解析(Parsor) HIML,生成DU树(DOM Tree)
同时解析(Parser) CSS,生成样式规则 (Style Rules)
根据DOM树和样式规则,生成海集树(Render Tree)
进行布局 Layout(回流/重排):根据生成的渲染树,得到节点的几何信息(位置,大小)
进行绘制 Painting(重绘): 根据计算和获取的信息进行整个页面的绘制
Display: 展示在页面上
当 Render Tree 中部分或者全部元素的尺寸、结构、布局等发生改变时,浏览器就会重新渲染部分或全部文档的过程称为 回流。
由于节点(元素)的样式的改变并不影响它在文档流中的位置和文档布局时(比如: color、background-color、outline等),称为重绘。
回流一定重绘
页面的首次刷新
浏览器的窗口大小发生改变元素的大小或位置发生改变
改变字体的大小
内容的变化(如: input框的输入,图片的大小)
激活css伪类 (如: :hover)
脚本操作DOM(添加或者删除可见的DOM元素)
简单理解影响到布局了,就会有回流
window对象是一个全局对象,也可以说是JavaScript中的顶级对象
像document、alert()、console,log()这些都是window的属性,基本BOM的属性都是window的。
所有通过var定义在全局作用域中的变量、函数都会变成window对象的属性和方法
window对象下的属性和方法调用的时候可以省略window
js代码是单线程
进程:程序所需要执行的内存空间
线程:真正干活的那个人
单线程 :只有一个人来完成js中的所有事情
一个人做事情,就一定会有先后顺序,同一时间,只能够做一件事情
1.同步的事情
2.异步的事情定时器事件处理函数
定时器
事件处理函数
js对于同步和异步的代码,有不同的处理策略
同步的代码:立马执行
异步的代码:直接略过
只有当同步的代码全部都执行完之后,才会回过头来看看,那些异步的代码,有没有达到执行的时机
给常量赋值
如果我们在存储复杂数据类型的时候,不想让数据丢失
我们把obj变成字符串之后,把变成字符串之后的数据存储在localStorage中
//把复杂数据类型变成字符串
JSON.stringify(obj) //将obj这个对象,转变成了json的字符串,这个json字符串将会保留对象中的所有信息
//将字符串转换为复杂数据类型
JSON.parse(字符串)
把arr进行持久化操作
什么时候存? 数据变的时候存
什么时候去? 数据初始化的时候取
let timp='zhangsan'
const arr=timp.split('')
//结果:['z','h','a','n','g','s','a','n']
let str1='zhangsan-lisi-wangwu'
const arr=str1.split('-')
//结果:['zhangsan','lisi','wangwu']
let str1='name:zhangsan'
console.log(str1.split(':')[1])
//结果:zhangsan
let str3='name=zhangsan&age=18&height=178'
const arr=str3.split('&')
const obj={}
//结果:['name=zhangsan','age=18','height=178']
for(let i=0;i<arr.length;i++){
const key=arr[i].split('=')[0]
const value=arr[i].split('=')[1]
obj[key]=value
}
//结果:{name=zhangsan,age=18,height=178}
字符串.includes('小字符串')//得到大字符串中是否包含了小字符串(true,false)
字符串.startWith('小字符串')//得到大字符串是否是以小字符串开头
字符串.endWith('小字符串')//得到大字符串是否是以小字符串结尾
字符串.toUpperCase()//转变为大写
字符串.toLowerCase()//转变为小写
就是用一堆乱七八糟的符号,去表示某些范围
使用字面量 /正则表达式的符号/
let str = 'hello'
let reg = /^he/ //以he开头
let reg = /lo$/ //以lo结尾
let reg = /^he$/ //必须以he当做全部,字符串内容只能是he
let str = 'hello'
let reg = /^hel{2}o/ //l重复俩次
let reg = /^hel{2,5}o/ //l重复2-5次
跟在最后一个斜杠后面
//把字符串中的所有激情都替换成**
let reg=/激情/g
const replace = str.replaceAll(reg, '**')
console.log(replace)
正则表达式对象.test(字符串)
let str = 'hello'
let reg = /he/ //定义了一个正则表达式的对象
const ret = reg.test(str) //用正则表达式去测试字符串
//结果:true
test(被检测的字符串) //用来查看正则表达式与指定的字符串是否匹配
// 节流阀:标记位
// 按钮的点击: 无论点击的有多快 3s内就执行一次事件处理函数中的代码
// 定义一个节流阀 :定义一个布尔类型的值 let flag=true
// if(flag) {
// flag=false
// setTimeout(function() {
// flag=true
// },3000)
// }
let flag=true
if(flag) {
flag=false
setTimeout(function() {
flag=true
},3000)
}
// blur: 仅仅只是失去了光标
// 验证: 失去光标,并且内容变化了
document.querySelector(‘input’).addEventListener(’ change’, function(){
console.log(‘验证…’)
})
// input框的事件: focus blur input change
// blur: 仅仅只是失去了光标
// 验证: 失去光标,并且内容变化了
document.querySelector('input').addEventListener(' change', function(){
console.log('验证...')
})