JS的执行机制
console.log(1);
setTimeout(function(){
console.log(3);
},1000);
console.log(2);
//结果为 1,2,3
console.log(1);
setTimeout(function(){
console.log(3);
},0);
console.log(2);
//结果为 1,2,3
JS是单线程
JS语言的最大特点之一就是单线程,单线程的核心概念是指:同一个时间只能做一件事。原因是因为JS脚本语言的初衷所导致(JS是为了实现处理页面中的用户交互),以及操作DOM。
在DOM操作中已经充分展示了单线程特征:创建一个元素,创建成功之后才可以将它添加到某个节点中。
单线程:排队,所有的任务工作都需要进行先排队,前一个任务完成了之后才会执行下一个任务,如果前一个任务所需的事件很长,后一个任务就不得不一直等待。
单线程导致的问题是,如果一个JS执行的时间过长,这样就会导致页面的渲染不连贯。
同步任务和异步任务
单线程导致的问题就是延时任务之后的任务要等待,如果延时任务耗时比较长,后面的任务就会一直等待
解决这个问题的方案:利用计算机CPU的多核特征进行解决,HTML5提出Web Worker标准,允许JS创建出多个线程,但是创建出来的所有子线程全部受制于主线程,这样实现了同步和异步的任务
同步
前一个任务结束后在执行后一个任务,程序执行的顺序和任务的排列顺序是一致的。同步的做法例如:一边吃饭吃完饭才能睡觉
异步
在做一件事的时候,因为这个任务花费时间比较长,在做这件事的时候,还可以去做另一件事,比如一边吃饭一边听音乐
本质区别:这条流水线上的各个流程的执行顺序不同
JS中的所有任务分两种:同步任务和异步任务
同步任务指的是:主线程上的任务排队执行
异步任务指的是:不进入主线程,而是进入一个"任务队列"的任务,当主线程中的任务执行完,才会从任务队列中取出异步任务放入主线程执行
同步任务
将所有的任务在主线程中拍好队然后形成一个执行队列,一个一个执行处理
异步任务
JS中的异步任务是通过回调函数实现的
回调函数callback:当一个任务执行完成之后回过头来调用的这个函数
一般而言,异步任务有三种:
- 普通事件,click、resize事件等
- 资源加载,如load,error等
- 定时器,setTimeout,setInterval等
异步任务相关的回调函数添加到任务列表中(消息队列)
JS执行机制(事件循环)
- 先执行主线程(执行栈)中的同步任务
- 异步任务(回调函数)放入到任务队列中
- 一旦执行栈中的所有同步任务执行完毕,系统就会自动按照次序读取任务队列中的异步任务,通过这种方式被读取的异步任务结束等待过程,进入到执行栈中,开始执行
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1ywCo4hn-1612491305071)(D:/张洁/VSCODE/前端资料/JavaScript笔记/img/1.png)]
元素偏移量offset系列
offset概述
offset相关的属性可以动态的得到元素的位置(偏移)、大小等
- 获得元素距离带有定位的父元素的位置
- 获得元素自身的大小(高度和宽度)
- 注意:返回的数据都是不带单位的数字类型
offset系列属性
- offsetParent:返回作为该元素带有定位的父元素,如果父元素无定位返回的是body
- offsetTop:返回元素相对于带有定位的父元素的上方的偏移量
- offsetLeft:返回元素相对于带有定位的父元素的左方的偏移量
- offsetWidth:返回元素自身包括padding、边框、内容区域的宽度
- offsetHeight:返回元素自身包括padding、边框、内容区域的宽度
offset和style区别
offset:
-
可以得到任意样式表中的样式值
-
获得的数值没有单位
-
offsetWidth包含:padding+border+width
-
offsetWidth等属性是只读属性,无法设置数据
读取元素的位置大小等使用offset读取
style:
-
只能得到行内样式表的样式值
-
style.width获得的是带有单位的字符串
-
style.width获得不包含padding和border的值
-
style.width是可读可写属性,可以取值也可以设置值
给元素设置或更改值,使用style设置
案例:
-
获取鼠标在一个div中的位置
-
购物平台的放大镜效果
- 黄色的遮罩层跟随鼠标的进入之后移动
- 将鼠标的坐标结合遮罩层进行计算遮罩层的位置
- 获取鼠标在盒子内的坐标
- 使用鼠标移动事件并结合计算的遮罩层的位置控制遮罩层移动
- 控制遮罩层不能超出图片盒子的范围
- 将遮罩层区域的图片内容按照一定的比例显示到放大区盒子里面
元素可视区client系列
client概述
client是客户端。使用client系列的相关属性用来获取元素可视区的相关信息,通过client系列属性可以动态的获得该元素的边框大小、元素大小
- clientTop:获取元素的上边框的大小
- clientLeft:获取元素的左边框的大小
- clientWidth:返回自身的padding,内容区宽度,不含边框,返回数据不带单位
- clientHeight:返回自身的padding,内容区高度,不含边框,返回数据不带单位
元素滚动scroll系列
scroll概述
是控制页面滚动,使用scroll系列属性可以动态的获取该元素的大小,滚动距离等
scrollTop:返回被卷到上侧的距离
scrollLeft:返回被卷到左侧的距离
scrollWidth:返回自身的实际宽度,不含边框
scrollHeight:返回自身的实际高度,不含边框
页面被卷去的部分
如果浏览器的高或者宽不足以显示整个页面时,会自动出现滚动条,当滚动条向下滚动时,页面上部会被逐渐隐藏,隐藏的页面高度就是卷上去的部分,称为页面被卷去的头部,滚动条在滚动的时候会触发onscroll事件
案例
淘宝右侧侧边菜单
- 侧边菜单选择的是绝对定位
- 当页面滚动到一定位置,侧边菜单改成固定定位
- 页面继续滚动,会让返回顶部按钮出现
- 采用onscroll页面滚动事件进行判断,核心对象是document
- 滚动到某个位置的时候进行判断页面被卷走的头部值
- 页面被卷上去的头部:页面被卷走的头部使用pageYOffset
- 元素被卷上去的头部:元素的scrollTop求
- 大致逻辑:当页面被卷上去的头部大于第一个值侧边菜单变成固定定位,继续往上滚动当页面被卷上去的头部大于第二个值让侧边菜单里面的返回顶部出现,同样如果小于两个值到的话做出相应到的改变
scroll兼容性解决方案
页面被卷上去的属性有兼容性问题,pageYOffset属性在IE9之后才有的
function Scroll(){
this.left=(window.pageXOffset||document.body.scrollLeft||document.documentElement.scrollLeft||0);
this.top=(window.pageYOffset||document.body.scrollTop||document.documentElement.scrollTop||0);
}
三个系列总结
offsetWidth:返回自身的包括padding、border、内容宽度,返回数值不带单位
clientWidth:返回自身的包括padding、内容宽度,不包括边框
scrollWidth:返回自身实际的宽度,不包含边框,实际宽度包括被卷走的
三大系列注意点
- offset系列经常用于获得元素的位置
- client系列经常用于获取元素的大小
- scroll系列经常用于获取滚动距离
mouseenter和mouseover区别
- 当鼠标进入元素的时候会触发mouseenter事件
- 类似mouseover,mouseover鼠标经过元素自身就会触发,经过子盒子也会触发,而mouseenter只有当鼠标经过自身盒子时触发,也可以得到一个结果mouseenter不会导致冒泡