HTML篇
1、H5新增标签有哪些?
一、语义化标签
header、footer、nav、aside、section、article
语义化的意义?
1、更适合搜索引擎的爬虫爬取有效的信息,利于SEO。
2、对开发团队很友好,增加了标签的可读性,结构更加的清晰,便于团队的开发和维护。
二、多媒体标签
视频标签:video
属性:src、 Poster(加载等待画面的图片)、muted(静音)
音频标签: audio
属性:src、loop、controls(调出当前控件)
三、表单元素、控件
输入框input中新增 type,类型可为、email、url、data、number等
required、placeholder
2、src和href的区别
src和href都是对外部资源的引用,区别如下:
src: 表示对资源的引用,用在js脚本、img、frame等元素上,当浏览器解析到该元素时,会暂停其他资源的下载和处理,直到该资源加载、编译、执行完成,所以js脚本会放在页面的底部,而不是头部。
href:表示超文本引用,指向一些网络资源,当浏览器识别它指向的文件时,就会并行下载资源,不会停止对当前文件的处理,用在a、link上
3、defer和async
参考博文:
默认情况下,浏览器是同步加载js脚本的,即渲染引擎遇到 script标签就会停下来,等执行完脚本,再去继续向下渲染,如果是外部脚本,还必须加入脚本的下载时间。
加入脚本的很多而且体积很大的话,下载和 执行 就会占用很大的时间,照成浏览器堵塞,用户就会感觉卡死了,没有任何响应,体验极差,所以浏览器允许脚本的异步加载,方式如下:
关键字就是defer和async,脚本会异步加载。渲染引擎遇到这行命令就会开始下载外部的脚本,但是并不会等待其脚本下载完成和执行完成,而是直接执行后面的命令。
defer和async的区别:
defer:需要等待整个页面正常DOM渲染完成后,才会执行下载好的js脚本,并且是按下载完后的顺序执行。
async:当外部的js脚本下载完成后,渲染引擎会暂停DOM渲染,开始执行下载好的JS脚本的内容,在执行完成后,再去渲染。
简单的说:
defer是需要等DOM元素都渲染完成后,才去执行下载完成的js脚本
async是当js脚本下载完成后,开始执行的时候中断DOM渲染,执行js脚本的内容,执行完成再去渲染DOM元素
没有defer或async属性,浏览器会立即下载并执行相应的脚本,并且在下载和执行时页面的处理会停止。可能形成页面堵塞
不用异步加载的话可以把外部引入的脚本放在前即可
4、行内元素与块级元素
块级元素: 独占一行,可以设置宽高,设置margin和padding都有效,代表如下:
div、p、h1…h6、table、tr、ol、li、ul
行内元素元素: 可以排成一行,设置宽高无效,对margin设置左右方向有效,而上下无效,padding设置都无效,代表如下:
基本上都是文本标签
span、img、b、strong、font、br、a
5、title与h1、b与strong、i与em的区别
Strong表示的是重点内容,有语气加强的含义,,会重读,而展示强调的内容
b只是展示强调的内容
title属性没有明确意义只表示是个标题,H1则表示层次明确的标题,对页面信息的抓取也有很大的影响
i内容展示为斜体,em表示强调的文本
6、回流(重拍)与重绘
先了解下HTML文文件渲染的过程
image-20220106163008328
都发生在渲染DOM树(Render Tree)后的过程中,其中Layout是回流,Painting是重绘
回流:浏览器中进行布局的过程就是回流
重绘:浏览器进行 渲染就是重绘
触发回流的一些条件:
1、添加或者删除可见的DOM元素;
2、元素位置改变;
3、元素尺寸改变——边距、填充、边框、宽度和高度
4、内容改变——比如文本改变或者图片大小改变而引起的计算值宽度和高度改变;
5、页面渲染初始化;
6、浏览器窗口尺寸改变——resize事件发生时;
image-20220106163705728
触发重绘的一些条件:
1、改变背景色
2、改变透明度
简单的说,就是不影响布局的情况下,改变的就是重绘
image-20220106164151661
性能优化方法:
减少浏览器的回流行为达到性能优化。
1、用transform代替位移
2、用visibility:hidden透明度代替display:none
3、使用display:none技术,只引发两次回流和重绘;
4、使用cloneNode(true or false)和replaceChild技术,引发一次回流和重绘;
5、让元素脱离动画流,减少回流的Render tree的规模;
7、cookie、localStorage 和 sessionStorage的区别及应用实例
详解cookie
简单的理解是因为http协议的无状态性,所以需要cookie去把特别的信息保存下来,当然保存的是在浏览器中,下面简单的讲解下逻辑
1、浏览器向服务器发送请求,传输一些信息
2、服务器收到请求,在响应体中通过set-cookie返回字段,保存在浏览器中。
3、浏览器再次发送请求时会携带cookie,根据服务器中对比,做一个判断。
在前端的js代码中通过:
去设置cookie,其中cookie带有如下属性
max-age/expires:可设置cookie的有效时间,其中expires必须时GMT的时间格式,可用new Date().toGMTString()去对时间进行转换。在没有设置时间时,cookie会随着浏览器的关闭,而被删除
domain:可设置访问该cookie的域名
path:可设置访问此cookie的页面路径
Size:设置cookie的大小
http:cookie的httponly属性,如果为true。则只有在http请求头中会有此cookie的信息,而不能通过document.cookie来进行访问
删除cookie
只需要把cookie的有效时间设置为当前日期的前任何时间即可
下面是列子:
localStorage 和sessionStorage
前面得cookie作为一个存储手段进行举例,但是在H5中新增了两种存储方式,其中使用方法如下:
localStorage.key() :拿到指定key得值
localStorage.setItem('名','值'):设置相关的储存值
localStorage.getItem('名'):取出对应名的值
localStorage.removeItem('名'):移除掉相关的值
sessionStorage使用的方法和localStorage一致。
三者的区别
cookie具有时效性,可以手动的去设置需要保存的时间,内存大小大概为4KB,内容保存在客户端上,删除的话把过期时间设置为前一天即可。
localStorage,除非手动去删除,不然一直会保存,内存大小为5MB
sessionStorage,临时会话保存,相关页面关闭掉就自动删除,内容大小为5MB
建议理解三者的基本使用再去理解这面试题,因为工作中也能用到
8、同源策略与跨域问题
什么是同源策略?
借用阮一峰老师的描述:
image-20220205201415594
简单地说就是为了网页之间的安全性,但是在平常的工作中,我们会遇到别的资源请求问题,也就是跨域问,下面给出几种常见的跨域解决问题的方案
跨域解决方案
参考B站技术蛋老师的讲解
1、JSONP
json with padding,也就是JSON的填充方法。在服务器与客户端之间的格式我们常用的是JSON格式。
我们用script标签获取数据,其中的数据会被执行,所以我们一般会给数据外包一个js函数,然后再外包一层作为传输用的json格式。
我们知道通过script标签请求的资源中,并不会受到同源策略的限制,而jsonp方法就是通过这个方式去实现别的资源共享,简单原理如下:
原理可分为 客户端与服务器
客户端:客户端上去写一个函数,专门用来处理跨域获取服务器JSON数据的方法,在传入的url上写额外的参数,传到服务器,同时客户端收到服务器传过来的数据后,调用提前设定好的函数,执行服务器传过来的数据。
服务器:数据源是在服务器上存在的,而我们需要再然后服务器对额外的参数进行判断,把数据外包一个js函数,通过JSON的方式传给客户端。
image-20220205203014701
image-20220205203255464
2、CORS
当浏览器向服务器发起请求的时候,会在请求头中添加origin(协议+主机+端口),也就是表明自己的协议+主机+端口,当服务器接收到这个origin的时候,就得添加头部Access-Control-Allow-Origin到响应里面,浏览器看到服务器传回来的Access-Control-Allow-Origin,就可以进行判断是否进行跨域请求
image-20220205205058169
image-20220205205425242
核心其实就是设置Access-Control-Allow-Origin
9、检测数据类型的方法
1、typeof
typeof在检测null、object、array、data的结果中都是object,所以无法用来区分这几个类型的区别
image-20220223220519006
2、instanceof
缺点是只能检测该对象是否存在目标对象的原型上
[对象] instanceof [构造函数]
instanceof 用于判断对象类型,但以上情况的结果都为false,请注意。
instanceof 的原理
因为会一直往原型链上查找
L代表instanceof左边,R代表右边
3、constructor
constructor 不能判断null、undefind,因为他们不是构造对象
image-20220223221351705
4、Object.prototype.toString.call
可以检测出所有的数据类型
image-20220223222504029
在使用Array.prototype.toString.call的时候,遇到null、undefined会出现报错
10、阻止默认事件
在面试中我们会被问到事件冒泡、默认事件等概念,下面做一些简单的了解:
事件冒泡:
1.原理:元素自身的事件被触发后,如果父元素有相同的事件,如click事件,那么元素本身的触发状态就会传递,也就是冒到父元素,父元素的相同事件也会一级一级根据嵌套关系向外触发,直到document/window,冒泡过程结束。
2.使用范围:冒泡事件只是针对于click相关的事件,还有click的分支事件:mouseup、mousedown
默认事件:
比如点击a标签会默认打开、input提交表单按钮,都是默认事件
阻止默认事件但是不阻止事件冒泡
event.preventDefault()
阻止事件冒泡阻止默认事件
event.stopPropagation();
在jquery中阻止事件冒泡和默认行为,在原生js中只阻止事件冒泡
return false
11、文档流,文本流清除浮动
文档流:
我理解的是页面中的块级元素等DOM元素按照默认的方式去进行排列
文本流:
网页页面上的一些文字的排列
清除浮动的方法及原理:
原理:其实就是让目标元素脱离文档流即可,手段有float:left、position中的绝对定位和固定定位等
方法:
1、用伪类去清除浮动
2、在浮动元素上添加一个空盒子,写上clear:both的样式
3、双伪类清除浮动
12、手写call、apply、bind
1、call
想要手写出就得知道它是怎么使用的,函数.call(绑定this指向,参数一,参数二,…)
image-20220225111457351
2、apply
apply和call的写法基本一至,就是二者接受的参数不同,面试apply的写法
函数.apply(this指向对象,[参数1,参数2,参数3…])
image-20220227125422710
3、bind
bind与前两个的区别如下
1、bind返回的是一个函数
2、如果是new出来的 ,返回一个空对象,且使创建出来的实例的__proto__指向_this的prototype,且完成函数柯里化
image-20220227151331533
13、new的过程中发生了什么
其实new的过程中就是this指向改变、新创建一个实列的过程,如下
14、js的继承方式
1、原型链继承
关键点就是: 继承函数.prototype =new 被继承函数
缺点:
1、继承单一
2、子类无法向父类的构造函数传参
3、所有新实列都会共享父类实列的属性(原型上的属性也是共享的,一个实列修改了原型属性,另一个也会被修改)
2、原型继承
image-20220228112350530
缺点:子类实列共享了父类构造函数的引用属性,不能传参
3、构造函数继承
重点:借用.call()和.apply()将父类构造函数引入子类函数(在子类函数中做了父类函数的自执行)
优点:1、可以继承多个构造函数属性
2、在子实列中可以向父实列传参
缺点:1、只能继承父实列的构造函数属性
2、每新实列都会有父类构造函数的副本,臃肿
4、组合继承
重点:结合了两种模式的优点,传参和复用 特点:1、可以继承父类原型上的属性,可以传参,可复用。 2、每个新实例引入的构造函数属性是私有的。 缺点:调用了两次父类构造函数(耗内存),子类的构造函数会代替原型上的那个父类构造函数。
5、寄生组合继承
优点
只调用了一次父类构造函数,只创建了一份父类属性 子类可以用到父类原型链上的属性和方法 6、extends继承
ES6出来的
子类只要继承父类,可以不写 constructor ,一旦写了,则在 constructor 中的第一句话必须是 super 。