环境对象this
环境对象本质上是一个关键字 this
this所在的代码区域不同,代表的含义不同
全局作用域中的this
全局作用域中this代表window对象
局部作用域中的this
在局部作用域中(函数中)this代表window对象
原因是函数调用的时候简写了,函数完整写法window.函数()
事件局部作用域中的this
事件中的this指向事件源
<input type="button"><script>console.log(this)function fn() {console.log('函数中this')console.log(this)}fn()let btn = document.querySelector('input')btn.addEventListener('click', function () {console.log(this)})</script>
规律:哪个对象在调用这个方法,那么方法中的this就指向当前调用对象(谁调用就指向谁)
let obj = {name: '老段',eat: function () {console.log(this)}}obj.eat()
回调函数
回调函数:本质是一个函数:如果我们将一个函数作为参数,当前这个函数就叫回调函数
高阶函数:还是一个函数,如果一个函数的参数是函数,那么这个函数就是高阶函数
事件
事件流
事件流就是事件的一种现象
事件流:事件冒泡现象,事件捕获现象
事件冒泡现象
1.在嵌套结构中,如果子元素事件会向外(父元素)传递,这个现象就叫事件冒泡现象
在嵌套结构中子元素向父元素传递
2.解决:如果遇到事件冒泡,而且冒泡对我们的程序产生了影响,我们可以阻止冒泡
阻止事件冒泡的时候,一定要给子元素阻止,阻止事件冒泡的语法:事件对象参数.stopPropagation();
点击子元素:
<div class="one"><div class="two"></div></div><script>// 需求,点击两个盒子,分别输出一句话let one = document.querySelector('.one')let two = document.querySelector('.two')// 点击第一个盒子one.addEventListener('click', function () {console.log('我是父元素')})two.addEventListener('click', function () {console.log('我是子元素')})</script>
事件捕获
现象:和事件冒泡相反,在嵌套结构中,事件从父元素向子元素传递
注意:
1.事件程序中默认看不到事件捕获
2.如果要看到事件捕获,要求必需要用addEventListener注册事件,并且设置一个参数为true
事件捕获不用管,因为默认是事件冒泡
<div class="one"><div class="two"></div></div><script>// 需求,点击两个盒子,分别输出一句话let one = document.querySelector('.one')let two = document.querySelector('.two')// 点击第一个盒子one.addEventListener('click', function () {console.log('我是父元素')}, true);two.addEventListener('click', function () {console.log('我是子元素')}, true)</script>
点击子元素,先显示父元素
解绑事件
通过解绑事件,可以不执行事件中的代码
<input type="button" value="按钮"><div></div><script>let btn = document.querySelector('input')function fn() {console.log('123')}// 函数带括号则立刻执行btn.addEventListener('click', fn);// 解绑事件// a)如果注册事件通过addEventListener方式注册的,那么移除事件(解绑)通过// removeEventListener('事件类型',函数名)移除// 移除btnbtn.removeEventListener('click', fn)// b)如果元素注册事件的时候,通过on方式注册的,那么解绑事件的时候// 通过语法:DOM对象.on事件类型=null// 总结 console.log(btn);输出的结构是以html标签的形式输出的// console.dir(btn)输出的结构是以对象格式输出的</script>
事件委托(★)
在注册事件的时候可以减少代码量
<div><ul><li>1</li><li>2</li><li>3</li><li>4</li></ul></div><script>// 事件委托的实现步骤// 1.必须将事件给父元素注册(无所谓直接父元素还是间接父元素)// 2.必须找到真正的事件源(对应的标签对象),可以进行各种处理:事件对象参数.target// 要求:点击每一个li标签,输出li标签的内容// 不用事件委托实现// let lis = document.querySelectorAll('li')// for (let i = 0; i < lis.length; i++) {// lis[i].addEventListener('click', function () {// console.log(this.innerHTML)// })// }// 事件委托实现let div = document.querySelector('div')div.addEventListener('click', function (e) {// 获得真正的事件源let li = e.target// 获取事件源内容console.log(li.innerHTML)})</script>
其他事件
页面加载事件:load
当页面中所有资源都加载完成之后,自动触发load事件
写法:window.addEventListener(‘load’,function(){})
应用场景:如果将获取标签的代码写到html结构(body)的前面,则必须加load事件
为什么获取标签的代码写到html结构前面必须加load事件才可以?
a)js的执行顺序是按照从上到下执行的
b)如何获取标签的代码写到head中,页面中还没有标签对象,会报错
页面加载事件:DOMContentLoaded
作用:当我们整个HTML文档加载完成后就会执行DOMContentLoaded事件
当初始的HTML文档被加载完成和解析完成之后,DOMContentLoaded事件被触发,而无需等待样式表、图像等完全加载
语法:document.addEventListener(‘DOMContentLoaded’,function(){})
页面滚动事件:scroll
语法:window.addEventListener(‘scroll’,function(){})
应用场景:拖拽滚动条,页面出现固定定位的导航
获取滚动距离
<script>// 获取滚动距离// 对象.scrollLeft 获取水平方向的滚动距离// 对象.scrollTop 获取垂直方向的滚动距离// 备注:1.获取滚动距离需要在滚动事件中获取// 2.如果给window注册滚动事件并获取滚动距离,不能通过window.scrollTop获取// 3,如果给window注册滚动事件并获取滚动距离,通过document.documentElement.scrollTop获取//4.获取到的滚动距离由两部分组成:window.addEventListener('scroll', function () {let lg = document.documentElement.scrollTopconsole.log(lg)})</script>