DOM 与事件JavaScript、ES6 高频重点面试题 | arry老师的博客-艾编程
目录
DOM 与事件JavaScript、ES6 高频重点面试题 | arry老师的博客-艾编程
2、冒泡和捕获,这个浏览器的冒泡和捕获能颠倒么 ? (字节)
4、 setTimeout为什么会存在延迟?怎么解决这个问题 ?(广联达)
6、给一个 DOM 同时绑定两个点击事件,一个用捕获,一个用冒泡,说下会执行几次事件,然后会先执行冒泡还是捕获(知乎)
8、CSS加载会阻塞JS的执行吗?异步加载 css 会阻塞页面的渲染吗?(腾讯)
10、DOM 树和 css dom 树是互斥的还是同时的(字节)
11、JS 脚本阻塞 DOM 构建,JS 脚本会不会对 css dom 树影响(字节)
12、script标签中defer和async都表示了什么⭐⭐⭐⭐⭐
1、说一说事件冒泡,事件委托以及应用场景(同花顺、网易)
事件冒泡:子元素向父元素传递的过程
事件委托:因为冒泡机制,触发子元素事件的时候,会同步触发父元素的相同事件,所以就可以把子元素的事件委托给父元素来做
好处:将多个事件处理器减少到一个,可减少内存,提高性能;新添加的元素也能触发相应事件
<body> <ul> <li>知否知否,点我应有弹框在手!</li> <li>知否知否,点我应有弹框在手!</li> <li>知否知否,点我应有弹框在手!</li> <li>知否知否,点我应有弹框在手!</li> <li>知否知否,点我应有弹框在手!</li> </ul> <script> // 事件委托的核心原理:给父节点添加侦听器, 利用事件冒泡影响每一个子节点 var ul = document.querySelector('ul'); ul.addEventListener('click', function(e) { // alert('知否知否,点我应有弹框在手!'); // e.target 这个可以得到我们点击的对象 e.target.style.backgroundColor = 'pink'; }) </script> </body>
2、冒泡和捕获,这个浏览器的冒泡和捕获能颠倒么 ? (字节)
- 事件流顺序:捕获阶段,执行阶段,冒泡阶段
- 冒泡:逐级向上传播到DOM最顶层节点
- 捕获:逐级向下传播到最具体的元素接受过程
先捕获后冒泡
1.Js代码中只能执行捕获或者冒泡其中的一个阶段。
2.onclick和attachEvent只能得到冒泡阶段。
3.addEventListener(type,listener【,useCapture】)第三个参数如果是true,表示在事件捕获阶段调用事件处理程序;如果是fa1se(不写默认就是false),表示在事件冒泡阶段调用事件处理程序。
4.实际开发中我们很少使用事件捕获,我们更关注事件冒泡。
5.有些事件是没有冒泡的,比如onblur、onfocus、onmouseenter、onmouseleave
3、如何阻止事件冒泡(网易、京东)
阻止事件冒泡:
- W3C:e.stopPropagation()
- IE: event.cancelBubble=true
阻止默认事件:
- W3C: event.preventDefault()
- IE:event.returnValue=false
<body> <div class="father"> <div class="son">son儿子</div> </div> <script> // 常见事件对象的属性和方法 // 阻止冒泡 dom 推荐的标准 stopPropagation() var son = document.querySelector('.son'); son.addEventListener('click', function(e) { alert('son'); e.stopPropagation(); // stop 停止 Propagation 传播 e.cancelBubble = true; // 非标准 cancel 取消 bubble 泡泡 }, false); var father = document.querySelector('.father'); father.addEventListener('click', function() { alert('father'); }, false); document.addEventListener('click', function() { alert('document'); }) </script> </body>
4、 setTimeout
为什么会存在延迟?怎么解决这个问题 ?(广联达)
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <p id="message"></p> </body> <script type="text/javascript"> var message = document.getElementById("message"); var count = 1000; function animate() { var start = +new Date(); message.innerHTML = count--; var finish = +new Date(); setTimeout(animate, 1000 - (finish-start)); } animate(); </script> </html>
本例实现了倒数1000秒的功能,我们在使用setTimeout的时候如果要一个函数每每隔1秒执行一次就会这样写
setTimeout(animate, 1000);
但是这样会忽略animate方法本身的运行时间,所以我们可以在执行animate方法的时候计算这个方法主要的语句的执行时间,之后在setTimeout中减去那个由于运行语句而耽搁的时间,从而实现更加精确的计时
原文链接:https://blog.youkuaiyun.com/hrj970808/article/details/109645183
5、 DOM 怎么添加事件(阿里)
给元素添加事件,即注册事件或绑定事件
1.传统方法
- 利用on开头的事件onclick
- <button οnclick="alert("hi")"></button>
- btn.οnclick=function(){}
- 特点:注册事件的唯一性
- 同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数会覆盖前面注册的处理函数
2.方法监听注册方式
- addEventListener()
- IE9之前的IE不支持,可使用attachEvent()代替
- 特点:同一个元素同一个事件可以注册多个监听器
<body> <button>传统注册事件</button> <button>方法监听注册事件</button> <button>ie9 attachEvent</button> <script> var btns = document.querySelectorAll('button'); // 1. 传统方式注册事件 btns[0].onclick = function() { alert('hi'); } btns[0].onclick = function() { alert('hao a u'); } // 2. 事件侦听注册事件 addEventListener // (1) 里面的事件类型是字符串 必定加引号 而且不带on // (2) 同一个元素 同一个事件可以添加多个侦听器(事件处理程序) btns[1].addEventListener('click', function() { alert(22); }) btns[1].addEventListener('click', function() { alert(33); }) // 3. attachEvent ie9以前的版本支持 btns[2].attachEvent('onclick', function() { alert(11); }) </script> </body>
6、给一个 DOM 同时绑定两个点击事件,一个用捕获,一个用冒泡,说下会执行几次事件,然后会先执行冒泡还是捕获(知乎)
- 先捕获再冒泡
- 由外向内捕获
- 由内向外冒泡
牛客网例题:
7、dom 树和 render 树有啥区别(腾讯)
浏览器的渲染过程:
- 解析 HTML 构建 DOM(DOM 树),并行请求 css/image/js
- CSS 文件下载完成,开始构建 CSSOM(CSS 树)
- CSSOM 构建结束后,和 DOM 一起生成 Render Tree(渲染树)
- 布局(Layout):计算出每个节点在屏幕中的位置
- 显示(Painting):通过显卡把页面画到屏幕上
DOM树:
- 浏览器将HTML解析成树形的数据结构,简称DOM。
- DOM 是文档对象模型 (Document Object Model) 的缩写。它是 HTML 文档的对象表示,同时也是外部内容(例如 JavaScript)与 HTML 元素之间的接口。
- 解析树的根节点是 Document对象
- 注意:文档(整个DOM树)的根节点是document
会阻塞dom解析的资源
- 内联css在标签内部通过style属性来设置元素的样式。
- 内联js
- 普通外联js
- 外联defer js
- js之前的外联css
所以,JS 会阻塞 DOM 解析
- 浏览器无法知晓
JS
的具体内容,倘若先解析DOM
,万一JS
内部全部删除掉DOM
,那么浏览器就白忙活了,所以就干脆暂停解析DOM
,等到JS
执行完成再继续解析。如何解决或者避免
- 将scrip标签放在body闭合时的上方
- 利用dom动态创建script标签
- 将script标签放在头部,但是要加上async或者defer
渲染树(render树):
浏览器在构造DOM树的同时也在构造着另一棵树-Render Tree,与DOM树相对应暂且叫它Render树。我们知道DOM树为javascript提供了一些列的访问接口(DOM API),但这棵树是不对外的。它的主要作用就是把HTML按照一定的布局与样式显示出来,用到了CSS的相关知识。从MVC的角度来说,可以将render树看成是V,dom树看成是M,C则是具体的调度者,比HTMLDocumentParser等。render树:
8、CSS加载会阻塞JS的执行吗?异步加载 css 会阻塞页面的渲染吗?(腾讯)
1、CSS加载会阻塞js的执行,因为js可能会去获取或改变元素的样式,所以浏览为了不重复渲染,等所有的css加载渲染完成后在执行js
2、异步加载不会阻塞渲染
在默认情况下,浏览器在加载
CSS
时将终止页面的样式呈现(同步加载),也就是加载CSS
会阻塞DOM树
的渲染(但并不会阻塞DOM树
的构建),可以简单理解为:当在加载CSS
的同时,也在构建DOM树
,只是没有应用上样式。
9、CSS会阻塞DOM解析吗?会阻塞DOM渲染吗
(CSS解析和DOM树解析是并行的)
CSS 不会阻塞 DOM 解析,但是会阻塞 DOM 渲染
浏览器的解析渲染过程,解析
DOM
生成DOM Tree
,解析CSS
生成CSSOM Tree
,两者结合生成render tree
渲染树,最后浏览器根据渲染树渲染至页面。由此可以看出
DOM Tree
的解析和CSSOM Tree
的解析是互不影响的,两者是并行的。因此
CSS
不会阻塞页面DOM
的解析,但是由于render tree
的生成是依赖DOM Tree
和CSSOM Tree
的,因此CSS
必然会阻塞DOM
的渲染。更为严谨一点的说,
CSS
会阻塞render tree
的生成,进而会阻塞DOM
的渲染。
10、DOM 树和 css dom 树是互斥的还是同时的(字节)
DOM 树和 css dom 树的解析是并行的
11、JS 脚本阻塞 DOM 构建,JS 脚本会不会对 css dom 树影响(字节)
会有影响?
JavaScript的加载、解析与执行会阻塞DOM的构建,也就是说,在构建DOM时,HTML解析器若遇到了JavaScript,那么它会暂停构建DOM,将控制权移交给JavaScript引擎,等JavaScript引擎运行完毕,浏览器再从中断的地方恢复DOM构建。
也就是说,如果你想首屏渲染的越快,就越不应该在首屏就加载 JS 文件,这也是都建议将 script 标签放在 body 标签底部的原因。当然在当下,并不是说 script 标签必须放在底部,因为你可以给 script 标签添加 defer 或者 async 属性。
JS文件不只是阻塞DOM的构建,它会导致CSSOM也阻塞DOM的构建。
原本DOM和CSSOM的构建是互不影响,井水不犯河水,但是一旦引入了JavaScript,CSSOM也开始阻塞DOM的构建,只有CSSOM构建完毕后,DOM再恢复DOM构建。
原文链接:https://blog.youkuaiyun.com/weixin_45820444/article/details/109013996
12、script标签中defer和async都表示了什么⭐⭐⭐⭐⭐
script 标签中的defer 和 async 属性_记忆怪 bug的博客-优快云博客_script标签的defer和async
script会阻塞页面的加载,如果我们要是引用外部js,假如这个外部js请求很久的话就难免出现空白页问题,好在官方为我们提供了defer和async
defer
<script src="d.js" defer></script>
<script src="e.js" defer></script>
- 不会阻止页面解析,并行下载对应的js文件
- 下载完之后不会执行
- 等所有其他脚本加载完之后,在DOMContentLoaded事件之前执行对应d.js、e.js
async
<script src="b.js" async></script>
<script src="c.js" async></script>
- 不会阻止DOM解析,并行下载对应的js文件
- 下载完之后立即执行
首先是浏览器发送请求以后,服务器或者本地返回给浏览器HTML文件
第一步解析HTML文件并且构建DOM
在解析html文件的时候遇到了link标签,浏览器就去请求css文件,请求css文件的同时也继续解析HTML文件,
然后遇到了script标签,浏览器就去请求js文件,服务器或者本地就会陆续返回css和js文件,实际操作中会先得到css还是js文件是要看具体情况的,
重点:这里如果先返回并且解析完成js文件也是会发生阻塞的,不能先执行js文件,必须等到cssom构建完成了才能执行js文件,因为渲染树是需要dom和cssom构建完成了以后才能构建,而且js是可以控制css样式的,所以返回css文件后就是解析css文件并且构建cssom,如果script中是写的样式,也会阻塞!
cssom的构建就是渲染中得一个重要的阻塞因素,dom也是会阻塞渲染过程的,但是dom可以部分解析,csson不可以部分解析!
在解析css文件并且构建cssom的时候,浏览器依旧可以去下载并且解析js文件,等cssom构建完成以后就可以执行js里面的内容了。
js是会阻塞html解析,js既可以操作dom,又可以操作cssom,如果不等js下载完并解析。有可能导致网页的的有些内容出现了又消失,所以在解析html文件的时候,不管是行内js代码还是外部js文件,都会让html的解析停止下来!
js执行完之前,啥都没有,js执行完以后,构建dom,构建渲染树