提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
目录
文章目录
1.事件链(冒泡目标捕获)
(1)事件链原理
(2)阻止冒泡和默认事件
2.事件代理(面试笔试题重点)
3.页面的渲染流程(高频面试题)
3.1 浏览器加载一份html文档是怎么加载的?
3.2重绘、回流/回档
4.style的操作
(1)行内样式
(2)获取最终绘制样式
5.防抖与节流(重点)
6.预加载与懒加载
1.事件链(冒泡目标捕获)
(1)事件链原理
(1)事件的三个阶段: 先捕获,后目标,再冒泡,只能有一个阶段触发程序执行,比如捕获阶段触发了到了冒泡阶段就不再触发
(2)事件经过所有元素都没有被处理,这个事件消失
(3)事件传递的过程 只跟文档树的结构有关系 跟界面显示的层叠效果没有任何关系
事件冒泡:结构上(非视觉上)嵌套关系的元素,会存在事件冒泡的功能,即同一事件,自子元素冒泡向父元素。(自底向上)
事件捕获:结构上(非视觉上)嵌套关系的元素,会存在事件捕获的功能,即同一事件,自父元素捕获至子元素(事件源元素)。(自顶向下)
2.默认在冒泡的时候执行事件:onclick/attach和 addEventListener传false的时候
3.addEventListener绑定事件,如果把第三个参数设置为true,则在捕捉的时候执行事件
3.整个事件处理过程,会有个event事件对象在整个事件过程传播(W3C标准,ie8及其以下没有)
4.ie8以下不支持addEventListener
5.focus,blur,change,submit,reset,select等事件不冒泡
(1)事件的三个阶段: 先捕获,后目标,再冒泡,只能有一个阶段触发程序执行,比如捕获阶段触发了到了冒泡阶段就不再触发
(2)事件经过所有元素都没有被处理,这个事件消失
(3)事件传递的过程 只跟文档树的结构有关系 跟界面显示的层叠效果没有任何关系
事件冒泡:结构上(非视觉上)嵌套关系的元素,会存在事件冒泡的功能,即同一事件,自子元素冒泡向父元素。(自底向上)
事件捕获:结构上(非视觉上)嵌套关系的元素,会存在事件捕获的功能,即同一事件,自父元素捕获至子元素(事件源元素)。(自顶向下)
2.默认在冒泡的时候执行事件:onclick/attach和 addEventListener传false的时候
3.addEventListener绑定事件,如果把第三个参数设置为true,则在捕捉的时候执行事件
3.整个事件处理过程,会有个event事件对象在整个事件过程传播(W3C标准,ie8及其以下没有)
4.ie8以下不支持addEventListener
5.focus,blur,change,submit,reset,select等事件不冒泡
addEventListener第三个参数 true捕获阶段触发 false冒泡阶段触发
(2)阻止冒泡和默认事件
1、阻止事件冒泡: W3C标准 event.stopPropagation();但不支持 ie9以下版本
stopImmediatePropagation() 支持stopPropagation的浏览器中也可以用 stopImmediatePropagation()方法,这个不仅会阻止事件向祖元素的冒泡,也会阻止同一个节点上同一事件的其他的事件处理程序(优先级比它低的,同元素同事件多处理程序时)
event.cancelBubble=true; ie8及ie8以下可用
2、阻止默认事件: 默认事件——表单提交,a标签跳转,右键菜单等等
return false; 以对象属性的方式注册的事件才生效,用addEventListener/attachEvent这种是不生效的
event.preventDefault(); W3C标准,IE9以下不兼容
event.returnValue=false;兼容IE
案例如下:
2.事件代理(面试笔试题重点)
(1)事件代理: 网页设计中一种设计思想 利用事件对象中引用的目标对象这个技术来实现的
(2)无论事件触发时 是不是目标对象的监听器 在监听器内部的事件对象event中都可以访问这个事件的目标对象,利用这个特点去绑定事件给父级元素 来代理子级元素的业务,这种设计就是事件代理
事件代理设计有两个缺点:
1.静态的事件绑定:如果动态的添加元素进去 添加进去的元素没有这个事件
2.性能消耗更高 业务却相同
hello1
hello2
hello3
hello4
var box2s=document.querySelectorAll(".box2")
box2s.forEach(el=>{
el.addEventListener("click",function(e){
console.log(this.innerHTML)
})
})
//案例事件代理的缺点的举例:
function load1(){
// var box1=document.querySelector(".box1")
// box1.innerHTML+='hello5'
var box1=document.querySelector(".box1")
var box2=document.createElement("div")
box2.innerHTML="hello5"
box2.className="box2"
box1.appendChild(box2)
}
1、阻止事件冒泡: W3C标准 event.stopPropagation();但不支持 ie9以下版本
stopImmediatePropagation() 支持stopPropagation的浏览器中也可以用 stopImmediatePropagation()方法,这个不仅会阻止事件向祖元素的冒泡,也会阻止同一个节点上同一事件的其他的事件处理程序(优先级比它低的,同元素同事件多处理程序时)
event.cancelBubble=true; ie8及ie8以下可用
2、阻止默认事件: 默认事件——表单提交,a标签跳转,右键菜单等等
return false; 以对象属性的方式注册的事件才生效,用addEventListener/attachEvent这种是不生效的
event.preventDefault(); W3C标准,IE9以下不兼容
event.returnValue=false;兼容IE
案例如下:
(1)事件代理: 网页设计中一种设计思想 利用事件对象中引用的目标对象这个技术来实现的
(2)无论事件触发时 是不是目标对象的监听器 在监听器内部的事件对象event中都可以访问这个事件的目标对象,利用这个特点去绑定事件给父级元素 来代理子级元素的业务,这种设计就是事件代理
事件代理设计有两个缺点:
1.静态的事件绑定:如果动态的添加元素进去 添加进去的元素没有这个事件
2.性能消耗更高 业务却相同
hello1 hello2 hello3 hello4 var box2s=document.querySelectorAll(".box2") box2s.forEach(el=>{ el.addEventListener("click",function(e){ console.log(this.innerHTML) }) }) //案例事件代理的缺点的举例: function load1(){ // var box1=document.querySelector(".box1") // box1.innerHTML+='hello5' var box1=document.querySelector(".box1") var box2=document.createElement("div") box2.innerHTML="hello5" box2.className="box2" box1.appendChild(box2) }
3.页面的渲染流程(高频面试题)
1.页面呈现过程 不同的浏览器略微会有些不同。但基本上都是类似的
①.浏览器把html代码解析成1个Dom树,html中的每个tag都是Dom树中的1个节点,根节点就是我们常用的document对象。dom树就是html结构,里面包含了所有的html tag,包括用JS添加的元素。
②浏览器把所有样式(主要包括css和浏览器自带的样式设置)解析成样式结构体,在解析的过程中会去掉浏览器不能识别的样式。
③dom tree和样式结构体结合后构建呈现树(render tree),render tree有点类似于dom tree,但有区别,render tree能识别样式,render tree中每个node都有自己的style,而且render tree不包含隐藏的节点(比如display:none的节点,还有head节点),因为这些节点不会用于呈现,而且不会影响呈现的,所以就不会包含到render tree中。但是visibility:hidden隐藏的元素还是会包含到render tree中的,因为visibility:hidden 会影响布局,会占有位置。
④一旦render tree构建完毕后,浏览器就根据render tree来绘制页面。
用户在浏览器地址栏输入url(网址)后,到页面渲染出来,背后发生了什么?
==>请求网址对应的资源,得到资源,然后运行文档(简单的过程,不是标准答案)
答案:前端=>网络=>后端=>网络=>前端 这4步都得分析
3.1 浏览器加载一份html文档是怎么加载的?
浏览器加载一份html文档是怎么加载的?
==> (1)把标签、文本、注释、属性等等解析为节点树(DOM Tree)
(2)解析DOM tree中的节点时遇到了不太的元素会有不同的操作:
(2.1) style标签或者link-css,遇到css代码就会把css解析为css样式结构体
(2.2) 遇到了src会去加载(网络请求)资源
(3)把(2.1)css样式结构体和(1)DOM Tree结合变成呈现树/渲染树(Render tree)
(4)按照Render tree绘制页面
呈现树有的文档树中一定有,呈现树中没有的文档树中可能也有
3.2重绘、回流/回档
自己理解:
重绘就是按照文档树的结构,重新绘制页面渲染
回流/回档:页面的元素排版布局数量和节点在树中的位置等发生了改变,就是回流/回档
回流必然引起重绘,但是重绘不一定引起回流
案例例如:
hello
1231243254
function change1 () {
var box=document.querySelector(".box")
// box.innerHTML="6666" //回档
// box.style.visibility= "hidden"; //重绘不回流
// box.style.display= "none"; //回流
}
2.回流与重绘
① 当render tree中因为元素的数量,尺寸,布局,隐藏等改变而需要重新构建。这就称为回流或者回档(其实我觉得叫重新布局更简单明了些)。每个页面至少需要一次回流,就是在页面第一次加载的时候。
②当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color。则就叫称为重绘。
③(面试,选择题,问答题就答上面)从上面可以看出,回流必将引起重绘,而重绘不一定会引起回流。
3.常见的回流和重绘操作 任何对render tree中元素的操作都会引起回流或者重绘
①添加、删除元素(回流+重绘)
② 隐藏元素,display:none(回流+重绘),visibility:hidden(只重绘,不回流)
③ 移动元素,比如改变top,left(jquery的animate方法就是,改变top,left不一定会影响回流),或者移动元素到另外1个父元素中。(重绘+回流)
④ 对style的操作(对不同的属性操作,影响不一样)
⑤ 还有一种是用户的操作,比如改变浏览器大小,改变浏览器的字体大小等(回流+重绘)
④重绘与回流操作的注意点 //重绘与回流操作的次数越多,计算机的性能消耗越大 进行dom操作的时候,就要考虑
案例例如:
我们的程序执行时 常常会操作页面 常常引起重绘/回流
频繁的重绘/回流会造成页面性能不好==>页面卡顿 迟缓 手机发烫
因此操作页面时: 尽量避免高频重绘 使用框架(MVVM)
尽量避免高频重绘案例:
添加1万个格子到页面上 每个格子显示时间(ms)
let tb=document.querySelector(".box")
for(let i=0;i<100;i++){
let tr=document.createElement("tr")
tb.appendChild(tr)
for(let j=0;j<100;j++){
let dt=new Date().getTime()
let td=document.createElement("td")
td.innerHTML=dt
tr.appendChild(td)
}
}
回档了1万零100次
1658297335582-1658297335446 136ms
创建一个"冰"元素来承载即将渲染的元素
dom=>fragment
wx=>block
vue=>template
react=>>
let tb=document.querySelector("#box")
let fra1=document.createDocumentFragment()//它在内存中还不在文档中
for(let i=0;i<100;i++){
let tr=document.createElement("tr")
fra1.appendChild(tr)
for(let j=0;j<100;j++){
let dt=new Date().getTime()
let td=document.createElement("td")
td.innerHTML=dt
tr.appendChild(td)
}
}
tb.appendChild(fra1)//它自己不会添加到文档树中用于渲染 但是它的子代元素都会添加进去
回档了1次
1658297870113-1658297869968 145ms
4.style的操作
1.获取script脚本节点后面加载的元素节点 是获取不了的
因为文档的加载是按照文档树的顺序加载的
解决方案一:当页面加载完成的事件触发 再去执行获取节点的方式
解决方案二:script-- defer async 修饰src如何加载外部js资源的异步属性
程序案例如下:
(1)行内样式
el.style.xx
设置/获取 ,只能操作行内样式
没有兼容问题,通吃
只能设置为字符串
样式必须用驼峰命名法
遇到与保留字一样的样式,前面应加“css”(eg:float——>el.style.cssFloat)
==>其实是获取的文档树中的元素的属性值
(2)获取最终绘制样式
let styleobj=window.getComputedStyle(ele);
styleobj对象是一个最终绘制的样式结果对象 有with height等270多个样式值
只能获取样式,要设置使用el.style.xx
拓展:window.getComputedStyle(ele,"after")
//第二个参数解决的是获取伪元素样式
ele.currentStyle
计算样式,只读
IE独有的属性
==>其实是获取的呈现树中的元素的属性值
5.防抖与节流(重点)
防抖:触发高频事件后 n 秒内函数只会执行一次,如果 n 秒内高频事件再次被触
发,则重新计算时间。
思路:每次触发事件时都取消之前的延时调用方法。
function debounce (fn, delay,...rest) {
let timeout = null;
return function (e) {
// e:事件对象
if (timeout) { clearTimeout(timeout) };//把前面那个
timeout
清除
timeout = setTimeout(()=>{
console.log(e, rest);
console.log(this);
fn.apply(this, [e, ...rest]);// 绑定 this
指向
}, delay);
}
}
function sayHi(e, ...rest) {
console.log(e, rest);
console.log(this.value);
}
var inp = document.getElementById('inp');
inp.addEventListener('input', debounce(sayHi, 300, 100, 200));
节流:高频事件触发,但在 n 秒内只执行一次,所以节流会稀释函数的执行频率。
思路:每次触发事件时都判断当前是否有等待执行的延时函数。
function throttle(fn) {
let canRun = true; // 通过闭包保存一个标记
return function () {
if (! canRun) return; // 在函数开头判断标记是否为
true
,不为
true
则
return
canRun = false; // 立即设置为
false
setTimeout(() => { // 将外部传入的函数的执行放在
setTimeout
中
fn. apply (this, arguments);
// 最后在 setTimeout
执行完毕后再把标记设置为
true(
关键
)
表示可以执行下一次循环了。当定时器没有执行的时候标记永远是 false
,在开头被
return
掉
canRun = true;
}, 500);
};
}
function sayHi(e) {
console.log (e. target. innerWidth, e. target. innerHeight);
}
window. addEventListener ('resize', throttle(sayHi));
6.预加载与懒加载
预加载: 提前加载资源--同源加载的优化
懒加载: 先不加载 等条件成立时再加载
1.页面呈现过程 不同的浏览器略微会有些不同。但基本上都是类似的
①.浏览器把html代码解析成1个Dom树,html中的每个tag都是Dom树中的1个节点,根节点就是我们常用的document对象。dom树就是html结构,里面包含了所有的html tag,包括用JS添加的元素。
②浏览器把所有样式(主要包括css和浏览器自带的样式设置)解析成样式结构体,在解析的过程中会去掉浏览器不能识别的样式。
③dom tree和样式结构体结合后构建呈现树(render tree),render tree有点类似于dom tree,但有区别,render tree能识别样式,render tree中每个node都有自己的style,而且render tree不包含隐藏的节点(比如display:none的节点,还有head节点),因为这些节点不会用于呈现,而且不会影响呈现的,所以就不会包含到render tree中。但是visibility:hidden隐藏的元素还是会包含到render tree中的,因为visibility:hidden 会影响布局,会占有位置。
④一旦render tree构建完毕后,浏览器就根据render tree来绘制页面。
用户在浏览器地址栏输入url(网址)后,到页面渲染出来,背后发生了什么?
==>请求网址对应的资源,得到资源,然后运行文档(简单的过程,不是标准答案)
答案:前端=>网络=>后端=>网络=>前端 这4步都得分析
浏览器加载一份html文档是怎么加载的?
==> (1)把标签、文本、注释、属性等等解析为节点树(DOM Tree)
(2)解析DOM tree中的节点时遇到了不太的元素会有不同的操作:
(2.1) style标签或者link-css,遇到css代码就会把css解析为css样式结构体
(2.2) 遇到了src会去加载(网络请求)资源
(3)把(2.1)css样式结构体和(1)DOM Tree结合变成呈现树/渲染树(Render tree)
(4)按照Render tree绘制页面
呈现树有的文档树中一定有,呈现树中没有的文档树中可能也有
3.2重绘、回流/回档
自己理解:
重绘就是按照文档树的结构,重新绘制页面渲染
回流/回档:页面的元素排版布局数量和节点在树中的位置等发生了改变,就是回流/回档
回流必然引起重绘,但是重绘不一定引起回流
案例例如:
hello
1231243254
function change1 () {
var box=document.querySelector(".box")
// box.innerHTML="6666" //回档
// box.style.visibility= "hidden"; //重绘不回流
// box.style.display= "none"; //回流
}
2.回流与重绘
① 当render tree中因为元素的数量,尺寸,布局,隐藏等改变而需要重新构建。这就称为回流或者回档(其实我觉得叫重新布局更简单明了些)。每个页面至少需要一次回流,就是在页面第一次加载的时候。
②当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color。则就叫称为重绘。
③(面试,选择题,问答题就答上面)从上面可以看出,回流必将引起重绘,而重绘不一定会引起回流。
3.常见的回流和重绘操作 任何对render tree中元素的操作都会引起回流或者重绘
①添加、删除元素(回流+重绘)
② 隐藏元素,display:none(回流+重绘),visibility:hidden(只重绘,不回流)
③ 移动元素,比如改变top,left(jquery的animate方法就是,改变top,left不一定会影响回流),或者移动元素到另外1个父元素中。(重绘+回流)
④ 对style的操作(对不同的属性操作,影响不一样)
⑤ 还有一种是用户的操作,比如改变浏览器大小,改变浏览器的字体大小等(回流+重绘)
④重绘与回流操作的注意点 //重绘与回流操作的次数越多,计算机的性能消耗越大 进行dom操作的时候,就要考虑
案例例如:
我们的程序执行时 常常会操作页面 常常引起重绘/回流
频繁的重绘/回流会造成页面性能不好==>页面卡顿 迟缓 手机发烫
因此操作页面时: 尽量避免高频重绘 使用框架(MVVM)
尽量避免高频重绘案例:
添加1万个格子到页面上 每个格子显示时间(ms)
let tb=document.querySelector(".box")
for(let i=0;i<100;i++){
let tr=document.createElement("tr")
tb.appendChild(tr)
for(let j=0;j<100;j++){
let dt=new Date().getTime()
let td=document.createElement("td")
td.innerHTML=dt
tr.appendChild(td)
}
}
回档了1万零100次
1658297335582-1658297335446 136ms
创建一个"冰"元素来承载即将渲染的元素
dom=>fragment
wx=>block
vue=>template
react=>>
let tb=document.querySelector("#box")
let fra1=document.createDocumentFragment()//它在内存中还不在文档中
for(let i=0;i<100;i++){
let tr=document.createElement("tr")
fra1.appendChild(tr)
for(let j=0;j<100;j++){
let dt=new Date().getTime()
let td=document.createElement("td")
td.innerHTML=dt
tr.appendChild(td)
}
}
tb.appendChild(fra1)//它自己不会添加到文档树中用于渲染 但是它的子代元素都会添加进去
回档了1次
1658297870113-1658297869968 145ms
4.style的操作
1.获取script脚本节点后面加载的元素节点 是获取不了的
因为文档的加载是按照文档树的顺序加载的
解决方案一:当页面加载完成的事件触发 再去执行获取节点的方式
解决方案二:script-- defer async 修饰src如何加载外部js资源的异步属性
程序案例如下:
(1)行内样式
el.style.xx
设置/获取 ,只能操作行内样式
没有兼容问题,通吃
只能设置为字符串
样式必须用驼峰命名法
遇到与保留字一样的样式,前面应加“css”(eg:float——>el.style.cssFloat)
==>其实是获取的文档树中的元素的属性值
(2)获取最终绘制样式
let styleobj=window.getComputedStyle(ele);
styleobj对象是一个最终绘制的样式结果对象 有with height等270多个样式值
只能获取样式,要设置使用el.style.xx
拓展:window.getComputedStyle(ele,"after")
//第二个参数解决的是获取伪元素样式
ele.currentStyle
计算样式,只读
IE独有的属性
==>其实是获取的呈现树中的元素的属性值
5.防抖与节流(重点)
防抖:触发高频事件后 n 秒内函数只会执行一次,如果 n 秒内高频事件再次被触
发,则重新计算时间。
思路:每次触发事件时都取消之前的延时调用方法。
function debounce (fn, delay,...rest) {
let timeout = null;
return function (e) {
// e:事件对象
if (timeout) { clearTimeout(timeout) };//把前面那个
timeout
清除
timeout = setTimeout(()=>{
console.log(e, rest);
console.log(this);
fn.apply(this, [e, ...rest]);// 绑定 this
指向
}, delay);
}
}
function sayHi(e, ...rest) {
console.log(e, rest);
console.log(this.value);
}
var inp = document.getElementById('inp');
inp.addEventListener('input', debounce(sayHi, 300, 100, 200));
节流:高频事件触发,但在 n 秒内只执行一次,所以节流会稀释函数的执行频率。
思路:每次触发事件时都判断当前是否有等待执行的延时函数。
function throttle(fn) {
let canRun = true; // 通过闭包保存一个标记
return function () {
if (! canRun) return; // 在函数开头判断标记是否为
true
,不为
true
则
return
canRun = false; // 立即设置为
false
setTimeout(() => { // 将外部传入的函数的执行放在
setTimeout
中
fn. apply (this, arguments);
// 最后在 setTimeout
执行完毕后再把标记设置为
true(
关键
)
表示可以执行下一次循环了。当定时器没有执行的时候标记永远是 false
,在开头被
return
掉
canRun = true;
}, 500);
};
}
function sayHi(e) {
console.log (e. target. innerWidth, e. target. innerHeight);
}
window. addEventListener ('resize', throttle(sayHi));
6.预加载与懒加载
预加载: 提前加载资源--同源加载的优化
懒加载: 先不加载 等条件成立时再加载
自己理解:
重绘就是按照文档树的结构,重新绘制页面渲染
回流/回档:页面的元素排版布局数量和节点在树中的位置等发生了改变,就是回流/回档
回流必然引起重绘,但是重绘不一定引起回流
案例例如:
hello
1231243254
function change1 () {
var box=document.querySelector(".box")
// box.innerHTML="6666" //回档
// box.style.visibility= "hidden"; //重绘不回流
// box.style.display= "none"; //回流
}
2.回流与重绘
① 当render tree中因为元素的数量,尺寸,布局,隐藏等改变而需要重新构建。这就称为回流或者回档(其实我觉得叫重新布局更简单明了些)。每个页面至少需要一次回流,就是在页面第一次加载的时候。
②当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color。则就叫称为重绘。
③(面试,选择题,问答题就答上面)从上面可以看出,回流必将引起重绘,而重绘不一定会引起回流。
3.常见的回流和重绘操作 任何对render tree中元素的操作都会引起回流或者重绘
①添加、删除元素(回流+重绘)
② 隐藏元素,display:none(回流+重绘),visibility:hidden(只重绘,不回流)
③ 移动元素,比如改变top,left(jquery的animate方法就是,改变top,left不一定会影响回流),或者移动元素到另外1个父元素中。(重绘+回流)
④ 对style的操作(对不同的属性操作,影响不一样)
⑤ 还有一种是用户的操作,比如改变浏览器大小,改变浏览器的字体大小等(回流+重绘)
④重绘与回流操作的注意点 //重绘与回流操作的次数越多,计算机的性能消耗越大 进行dom操作的时候,就要考虑
案例例如:
创建一个"冰"元素来承载即将渲染的元素
dom=>fragment
wx=>block
vue=>template
react=>>
let tb=document.querySelector("#box")
let fra1=document.createDocumentFragment()//它在内存中还不在文档中
for(let i=0;i<100;i++){
let tr=document.createElement("tr")
fra1.appendChild(tr)
for(let j=0;j<100;j++){
let dt=new Date().getTime()
let td=document.createElement("td")
td.innerHTML=dt
tr.appendChild(td)
}
}
tb.appendChild(fra1)//它自己不会添加到文档树中用于渲染 但是它的子代元素都会添加进去
回档了1次
1658297870113-1658297869968 145ms
1.获取script脚本节点后面加载的元素节点 是获取不了的
因为文档的加载是按照文档树的顺序加载的
解决方案一:当页面加载完成的事件触发 再去执行获取节点的方式
解决方案二:script-- defer async 修饰src如何加载外部js资源的异步属性
程序案例如下:
(1)行内样式
el.style.xx
设置/获取 ,只能操作行内样式
没有兼容问题,通吃
只能设置为字符串
样式必须用驼峰命名法
遇到与保留字一样的样式,前面应加“css”(eg:float——>el.style.cssFloat)
==>其实是获取的文档树中的元素的属性值
(2)获取最终绘制样式
let styleobj=window.getComputedStyle(ele);
styleobj对象是一个最终绘制的样式结果对象 有with height等270多个样式值
只能获取样式,要设置使用el.style.xx
拓展:window.getComputedStyle(ele,"after")
//第二个参数解决的是获取伪元素样式
ele.currentStyle
计算样式,只读
IE独有的属性
==>其实是获取的呈现树中的元素的属性值
5.防抖与节流(重点)
防抖:触发高频事件后 n 秒内函数只会执行一次,如果 n 秒内高频事件再次被触
发,则重新计算时间。
思路:每次触发事件时都取消之前的延时调用方法。
function debounce (fn, delay,...rest) {
let timeout = null;
return function (e) {
// e:事件对象
if (timeout) { clearTimeout(timeout) };//把前面那个
timeout
清除
timeout = setTimeout(()=>{
console.log(e, rest);
console.log(this);
fn.apply(this, [e, ...rest]);// 绑定 this
指向
}, delay);
}
}
function sayHi(e, ...rest) {
console.log(e, rest);
console.log(this.value);
}
var inp = document.getElementById('inp');
inp.addEventListener('input', debounce(sayHi, 300, 100, 200));
节流:高频事件触发,但在 n 秒内只执行一次,所以节流会稀释函数的执行频率。
思路:每次触发事件时都判断当前是否有等待执行的延时函数。
function throttle(fn) {
let canRun = true; // 通过闭包保存一个标记
return function () {
if (! canRun) return; // 在函数开头判断标记是否为
true
,不为
true
则
return
canRun = false; // 立即设置为
false
setTimeout(() => { // 将外部传入的函数的执行放在
setTimeout
中
fn. apply (this, arguments);
// 最后在 setTimeout
执行完毕后再把标记设置为
true(
关键
)
表示可以执行下一次循环了。当定时器没有执行的时候标记永远是 false
,在开头被
return
掉
canRun = true;
}, 500);
};
}
function sayHi(e) {
console.log (e. target. innerWidth, e. target. innerHeight);
}
window. addEventListener ('resize', throttle(sayHi));
6.预加载与懒加载
预加载: 提前加载资源--同源加载的优化
懒加载: 先不加载 等条件成立时再加载
el.style.xx
设置/获取 ,只能操作行内样式
没有兼容问题,通吃
只能设置为字符串
样式必须用驼峰命名法
遇到与保留字一样的样式,前面应加“css”(eg:float——>el.style.cssFloat)
==>其实是获取的文档树中的元素的属性值
let styleobj=window.getComputedStyle(ele);
styleobj对象是一个最终绘制的样式结果对象 有with height等270多个样式值
只能获取样式,要设置使用el.style.xx
拓展:window.getComputedStyle(ele,"after")
//第二个参数解决的是获取伪元素样式ele.currentStyle
计算样式,只读
IE独有的属性==>其实是获取的呈现树中的元素的属性值
5.防抖与节流(重点)
防抖:触发高频事件后 n 秒内函数只会执行一次,如果 n 秒内高频事件再次被触
发,则重新计算时间。
思路:每次触发事件时都取消之前的延时调用方法。
function debounce (fn, delay,...rest) {
let timeout = null;
return function (e) {
// e:事件对象
if (timeout) { clearTimeout(timeout) };//把前面那个
timeout
清除
timeout = setTimeout(()=>{
console.log(e, rest);
console.log(this);
fn.apply(this, [e, ...rest]);// 绑定 this
指向
}, delay);
}
}
function sayHi(e, ...rest) {
console.log(e, rest);
console.log(this.value);
}
var inp = document.getElementById('inp');
inp.addEventListener('input', debounce(sayHi, 300, 100, 200));
节流:高频事件触发,但在 n 秒内只执行一次,所以节流会稀释函数的执行频率。
思路:每次触发事件时都判断当前是否有等待执行的延时函数。
function throttle(fn) {
let canRun = true; // 通过闭包保存一个标记
return function () {
if (! canRun) return; // 在函数开头判断标记是否为
true
,不为
true
则
return
canRun = false; // 立即设置为
false
setTimeout(() => { // 将外部传入的函数的执行放在
setTimeout
中
fn. apply (this, arguments);
// 最后在 setTimeout
执行完毕后再把标记设置为
true(
关键
)
表示可以执行下一次循环了。当定时器没有执行的时候标记永远是 false
,在开头被
return
掉
canRun = true;
}, 500);
};
}
function sayHi(e) {
console.log (e. target. innerWidth, e. target. innerHeight);
}
window. addEventListener ('resize', throttle(sayHi));
6.预加载与懒加载
预加载: 提前加载资源--同源加载的优化
懒加载: 先不加载 等条件成立时再加载
预加载: 提前加载资源--同源加载的优化
懒加载: 先不加载 等条件成立时再加载



