整合部分
(1)http和https基本概念
http:超文本传输协议,是一种网络协议,遵从TPC原则。
https:是以安全为目标的http协议,在http的基础上进行了ssl加密,ssl运用在传输层。
(2)http和https区别
http传输是未加密的,也就是说是明文的。网景公司设置了SSL协议来对http传输进行加密,即为https。
主要的区别如下:
https需要ca证书,定期交一定费用。端口为443,有SSL协议
http不需要,http是明文传输。端口为80.很简单,无状态
(3)
主要有如下几个步骤:
-
客户端使用https:url访问,web服务器要建立ssl链接。
-
web服务器接收到客户请求后,将网络证书(证书包含公匙),返回或者传给客户端。
-
客户端和web服务器开始进行ssl协议加密。
-
客户端和服务器协商一致安全性后,通过网站公匙进行加密,并传给网站。
-
web服务器通过私密钥解密秘钥
-
web 服务器通过会话密钥加密与客户端之间的通信。
(4)https优点
HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,要比http 协议安全,可防止数据在传输过程中不被窃取、改变,确保数据的完整性。
(5)https缺点
https 握手阶段比较费时.
https 缓存不如 http 高效.
https的ssl加密也比较费钱
SSL 证书需要绑定 IP,不能再同一个 ip 上绑定多个域名。
总结:https即为在http基础上增加了Ca证书和SSL协议。https在进行访问时候,web服务器将网络证书传给客户端,网络证书传给客户端后,进行ssl加密,web服务器通过私密钥解密,然后进行加密连接。
2. TCP的三次握手
tcp就像打电话需要对方确认身份。客户向服务端发送请求,服务端进行确认,然后传递给客户。
3.TCP和UDP的区别
(1)TCP是面向连接的,需要先建立连接。UDP不需要建立连接就可以发送数据。
(2)TCP 提供可靠的服务。也就是说,通过 TCP 连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP 尽最大努力交付,即不保证可靠交付。 并且因为 tcp可靠,面向连接,不会丢失数据因此适合大数据量的交换。
(3)首部传输的字节也不一样,TCP传输20字节,UDP只有8字节。
(4)TCP一对一的,UDP可以一对多
(5)TCP 是面向连接的可靠性传输,而 UDP 是不可靠的。
总结:TCP更像打电话,UDP更像发短信。TCP首部传20字节,UDP首部只能传8字节
4.WebSocket 的实现和应用
(1)什么是 WebSocket?
WebSocket 是 HTML5 中的协议,支持持久连续,http 协议不支持持久性连接。Http1.0
和 HTTP1.1 都不支持持久性的链接,HTTP1.1 中的 keep-alive,将多个 http 请求合并为
1 个
(2)WebSocket 是什么样的协议,具体有什么优点?
HTTP 的生命周期通过 Request 来界定,也就是 Request 一个 Response,那么在 Http1.0
协议中,这次 Http 请求就结束了。在 Http1.1 中进行了改进,是的有一个 connection:
Keep-alive,也就是说,在一个 Http 连接中,可以发送多个 Request,接收多个 Response。
但是必须记住,在 Http 中一个 Request 只能对应有一个 Response,而且这个 Response
是被动的,不能主动发起。
WebSocket 是基于 Http 协议的,或者说借用了 Http 协议来完成一部分握手,在握手阶段
与 Http 是相同的。我们来看一个 websocket 握手协议的实现,基本是 2 个属性,upgrade,
connection。
基本请求如下:
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
多了下面 2 个属性:
1Upgrade:webSocket
2Connection:Upgrade
告诉服务器发送的是 websocket
1Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
2Sec-WebSocket-Protocol: chat, superchat
3Sec-WebSocket-Version: 13
总结:websocket是html5的协议,和服务器进行实时通话时用的比较多。建立通话new webSocket(),利用new websocket的方法进行传输。
initWebSocket: function (userId,sessionId) {
// WebSocket与普通的请求所用协议有所不同,ws等同于http,wss等同于https
this.websock = new WebSocket("ws://127.0.0.1:1997/websocket/"+userId+"/"+sessionId);
this.websock.onopen = this.websocketonopen;
this.websock.onerror = this.websocketonerror;
this.websock.onmessage = this.websocketonmessage;
this.websock.onclose = this.websocketclose;
},
websocketonopen: function () {
console.log("WebSocket连接成功");
},
websocketonerror: function (e) {
console.log("WebSocket连接发生错误",e);
},
websocketonmessage: function (e) {
console.log("获取到后端传递来的数据",e.data);
},
websocketclose: function (e) {
console.log("WebSocket连接关闭",e);
}
5.http的请求方式 head方式
head:方式类似get请求方式,不同的是没有请求内容,用户只获取报头。
option: 允许服务端查询客户端请求的性能,和支持的方式。
总结:head只获取报头,option允许查看性能和支持方式
6.一个图片 url 访问后直接下载怎样实现?
请求的返回头里面,用于浏览器解析的重要参数就是 OSS 的 API 文档里面的返回 http头,决定用户下载行为的参数。
7.说一下 web Quality(无障碍)
能够被残障人士使用的网站才能称得上一个易用的(易访问的)网站。
残障人士指的是那些带有残疾或者身体不健康的用户。
使用 alt 属性:
有时候浏览器会无法显示图像。具体的原因有:
用户关闭了图像显示
浏览器是不支持图形显示的迷你浏览器
浏览器是语音浏览器(供盲人和弱视人群使用)
如果您使用了 alt 属性,那么浏览器至少可以显示或读出有关图像的描述。
总结:使web更加适合残疾或者身体不健康用户访问
8.几个很实用的 BOM 属性对象方法?
什么是 Bom? Bom 是浏览器对象。有哪些常用的 Bom 属性呢?
(1)location 对象
location.href-- 返回或设置当前文档的 URL
location.search -- 返回 URL 中的查询字符串部分。例
如 http://www.dreamdu.com/dreamdu.php?id=5&name=dreamdu 返回包括(?)后面的内
容?id=5&name=dreamdu
location.hash -- 返回 URL#后面的内容,如果没有#,返回空
location.host -- 返回 URL 中的域名部分,例如 www.dreamdu.com
location.hostname -- 返回 URL 中的主域名部分,例如 dreamdu.com
location.pathname -- 返回 URL 的域名后的部分。例如 http://www.dreamdu.com/xhtml/ 返
回/xhtml/
location.port -- 返回 URL 中的端口部分。例如 http://www.dreamdu.com:8080/xhtml/ 返回
8080
location.protocol -- 返回 URL 中的协议部分。例如 http://www.dreamdu.com:8080/xhtml/ 返
回(//)前面的内容 http:
location.assign -- 设置当前文档的 URL
location.replace() -- 设置当前文档的 URL,并且在 history 对象的地址列表中移除这个
URL location.replace(url);
location.reload() -- 重载当前页面
(2)history 对象
history.go() -- 前进或后退指定的页面数 history.go(num);
history.back() -- 后退一页
history.forward() -- 前进一页
(3)Navigator 对象
navigator.userAgent -- 返回用户代理头的字符串表示(就是包括浏览器版本信息等的字
符串)
navigator.cookieEnabled -- 返回浏览器是否支持(启用)cookie
总结:BOM即为浏览器对象,是浏览器自带的方法,不如location,navigator,history
9.说一下 HTML5 drag api
dragstart:事件主体是被拖放元素,在开始拖放被拖放元素时触发,。
darg:事件主体是被拖放元素,在正在拖放被拖放元素时触发。
dragenter:事件主体是目标元素,在被拖放元素进入某元素时触发。
dragover:事件主体是目标元素,在被拖放在某元素内移动时触发。
dragleave:事件主体是目标元素,在被拖放元素移出目标元素是触发。
drop:事件主体是目标元素,在目标元素完全接受被拖放元素时触发。
dragend:事件主体是被拖放元素,在整个拖放操作结束时触发
总结:drag是拖拽属性
10.说一下 http2.0
首先补充一下,http 和 https 的区别,相比于 http,https 是基于 ssl 加密的 http 协议简要概括:http2.0 是基于 1999 年发布的 http1.0 之后的首次更新。
提升访问速度(可以对于,请求资源所需时间更少,访问速度更快,相比 http1.0)允许多路复用:多路复用允许同时通过单一的 HTTP/2 连接发送多重请求-响应信息。改善了:在 http1.0 中,浏览器客户端在同一时间,针对同一域名下的请求有一定数量限制(连接数量),超过限制会被阻塞。二进制分帧:HTTP2.0 会将所有的传输信息分割为更小的信息或者帧,并对他们进行二
进制编码
首部压缩
服务器端推送
总结:http2.0就是http1.0后首次更新严格说是http1.1,增加了服务器推送功能,改善了在同一时间内,针对同一域名下的请求有一定数量限制,超过会被阻塞的问题。
11.fetch 发送 2 次请求的原因
fecth在请求时候会先发送options请求,进行查询请求的支持方式,然后再发送请求。
12.Cookie、sessionStorage、localStorage 的区别
(1)Cookie是在浏览器中储存,在浏览器请求时进行携带,多用于保存用户的用户名和密码。也可设置保存日期。单个cookie储存不能超过4k
(2)sessionStorage是在浏览器中储存,浏览器关闭消失。大小5mb。
(3) localstorage是储存在本地,浏览器关闭依然存在。大小为5mb。
13.说一下 web worker
在 HTML 页面中,如果在执行脚本时,页面的状态是不可相应的,直到脚本执行完成后,页面才变成可相应。web worker 是运行在后台的 js,独立于其他脚本,不会影响页面你的性能。并且通过 postMessage 将结果回传到主线程。这样在进行复杂操作的时候,就不会阻塞主线程了。
14.对 HTML 语义化标签的理解
HTML5 语义化标签是指正确的标签包含了正确的内容,结构良好,便于阅读,比如 nav表示导航条,类似的还有 article、header、footer 等等标签。
15.iframe 是什么?有什么缺点?
iframe 元素会创建包含另一个文档的内联框架。
缺点:(1)阻塞页面onLoad事件。(2)不利于seo搜索。(3)影响性能
16.Doctype 作用?严格模式与混杂模式如何区分?它们有何意义?
Doctype声明在文档前面,告诉浏览器用什么方式渲染页面。这里有两种方式:严格模式和混杂模式。
严格模式的排版和 JS 运作模式是 以该浏览器支持的最高标准运行。
混杂模式,向后兼容,模拟老式浏览器,防止浏览器无法兼容页面。
总结:告诉浏览器渲染页面的方式。严格模式用最高级渲染,混杂模式进行兼容渲染。
17.Cookie 如何防范 XSS 攻击
XSS(跨站脚本攻击)是指攻击者在返回的 HTML 中嵌入 javascript 脚本,为了减轻这些攻击,需要在 HTTP 头部配上,set-cookie:httponly-这个属性可以防止 XSS,它会禁止 javascript 脚本来访问 cookie。secure - 这个属性告诉浏览器仅在请求为 https 的时候发送 cookie。
结果应该是这样的:Set-Cookie=<cookie-value>.....
18.Cookie 和 session 的区别
Cookie多放在前端,session多放在服务器上。
19.click 在 ios 上有 300ms 延迟,原因及如何解决?
(1)粗暴型,禁用缩放
(2)利用 FastClick,其原理是:
检测到 touchend 事件后,立刻出发模拟 click 事件,并且把浏览器 300 毫秒之后真正出
发的事件给阻断掉
20.addEventListener 参数
addEventListener(event, function, useCapture)
其中,event 指定事件名;function 指定要事件触发时执行的函数;useCapture 指定事件
是否在捕获或冒泡阶段执行
21.介绍知道的 http 返回的状态码
100 Continue 继续。客户端应继续其请求
200 OK 请求成功。一般用于 GET 与 POST 请求
404 Not Found 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
500 Internal Server Error 服务器内部错误,无法完成请求
22.强,协商缓存
协商缓存和强缓存是HTTP协议中的两种不同的缓存机制,用于优化网络性能和减少重复请求。它们在客户端和服务器之间进行通信,以确定是否使用缓存副本或请求最新资源。
-
强缓存(Expires和Cache-Control):
-
Expires:通过设置Expires响应头,服务器告诉浏览器资源的过期时间。当浏览器发起请求时,如果本地缓存未过期,浏览器将直接使用缓存副本,而无需再次请求服务器。
-
Cache-Control:通过设置Cache-Control响应头,服务器可以提供更精确的缓存控制。常见的Cache-Control指令包括max-age、public、private、no-cache和no-store等。例如,设置max-age=3600表示资源在3600秒内有效,浏览器可以直接使用缓存。
-
协商缓存(Last-Modified和ETag):
-
Last-Modified:服务器在响应头中返回资源的最后修改时间(GMT格式)。当浏览器再次请求资源时,通过If-Modified-Since请求头将上次的最后修改时间发送给服务器。如果资源的最后修改时间与服务器上的相同,服务器返回304 Not Modified响应,告诉浏览器可以使用缓存副本。
-
ETag:服务器在响应头中返回资源的唯一标识符(通常是哈希值)。当浏览器再次请求资源时,通过If-None-Match请求头将上次的ETag发送给服务器。如果资源的ETag与服务器上的相同,服务器返回304 Not Modified响应,告诉浏览器可以使用缓存副本。
23.前端优化
降低请求量:合并资源,减少 HTTP 请求数,minify / gzip 压缩,webP,lazyLoad。
加快请求速度:预解析 DNS,减少域名数,并行加载,CDN 分发。
缓存:HTTP 协议缓存请求,离线缓存 manifest,离线数据缓存 localStorage。
渲染:JS/CSS 优化,加载顺序,服务端渲染,pipeline。
24.GET 和 POST 的区别
Get:传参在url上,有长度限制
Post:传参在body上,无长度限制。
GET 产生一个 TCP 数据包;POST 产生两个 TCP 数据包。
25.在地址栏里输入一个 URL,到这个页面呈现出来,中间会发生什么?
输入 url 后,首先需要找到这个 url 域名的服务器 ip,为了寻找这个 ip,浏览器首先会寻找缓存,查看缓存中是否有记录,缓存的查找记录为:浏览器缓存-》系统缓存-》路由器缓存,缓存中没有则查找系统的 hosts 文件中是否有记录,如果没有则查询 DNS 服务器,得到服务器的 ip 地址后,浏览器根据这个 ip 以及相应的端口号,构造一个 http 请求,这个请求报文会包括这次请求的信息,主要是请求方法,请求说明和请求附带的数据,并将这个 http 请求封装在一个 tcp 包中,这个 tcp 包会依次经过传输层,网络层,数据链路层,物理层到达服务器,服务器解析这个请求来作出响应,返回相应的 html给浏览器,因为 html 是一个树形结构,浏览器根据这个 html 来构建 DOM 树,在 dom树的构建过程中如果遇到 JS 脚本和外部 JS 连接,则会停止构建 DOM 树来执行和下载相应的代码,这会造成阻塞,这就是为什么推荐 JS 代码应该放在 html 代码的后面,之后根据外部央视,内部央视,内联样式构建一个 CSS 对象模型树 CSSOM 树,构建完成后和 DOM 树合并为渲染树,这里主要做的是排除非视觉节点,比如 script,meta 标签和之后是渲染页面,因为 html 文件中会含有图片,视频,音频等资源,在解析 DOM 的过程中,遇到这些都会进行并行下载,浏览器对每个域的并行下载数量有一定的限制,一般是 4-6 个,当然在这些所有的请求中我们还需要关注的就是缓存,缓存一般通过Cache-Control、Last-Modify、Expires 等首部字段控制。 Cache-Control 和 Expires 的区别在于 Cache-Control 使用相对时间,Expires 使用的是基于服务器 端的绝对时间,因为存在时差问题,一般采用 Cache-Control,在请求这些有设置了缓存的数据时,会先 查看是否过期,如果没有过期则直接使用本地缓存,过期则请求并在服务器校验文件是否修改,如果上一次 响应设置了 ETag 值会在这次请求的时候作为 If-None-Match 的值交给服务器校验,如果一致,继续校验 Last-Modified,没有设置 ETag 则直接验证Last-Modified,再决定是否返回 304排除 display 为 none 的节点,之后进行布局,布局主要是确定各个元素的位置和尺寸。
26. 浏览器在生成页面的时候,会生成那两颗树?
构造两棵树,DOM 树和 CSSOM 规则树,当浏览器接收到服务器相应来的 HTML 文档后,会遍历文档节点,生成 DOM 树,CSSOM 规则树由浏览器解析 CSS 文件生成。
27.csrf 和 xss 的网络攻击及防范
CSRF(Cross Site Request Forgery,跨站请求伪造):跨站请求伪造,可以理解为攻击者盗用了用户的身份,以用户的名义发送了恶意请求,比如用户登录了一个网站后,立刻在另一个tab页面访问量攻击者用来制造攻击的网站,这个网站要求访问刚刚登陆的网站,并发送了一个恶意请求,这时候 CSRF就产生了,比如这个制造攻击的网站使用一张图片,但是这种图片的链接却是可以修改数据库的,这时候攻击者就可以以用户的名义操作这个数据库,防御方式的话:使用验证码,检查 https 头部的 refer,使用 token。
xss(Cross Site Scripting):跨站脚本攻击,是说攻击者通过注入恶意的脚本,在用户浏览网页的时候进行攻击,比如获取 cookie,或者其他用户身份信息,可以分为存储型和反射型,存储型是攻击者输入一些数据并且存储到了数据库中,其他浏览者看到的时候进行攻击,反射型的话不存储在数据库中,往往表现为将攻击代码放在 url 地址的请求参数中,防御的话为cookie 设置 httpOnly 属性,对用户的输入进行检查,进行特殊字符过滤。
总结:CSRF为盗用了用户的身份进行了攻击,恶意做一些操作。可以使用验证码,token处理。xss利用一些恶意的脚本获取cookie进行攻击。对cookie属性设置httponly,对用户检查,特殊字符过滤
28.说一下 css 盒模型
简介:就是用来装页面上的元素的矩形区域。CSS 中的盒子模型包括 IE 盒子模型和标准的 W3C 盒子模型。
box-sizing(有 3 个值哦):border-box,padding-box,content-box
29.transition 和 animation 的区别
Animation 和 transition 大部分属性是相同的,他们都是随时间改变元素的属性值,他们的主要区别是 transition 需要触发一个事件才能改变属性,而 animation 不需要触发任何事件的情况下才会随时间改变属性值,并且 transition 为 2 帧,从 from .... to,而 animation可以一帧一帧的。
30.Flex 布局
Flex 是 Flexible Box的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。布局的传统解决方案,基于盒状模型,依赖 display 属性 + position 属性 + float 属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。简单的分为容器属性和元素属性
31.BFC(块级格式化上下文,用于清楚浮动,防止 margin 重叠等)
直译成:块级格式化上下文,是一个独立的渲染区域,并且有一定的布局规则。
32.关于 JS 动画和 css3 动画的差异性
渲染线程分为 main thread 和 compositor thread,如果 css 动画只改变 transform 和 opacity,
这时整个 CSS 动画得以在 compositor trhead 完成(而 JS 动画则会在 main thread 执行,然
后出发 compositor thread 进行下一步操作),特别注意的是如果改变 transform 和 opacity
是不会 layout 或者 paint 的。
区别:
功能涵盖面,JS 比 CSS 大
实现/重构难度不一,CSS3 比 JS 更加简单,性能跳优方向固定
对帧速表现不好的低版本浏览器,css3 可以做到自然降级
css 动画有天然事件支持
css3 有兼容性问题
33.visibility=hidden, opacity=0,display:none
opacity=0,该元素隐藏起来了,但不会改变页面布局,并且,如果该元素已经绑定一些事件,如 click 事件,那么点击该区域,也能触发点击事件的visibility=hidden,该元素隐藏起来了,但不会改变页面布局,但是不会触发该元素已经绑定的事件 display=none,把元素隐藏起来,并且会改变页面布局,可以理解成在页面中把该元素删除掉一样。
34.浮动清除
如果一个父盒子中有一个子盒子,并且父盒子没有设置高,子盒子在父盒子中进行了浮动,那么将来父盒子的高度为0.由于父盒子的高度为0,下面的元素会自动补位,所以这个时候要进行浮动的清除。
方法一:使用带 clear 属性的空元素
在浮动元素后使用一个空元素如<div class="clear"></div>,并在 CSS 中赋予.clear{clear:both;}属性即可清理浮动。亦可使用<br class="clear" />或<hr class="clear" />来进行清理。
方法二:使用 CSS 的 overflow 属性
给浮动元素的容器添加 overflow:hidden;或 overflow:auto;可以清除浮动,另外在 IE6 中还需要触发 hasLayout ,例如为父元素设置容器宽高或设置 zoom:1。
在添加 overflow 属性后,浮动元素又回到了容器层,把容器高度撑起,达到了清理浮动的效果。
方法三:使用 CSS 的:after 伪元素
使用伪元素clear:both
35.CSS 选择器有哪些,优先级呢
id 选择器,class 选择器,标签选择器,伪元素选择器,伪类选择器等。
id 选择器 > class 选择器 > 标签选择器
36.calc 属性
Calc 用户动态计算长度值,任何长度值都可以使用 calc()函数计算,需要注意的是,运算符前后都需要保留一个空格,例如:width: calc(100% - 10px);
37.display:table 和本身的 table 有什么区别
Display:table 和本身 table 是相对应的,区别在于,display:table 的 css 声明能够让一个html 元素和它的子节点像 table 元素一样,使用基于表格的 css 布局,是我们能够轻松定义一个单元格的边界,背景等样式,而不会产生因为使用了 table 那样的制表标签导致的语义化问题。之所以现在逐渐淘汰了 table 系表格元素,是因为用 div+css 编写出来的文件比用 table边写出来的文件小,而且 table 必须在页面完全加载后才显示,div 则是逐行显示,table 的嵌套性太多,没有 div 简洁。
总结:div像table那样去展示。比语义化table展示的文件小。
38.对 CSS 的新属性有了解过的吗
CSS3 的新特性中,在布局方面新增了 flex 布局,在选择器方面新增了例如first-of-type,nth-child 等选择器,在盒模型方面添加了 box-sizing 来改变盒模型,在动画方面增加了 animation,2d 变换,3d 变换等,在颜色方面添加透明,rbga 等,在字体方面允许嵌入字体和设置字体阴影,最后还有媒体查讯等
39.line-height 和 height 的区别
line-height 一般是指布局里面一段文字上下行之间的高度,是针对字体来设置的,height 一般是指容器的整体高度。
40.inline-block、inline 和 block 的区别;为什么 img 是 inline 还可以设置宽高
Inline-block:能设置宽度高度,margin/padding 水平垂直方向 都有效,前后无换行符。
Inline:设置 width 和 height 无效,margin 在竖直方向上无效,padding 在水平方向垂直方向都有效,前后无换行符。
Inline-block:能设置宽度高度,margin/padding 水平垂直方向 都有效,前后无换行符。
41.了解重绘和重排吗,知道怎么去减少重绘和重排吗,让文档脱离文档流有哪些方法
浏览器窗口大小发生改变,重排一定导致重绘,重绘不一定导致重排。Dom的样式发生改变导致重绘。dom的大小和删除的改变导致重排。
42.overflow 的原理
block formatting context简称BFC当元素设置了 overflow 样式且值部位 visible 时,该元素就构建了一个 BFC,BFC 在计算高度时,内部浮动元素的高度也要计算在内,也就是说技术 BFC 区域内只有一个浮动元素,BFC 的高度也不会发生塌缩,所以达到了清除浮动的目的。
总结:overflow时候,构建了BFC把内部浮动元素的高度也计算在内。
43.box-sizing 的语法和基本用处
box-sizing 规定两个并排的带边框的框,语法为 box-sizing:content-box/border-box/inheritcontent-box:宽度和高度分别应用到元素的内容框,在宽度和高度之外绘制元素的内边距和边框
border-box:为元素设定的宽度和高度决定了元素的边框盒,
inherit:继承父元素的 box-sizing
44.使元素消失的方法有哪些?
-
opacity:0,该元素隐藏起来了,但不会改变页面布局,并且,如果该元素已经绑定一些事件,如 click 事件,那么点击该区域,也能触发点击事件的
-
visibility:hidden,该元素隐藏起来了,但不会改变页面布局,但是不会触发该元素已经绑定的事件
-
display:none,把元素隐藏起来,并且会改变页面布局,可以理解成在页面中把该元素删除掉。
45.说说盒子模型
CSS 盒模型本质上是一个盒子,封装周围的 HTML 元素,它包括:边距,边框,填充,和实际内容。
标准盒模型:一个块的总宽度=width+margin(左右)+padding(左右)+border(左右)。
怪异盒模型:一个块的总宽度=width+margin(左右)(既 width 已经包含了 padding 和border 值)
如何设置:box-sizing:border-box
46.css 预处理器有什么
less,sass 等
47.说一下闭包
一句话可以概括:闭包就是能够读取其他函数内部变量的函数,或者子函数在外调用,子函数所在的父函数的作用域不会被释放。
var a = 1;
function outerFunc(){
var b = a + 10;
function innerFunc(){
var c = 2;
return b+c;
}
return innerFunc();
}
outerFunc();
48.说一下类的创建和继承
(1)类的创建(es5):new 一个 function,在这个 function 的 prototype 里面增加属性和方法。
下面来创建一个 Animal 类:
// 定义一个动物类
function Animal (name) {
// 属性
this.name = name || 'Animal';
// 实例方法
this.sleep = function(){
console.log(this.name + '正在睡觉!');
}
}
// 原型方法
Animal.prototype.eat = function(food) {
console.log(this.name + '正在吃:' + food);
};
这样就生成了一个 Animal 类,实力化生成对象后,有方法和属性
(2)类的继承——原型链继承
function Cat(){ }
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.eat('fish'));
console.log(cat.sleep());
console.log(cat instanceof Animal); //true
console.log(cat instanceof Cat); //true
在这里我们可以看到 new 了一个空对象,这个空对象指向 Animal 并且 Cat.prototype指向了这个空对象,这种就是基于原型链的继承。
特点:基于原型链,既是父类的实例,也是子类的实例
缺点:无法实现多继承
(3)构造继承:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true
特点:可以实现多继承
缺点:只能继承父类实例的属性和方法,不能继承原型上的属性和方法。
(4)实例继承和拷贝继承
实例继承:为父类实例添加新特性,作为子类实例返回
拷贝继承:拷贝父类元素上的属性和方法
(5)es6的extend继承
49.如何解决异步回调地狱
promise、generator、async/await
50.说说前端中的事件流
HTML 中与 javascript 交互是通过事件驱动来实现的,例如鼠标点击事件 onclick、页面
的滚动事件 onscroll 等等,可以向文档或者文档中的元素添加事件侦听器来预订事件。
想要知道这些事件是在什么时候进行调用的,就需要了解一下“事件流”的概念。
什么是事件流:事件流描述的是从页面中接收事件的顺序,DOM2 级事件流包括下面几个
阶段。
事件捕获阶段
处于目标阶段
事件冒泡阶段
addEventListener:addEventListener 是 DOM2 级事件新增的指定事件处理程序的操作,
这个方法接收 3 个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。最
后这个布尔值参数如果是 true,表示在捕获阶段调用事件处理程序;如果是 false,表示
在冒泡阶段调用事件处理程序。
IE 只支持事件冒泡
51.如何让事件先冒泡后捕获
在 DOM 标准事件模型中,是先捕获后冒泡。但是如果要实现先冒泡后捕获的效果,对于同一个事件,监听捕获和冒泡,分别对应相应的处理函数,监听到捕获事件,先暂缓执行,直到冒泡事件被捕获后再执行捕获之间。
52.说一下事件委托
事件委托指的是,不在事件的发生地(直接 dom)上设置监听函数,而是在其父元素上设置监听函数,通过事件冒泡,父元素可以监听到子元素上事件的触发,通过判断事件发生元素 DOM 的类型,来做出不同的响应。
53.说一下图片的懒加载和预加载
预加载:提前加载图片,当用户需要查看时可直接从本地缓存中渲染。
懒加载:懒加载的主要目的是作为服务器前端的优化,减少请求数或延迟请求数。
54.JS 的 new 操作符做了哪些事情
new 操作符新建了一个空对象,这个对象原型指向构造函数的 prototype,执行构造函数后返回这个对象
55.改变函数内部 this 指针的指向函数(bind,apply,call 的区别)
通过 apply 和 call 改变函数的 this 指向,他们两个函数的第一个参数都是一样的表示要改变指向的那个对象,第二个参数,apply 是数组,而 call 则是 arg1,arg2...这种形式。通过 bind 改变 this 作用域会返回一个新的函数,这个函数不会马上执行。
56.JS 的各种位置,比如 clientHeight,scrollHeight,offsetHeight ,以及 scrollTop, offsetTop,clientTop 的区别?
clientHeight:表示的是可视区域的高度,不包含 border 和滚动条
offsetHeight:表示可视区域的高度,包含了 border 和滚动条
scrollHeight:表示了所有区域的高度,包含了因为滚动被隐藏的部分
clientTop:表示边框 border 的厚度,在未指定的情况下一般为 0
scrollTop:滚动后被隐藏的高度,获取对象相对于由 offsetParent 属性指定的父坐标(css定位的元素或 body 元素)距离顶端的高度。
57.JS 拖拽功能的实现
首先是三个事件,分别是 mousedown,mousemove,mouseup
当鼠标点击按下的时候,需要一个 tag 标识此时已经按下,可以执行 mousemove 里面的
具体方法。
clientX,clientY 标识的是鼠标的坐标,分别标识横坐标和纵坐标,并且我们用 offsetX
和 offsetY 来表示元素的元素的初始坐标,移动的举例应该是:
鼠标移动时候的坐标-鼠标按下去时候的坐标。
也就是说定位信息为:
鼠标移动时候的坐标-鼠标按下去时候的坐标+元素初始情况下的 offetLeft.
还有一点也是原理性的东西,也就是拖拽的同时是绝对定位,我们改变的是绝对定位条
件下的 left
以及 top 等等值。
补充:也可以通过 html5 的拖放(Drag 和 drop)来实现
58.异步加载 JS 的方法
defer:只支持 IE 如果您的脚本不会改变文档的内容,可将 defer 属性加入到<script>标签中,以便加快处理文档的速度。因为浏览器知道它将能够安全地读取文档的剩余部分而不用执行脚本,它将推迟对脚本的解释,直到文档已经显示给用户为止。
async,HTML5 属性仅适用于外部脚本,并且如果在 IE 中,同时存在 defer 和 async,那么 defer 的优先级比较高,脚本将在页面完成时执行。
创建 script 标签,插入到 DOM 中
59.Ajax 解决浏览器缓存问题
在 ajax 发送请求前加上 anyAjaxObj.setRequestHeader("If-Modified-Since","0")。
在 ajax 发送请求前加上 anyAjaxObj.setRequestHeader("Cache-Control","no-cache")。
在 URL 后面加上一个随机数: "fresh=" + Math.random()。
在 URL 后面加上时间搓:"nowtime=" + new Date().getTime()。
如果是使用 jQuery,直接这样就可以了 $.ajaxSetup({cache:false})。这样页面的所有 ajax
都会执行这条语句就是不需要保存缓存记录。
60.JS 的节流和防抖
防抖:不间断的点击只执行最后一次
节流:执行之后给予充分时间再执行下一次
61.JS 中的垃圾回收机制
必要性:由于字符串、对象和数组没有固定大小,所有当他们的大小已知时,才能对他们进行动态的存储分配。JavaScript 程序每次创建字符串、数组或对象时,解释器都必须分配内存来存储那个实体。只要像这样动态地分配了内存,最终都要释放这些内存以便他们能够被再用。
var a="hello world";
var b="world";
var a=b;
//这时,会释放掉"hello world",释放内存以便再引用
62.eval的作用
它的功能是将对应的字符串解析成 JS 并执行,应该避免使用 JS,因为非常消耗性能(2次,一次解析成 JS,一次执行)
63.如何理解前端模块化
前端模块化就是复杂的文件编程一个一个独立的模块,比如 JS 文件等等,分成独立的模块有利于重用(复用性)和维护(版本迭代),这样会引来模块之间相互依赖的问题,所以有了 commonJS 规范,AMD,CMD 规范等等,以及用于 JS 打包(编译等处理)的工具 webpack
64.说一下 CommonJS、AMD 和 CMD规范
CommonJS:开始于服务器端的模块化,同步定义的模块化,每个模块都是一个单独的作用域,模块输出,modules.exports,模块加载 require()引入模块。
AMD:中文名异步模块定义的意思。
requireJS 实现了 AMD 规范,主要用于解决下述两个问题。
1.多个文件有依赖关系,被依赖的文件需要早于依赖它的文件加载到浏览器
2.加载的时候浏览器会停止页面渲染,加载文件越多,页面失去响应的时间越长。
语法:requireJS 定义了一个函数 define,它是全局变量,用来定义模块。
CMD:相当于按需加载,定义一个模块的时候不需要立即制定依赖模块,在需要的时候require就可以了,比较方便;而AMD则相反,定义模块的时候需要制定依赖模块,并以形参的方式引入factory中。
65.将原生的 ajax 封装成 promise
var myNewAjax=function(url){
return new Promise(function(resolve,reject){
var xhr = new XMLHttpRequest();
xhr.open('get',url);
xhr.send(data);
xhr.onreadystatechange=function(){
if(xhr.status==200&&readyState==4){
var json=JSON.parse(xhr.responseText);
resolve(json)
}else if(xhr.readyState==4&&xhr.status!=200){
reject('error');
}
}
})
}
66.JS 监听对象属性的改变
//我们假设这里有一个 user 对象, (1)在 ES5 中可以通过 Object.defineProperty 来实现已有属性的监听
Object.defineProperty(user,'name',{
set:function(key,value){
}
})
//缺点:如果 id 不在 user 对象中,则不能监听 id 的变化
//(2)在 ES6 中可以通过 Proxy 来实现
var user = new Proxy({},{
set:function(target,key,value,receiver){
}
})
//这样即使有属性在 user 中不存在,通过 user.id 来定义也同样可以这样监听这个属性的
//变化哦。
67.如何实现一个私有变量,用 getName 方法可以访问,不能直接访问
//(1)通过 defineProperty 来实现
obj={
name:yuxiaoliang, getName:function(){
return this.name
}
}
object.defineProperty(obj,"name",{
//不可枚举不可配置
});
//(2)通过函数的创建形式
function product(){
var name='yuxiaoliang';
this.getName=function(){
return name;
}
}
var obj=new product();
68.setTimeout、setInterval 和 requestAnimationFrame 之间的区别
(1)requestAnimationFrame 会把每一帧中的所有 DOM 操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率。
(2) setTimeout多长时间之后执行
(3) setInterval 间隔执行。
69.JS 怎么控制一次加载一张图片,加载完后再加载下一张
// 方法一
<script type="text/javascript">
var obj=new Image();
obj.src="http://www.phpernote.com/uploadfiles/editor/201107240502201179.jpg";
obj.onload=function(){
alert('图片的宽度为:'+obj.width+';图片的高度为:'+obj.height);
document.getElementById("mypic").innnerHTML="<img src='"+this.src+"' />";
}
</script>
<div id="mypic">onloading……</div>
// 方法二
var obj=new Image();
obj.src="http://www.phpernote.com/uploadfiles/editor/201107240502201179.jpg";
obj.onreadystatechange=function(){
if(this.readyState=="complete"){
alert('图片的宽度为:'+obj.width+';图片的高度为:'+obj.height);
document.getElementById("mypic").innnerHTML="<img src='"+this.src+"' />";
}
}
</script>
<div id="mypic">onloading……</div>
69.如何实现 sleep 的效果(es5 或者 es6)
//(1)while 循环的方式
function sleep(ms){
var start=Date.now(),expire=start+ms;
while(Date.now()<expire);
console.log('1111');
return;
}
//执行 sleep(1000)之后,休眠了 1000ms 之后输出了 1111。上述循环的方式缺点很明显,
//容易造成死循环。
//(2)通过 promise 来实现
function sleep(ms){
var temple=new Promise(
(resolve)=>{
console.log(111);setTimeout(resolve,ms)
});
return temple
}
sleep(500).then(function(){
//console.log(222)
})
//先输出了 111,延迟 500ms 后输出 222
//(3)通过 async 封装
function sleep(ms){
return new Promise((resolve)=>setTimeout(resolve,ms));
}
async function test(){
var temple=await sleep(1000);
console.log(1111)
return temple
}
test();
//延迟 1000ms 输出了 1111
//(4).通过 generate 来实现
function* sleep(ms){
yield new Promise(function(resolve,reject){
console.log(111);
setTimeout(resolve,ms);
})
}
sleep(500).next().value.then(function(){console.log(2222)})
70.简单的实现一个 promise
new Promise((resolve, reject) => {
if(true){
resolve()
}else{
reject()
}
})
71.JS 判断类型
判断方法:typeof(),instanceof,Object.prototype.toString.call()等
72.数组常用方法
push(),pop(),shift(),unshift(),splice(),sort(),reverse(),map()等
73.数组去重
法一:indexOf 循环去重
法二:ES6 Set 去重;Array.from(new Set(array))
74.性能优化
减少 HTTP 请求
使用内容发布网络(CDN)
添加本地缓存
压缩资源文件
将 CSS 样式表放在顶部,把 javascript 放在底部(浏览器的运行机制决定)
避免使用 CSS 表达式
减少 DNS 查询
使用外部 javascript 和 CSS
避免重定向
图片 lazyLoad
75.如何判断一个数组(讲到 typeof 差点掉坑里)
instanceof
76.JS 实现跨域
JSONP:通过动态创建 script,再请求一个带参网址实现跨域通信。
CORS:服务端设置 Access-Control-Allow-Origin 即可,前端无须设置,若要带 cookie 请求,前后端都需要设置。
代理跨域:启一个代理服务器。
77.跨域的原理
跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对 JavaScript 实施的安全限制,那么只要协议、域名、端口有任何一个不同,都被当作是不同的域。跨域原理,即是通过各种方式,避开浏览器的安全限制。
78.简历中提到了 requestAnimationFrame,请问是怎么使用的
requestAnimationFrame() 方法告诉浏览器您希望执行动画并请求浏览器在下一次重绘之前调用指定的函数来更新动画。该方法使用一个回调函数作为参数,这个回调函数会在浏览器重绘之前调用。
79.什么是按需加载
当用户触发了动作时才加载对应的功能。触发的动作,是要看具体的业务场景而言,包括但不限于以下几个情况:鼠标点击、输入文字、拉动滚动条,鼠标移动、窗口大小更改等。加载的文件,可以是 JS、图片、CSS、HTML 等
80.说一下什么是 virtual dom
Virtual DOM 本质上就是在 JS 和 DOM 之间做了一个缓存。
81.webpack 用来干什么的
webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当
webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包
含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
82.VUE的生命周期
Vue 实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、销毁等一系列过程,我们称这是 Vue 的生命周期。通俗说就是 Vue 实例从创建到销毁的过程,就是生命周期。
实例、组件通过 new Vue() 创建出来之后会初始化事件和生命周期,然后就会执行
beforeCreate 钩子函数,这个时候,数据还没有挂载呢,只是一个空壳,无法访问到数据
和真实的 dom,一般不做操作
挂载数据,绑定事件等等,然后执行 created 函数,这个时候已经可以使用到数据,也
可以更改数据,在这里更改数据不会触发 updated 函数,在这里可以在渲染前倒数第二次
更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取
接下来开始找实例或者组件对应的模板,编译模板为虚拟 dom 放入到 render 函数中准备
渲染,然后执行 beforeMount 钩子函数,在这个函数中虚拟 dom 已经创建完成,马上就
要渲染,在这里也可以更改数据,不会触发 updated,在这里可以在渲染前最后一次更改
数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取
接下来开始 render,渲染出真实 dom,然后执行 mounted 钩子函数,此时,组件已经出
现在页面中,数据、真实 dom 都已经处理好了,事件都已经挂载好了,可以在这里操作
真实 dom 等事情...
当组件或实例的数据更改之后,会立即执行 beforeUpdate,然后 Vue 的虚拟 dom 机制会
重新构建虚拟 dom 与上一次的虚拟 dom 树利用 diff 算法进行对比之后重新渲染,一般不
做什么事儿
当更新完成后,执行 updated,数据已经更改完成,dom 也重新 render 完成,可以操作
更新后的虚拟 dom
当经过某种途径调用$destroy 方法后,立即执行 beforeDestroy,一般在这里做一些善后工
作,例如清除计时器、清除非指令绑定的事件等等
组件的数据绑定、监听...去掉后只剩下 dom 空壳,这个时候,执行 destroyed,在这里做
善后工作也可以。
总结:组件通过 new Vue() 创建。然后执行beforeCreate()然后挂载数据绑定事件,create()可以操作数据和事件,然后beforemounted虚拟化dom,然后mounted()加载dom,然后执行beforeUpdate上一次的虚拟 dom 树利用 diff 算法进行对比之后重新渲染。然后update更新完数据dom也render完成即执行 beforeDestroy,一般在这里做一些善后工作,例如清除计时器、清除非指令绑定的事件等等组件的数据绑定、监听...去掉后只剩下 dom 空壳,这个时候,执行 destroyed
83.简单介绍一下 symbol
Symbol 是 ES6 的新增属性,代表用给定名称作为唯一标识,这种类型的值可以这样创
建,let id=symbol(“id”)
84.介绍一下 promise,及其底层如何实现
Promise 是一个对象,保存着未来将要结束的事件,她有两个特征。
1、对象的状态不受外部影响,Promise 对象代表一个异步操作,有三种状态,pending进行中,fulfilled 已成功,rejected 已失败,只有异步操作的结果,才可以决定当前是哪一种状态,任何其他操作都无法改变这个状态,这也就是 promise 名字的由来
85.JS 原型链,原型链的顶端是什么?Object 的原型是什么?Object 的原型的原型是什么?在数组原型链上实现删除数组重复数据的方法
首先明白原型是什么,在 ES6 之前,JS 没有类和继承的概念,JS 是通过原型来实现继
承的,在 JS 中一个构造函数默认带有一个 prototype 属性,这个的属性值是一个对象,
同时这个 prototype 对象自带有一个 constructor 属性,这个属性指向这个构造函数,同时
每一个实例都会有一个proto属性指向这个 prototype 对象,我们可以把这个叫做隐式原
型,我们在使用一个实例的方法的时候,会先检查这个实例中是否有这个方法,没有的
话就会检查这个 prototype 对象是否有这个方法,
基于这个规则,如果让原型对象指向另一个类型的实例,即
constructor1.protoytpe=instance2,这时候如果试图引用 constructor1 构造的实例 instance1
的某个属性 p1,
首先会在 instance1 内部属性中找一遍,接着会在 instance1.proto(constructor1.prototype)即是 instance2 中寻找 p1
搜寻轨迹:instance1->instance2->constructor2.prototype……->Object.prototype;这即是原
型链,原型链顶端是 Object.prototype
86.let,const,var 的区别 ,什么是块级作用域,如何用 ES5 的方法实现块级作用域(立即执行函数)
var 声明的变量是全局或者整个函数块的,而 let,const 声明的变量是块级的变量,var 声明的变量存在变量提升,let,const 不存在,let 声明的变量允许重新赋值,const 不允许。
var可以在for循环中使用,let和const不行。var在之前打印为undefined,let会报错。
87.ES6 箭头函数的特性
1、箭头函数没有 this,所以需要通过查找作用域链来确定 this 的值,这就意味着如果箭
头函数被非箭头函数包含,this 绑定的就是最近一层非箭头函数的 this,
2、箭头函数没有自己的 arguments 对象,但是可以访问外围函数的 arguments 对象
3、不能通过 new 关键字调用,同样也没有 new.target 值和原型
88.setTimeout(fn,100);100 毫秒是如何权衡的
setTimeout()函数只是将事件插入了任务列表,必须等到当前代码执行完,主线程才会去执行它指定的回调函数,有可能要等很久,所以没有办法保证回调函数一定会在setTimeout 指定的时间内执行,100 毫秒是插入队列的时间+等待的时间
总结:setTimeout是线程结束完成再去调用
89.怎么获得对象上的属性:比如说通过 Object.key()
for(let I in obj)该方法依次访问一个对象及其原型链中所有可枚举的类型
object.keys:返回一个数组,包括所有可枚举的属性名称
object.getOwnPropertyNames:返回一个数组包含不可枚举的属性
90.简单讲一讲 ES6 的一些新特性
ES6 在变量的声明和定义方面增加了 let、const 声明变量,有局部变量的概念,赋值中有比较吸引人的结构赋值,同时 ES6 对字符串、 数组、正则、对象、函数等拓展了一些方法,如字符串方面的模板字符串、函数方面的默认参数、对象方面属性的简洁表达方式,ES6 也 引入了新的数据类型 symbol,新的数据结构 set 和 map,symbol 可以通过typeof 检测出来,为解决异步回调问题,引入了 promise 和 generator,还有最为吸引人了实现 Class 和模块,通过 Class 可以更好的面向对象编程,使用模块加载方便模块化编程,当然考虑到 浏览器兼容性,我们在实际开发中需要使用 babel 进行编译
重要的特性:
块级作用域:ES5 只有全局作用域和函数作用域,块级作用域的好处是不再需要立即执
行的函数表达式,循环体中的闭包不再有问题
rest 参数:用于获取函数的多余参数,这样就不需要使用 arguments 对象了,
promise:一种异步编程的解决方案,比传统的解决方案回调函数和事件更合理强大
模块化:其模块功能主要有两个命令构成,export 和 import,export 命令用于规定模块的
对外接口,import 命令用于输入其他模块提供的功能
91.JS 对象类型,基本对象类型以及引用对象类型的区别
基本数据类型有这六种:undefined、null、string、number、boolean、symbol。
引用类型有这几种:Object、Array、RegExp、Date、Function
基本包装类型(String、Number、Boolean)
92.arguments
arguments 是类数组对象,有 length 属性,不能调用数组方法
可用 Array.from()转换
93. 写出原生 Ajax
var xhr = new XMLHttpRequest();
xhr.open('get', 'aabb.php', true);
xhr.send(null);
xhr.onreadystatechange = function() {
if(xhr.readyState==4) {
if(xhr.status==200) {
console.log(xhr.responseText);
}
}
}
94.防止手机中页面放大和缩小
95.手机上下拉动滚动条时卡顿、慢
body{
overflow-scolling:touch;
}
96.长时间按住页面出现闪退
element{
touch-callout:none
}
浙公网安备 33010602011771号