作为一名刚刚毕业,正在开始前端工作的小白,也是经历了校招的种种,这里附上自己总结的一份前端面试题,当然有部分内容也是借鉴网上大牛的博客,我做了个整合,若总结有误,欢迎批评指出哦~
1.由盒模型引申出border-box:
box-sizing:border-box|content-box(此为标准盒子)
border-box:padding和border均计算在width、height中
content-box:padding和border不计算在width、height中
下面用一个例子给出盒子模型的宽度计算:
例如:
如果用w3c盒子模型解释,那么这个盒子模型占用的
宽度: 20*2+10*2+10*2+200=280px
高度: 20*2+10*2+10*2+50=130px
盒子实际的宽度:10*2+10*2+200=240px
盒子实际的高度:10*2+10*2+50=90px
而用ie的盒子模型解释
盒子在网页中占据的大小是
宽度: 20*2+200=240px
高度: 20*2+50=90px
盒子实际的宽度:200px
盒子实际的高度:50px
所以w3c为了解决这个问题,就在css3中加了box-sizing属性,当设为border-box时,padding和border就都被包含在了盒子的宽高中。
2.三栏式布局:
a.绝对定位法:
左右通过absolute,top,right,left进行绝对定位,中间元素用margin撑开,因为块级元素默认宽度为auto,充满整行。
附:行内元素不能设置高宽,其大小为内容大小,但可以设置margin
b.设置浮动
一个左浮动,一个右浮动,main的div放在最后,用margin撑开。
c.flex布局
3.offsetTop、offsetHeight、clientHeight等的一些区别
offsetHeight=height+padding+border+(滚动条)
clientHeight是对象看到的高度(不含border)
scrollTop:网页被卷进去的高度
1) style.width返回值除了数字外还带有单位px;
2) 如对象的宽度设定值为百分比宽度,则无论页面变大还是变小, style.width都返回此百分比,而offsetWidth则返回在不同页面中对象的宽度值而不是百分比值;
3) 如果没有给 HTML 元素指定过 width样式,则 style.width 返回的是空字符串;
只有在元素上设置,才能获取a.style.height为200px;
4.垂直居中对齐
02:
03:
04:
transition:过渡动画
transform:转换动画 skew(20deg)
5.border-width只能设置整数值,如何实现border-width的值为0.5px
在div后面加一个内容,设置其渐变的样式:0deg表示从下往上,50%表示color-stop,区间内为变化的状态,这里0-50%是透明,50%-100%是红色。
附:
这样的方式可以实现间隔颜色不渐变显示:
从中间到两边:
background: linear-gradient(to left,red,yellow,red);
to left表示渐变的方向和起点。
实现斜向渐变:
background: linear-gradient(45deg,red,yellow);
6.css3的动画:点击按钮时底部弹框从下弹出(即从无到有的过程)
效果图:
html:
css:
刚进入页面时展示的是id为new1的div,从底部向上弹出,我们可以设置position为absolute,bottom为0。设置动画,高度的变化实现动画效果。
:target选择器可用于选取当前活动的目标元素。
URL中有锚名称#,指向文档内某个具体的元素。比如我点击超链接“收缩”,锚名称为#new1,指向id为new1的元素,即该元素为目标元素。
点击收缩的时候,锚为new1,此时触发#new1:target这部分的样式,实现收缩;点击展开时,#new1:target的样式失效,#new1的样式重新展现,也就出现了展开的动画。
7.ul中有若干li,如何实现点击一个li弹出相应的文本内容
方法1(事件委托):
方法2(闭包):
8.如何理解冒泡,冒泡和事件委托的区别是什么?
所谓的事件冒泡就是子级元素的某个元素被触发,它的上级元素的该事件也被递归执行。
事件委托使用了冒泡的原理,从点击的元素开始,以递归方式向父元素传递时间,这样做的好处是对于大量要处理的元素,不必为每个元素都绑定,只需要在他们的父元素上绑定一次即可,能够提高性能。
jquery中事件绑定优先使用on,on(事件类型,[子选择器],事件处理函数)
如果子选择器不存在,那么这个就是个直接事件
当指定了子选择器后,这就变成了事件委托,他有一个优势,能够在后代元素添加到dom后处理这些事件,即能够实现动态的事件绑定,开销更小。用off来删除on的绑定事件。
9.click和touch的区别
在移动端,手指点击一个元素,会经过:touchstart --> touchmove -> touchend -->click。因此,click时间会有一定的延迟
10.简述一下输入url到内容渲染的整个过程(DNS寻址的过程是什么)
a.首先在浏览器的地址栏中输入url地址
b.浏览器先查看浏览器缓存-系统缓存-路由器缓存,如果缓存中有,会直接在屏幕中显示页面内容。若缓存中没有,则调到下面一步。
c.在发送http请求之前,需要域名解析(DNS解析),解析获取相应的ip地址。
d.浏览器向服务器发起tcp连接,与浏览器建立tcp三次握手。
e.握手成功后,浏览器向服务器发送http请求,请求数据包。
f.服务器处理收到的请求,将数据返回至浏览器。
g.浏览器收到http响应
h.读取页面内容,浏览器渲染,解析html源码
j.生成Dom树,解析css样式文件、js交互文件
k.客户端与浏览器交互
l.ajax查询
11.http中301,302,304各代表什么?地址转义的时间如何设置(在请求头部添加字段)
301和302状态码都表示重定向,就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,这个地址可以从响应的Location首部中获取(用户看到的效果就是他输入的地址A瞬间变成了另一个地址B)——这是它们的共同点。他们的不同在于:301表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址;302表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址。301:永久性转移
302:暂时性转移
304:地址没有被修改,仍可以用浏览器缓存
12.async和defer的区别
<script src="file.js" defer="defer"></script>
<script src="file.js" async="async"></script>
这两个属性不应该用在内联脚本上。
defer表明<script>元素中包含的js代码不会修改DOM结构,因此此段代码可以延迟执行。设置了该属性后浏览器会以并行的方式下载脚本,而不是以阻塞的方式下载。
async:浏览器会以异步的方式下载js代码,并在下载完成之后立即执行,不会等待页面解析结束。
两个属性的差别是:设置async之后不能保证脚本按照原来的顺序加载和执行,脚本加载完成之后就会立即执行。因此,如果脚本之间有依赖的话就不能使用async属性,如果页面中有内联的脚本依赖于加载的脚本,则不适合使用defer属性。
13.前端性能优化(说到减少http请求,如何减少)
1、图片、代码进行压缩
2、使用精灵图,图像精灵是放入一张单独的图片中的一系列图像。包含大量图像的网页需要更长时间来下载,同时会生成多个服务器请求。使用图像精灵将减少服务器请求数量并节约带宽。
3、两个js合并到一个js中,减少http请求。
4、样式表放在头部,脚本文件放在尾部
5、图片懒加载(lazyload)
用的是lazyload.js的插件
6、减少dom操作(可以使用事件委托,对于要大量处理的元素,不必为每个元素都绑定,只需要在他们的父元素上绑定一次即可,能够提高性能)
在《高性能JavaScript》中这么比喻:“把DOM看成一个岛屿,把JavaScript(ECMAScript)看成另一个岛屿,两者之间以一座收费桥连接”。所以每次访问DOM都会教一个过桥费,而访问的次数越多,交的费用也就越多。所以一般建议尽量减少过桥次数。
7、图片预加载:
做过图片翻转效果的朋友其实都知道,要让图片轮换的时候不出现等待,最好是先让图片下载到本地,让浏览器缓存起来。这时,一般都会用到js里边的Image对象
通过调用preLoadImg函数,传入图片的url,就能使图片预先下载下来了。实际上,这里用到的预下载功能也和这基本一致。图片预下载下来后,通过 img的width和height属性,就能知道图片的宽和高了。需要用一些异步的方法,等到图片下载完毕的时候才会再对img的width和height进行调用。
14.闭包的问题(下面一段代码的输出内容是什么,如何修改能够输出0,1,2)
此时是输出2,2。setTimeout在任务队列的末尾
修改:
此时输出0,1
15.正则表达式(^和$分别表示匹配头部和尾部,那么一个字符串有多行时是每行结束都会$匹配吗)
开启多行匹配时,^和$会匹配每行,关闭多行匹配时则只会匹配字符串
/m:开启多行匹配 multiple
/s:singleline
16.jquery中$有哪些作用,选择器中>、~、+的作用是什么,如何选中div的兄弟节点中的所有span标签
$("div span"):选取<div>里的所有<span>元素
$("div >span"):选取<div>元素下元素名为<span>的子元素
$("#one + div"):选取id为one的元素的下一个<div>同辈元素,等同于$("#one").next("div")。
$("#one ~ div"):选取id为one的元素的后面的所有<div>同辈元素,等同于$("#one").nextAll("div")。
$("#one").siblings("div"):获取id为one的元素的所有<div>同辈元素(不管前后)
$("#one").prev("div"):获取id为one的元素的前面紧邻的同辈<div>元素
如何选中div的兄弟节点中的所有span标签:
$("#one").siblings("span")
17.vue中数据双向绑定是用v-model实现的,那么他的底层源码实现逻辑是什么
vue中的数据双向绑定主要是通过数据劫持来实现的。说白了就是通过Object.defineProperty()来劫持对象属性中的setter和getter操作,在数据变动时做你想做的事情。
18.原生ajax
19.实现console.log(fn(1)(2)(3))输出6
拓展:如果有(1)(2)(3)(4)(5)(6).......如何实现
reduce的用法:Array的reduce()把一个函数作用在这个Array的[x1, x2, x3...]上,这个函数必须接收两个参数,reduce()把结果继续和序列的下一个元素做累积计算,其效果就是:
[x1, x2, x3, x4].reduce(f) = f(f(f(x1, x2), x3), x4)
注:[].forEach.call()等价于Array.prototype.forEach.call()