认真对待每一道面试题
CSS部分
CSS中 link 和@import 的区别是?
link属于HTML标签,而@import是CSS提供的,页面被加载的时,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载
import只在IE5以上才能识别,而link是HTML标签,无兼容问题
link方式的样式的权重 高于@import的权重.
css3实现三栏布局,左右固定,中间自适应
圣杯布局/双飞翼布局
如何修改Chrome记住密码后自动填充表单的黄色背景?
产生原因:由于Chrome默认会给自动填充的input表单加上 input:-webkit-autofill 私有属性造成的
解决方案1:在form标签上直接关闭了表单的自动填充:autocomplete="off"
解决方案2:input:-webkit-autofill { background-color: transparent; }
display:inline-block 什么时候会显示间隙?(携程)
产生原因:元素被当成行内元素排版的时候,元素之间的空白符(空格、回车换行等)都会被浏览器处理,根据white-space的处理方式(默认是normal,合并多余空白),原来HTML代码中的回车换行被转成一个空白符,在字体不为0的情况下,空白符占据一定宽度,所以inline-block的元素之间就出现了空隙。这些元素之间的间距会随着字体的大小而变化,当行内元素font-size:16px时,间距为8px。
解决方法:移除空格、使用margin负值、使用font-size:0、letter-spacing、word-spacing
li与li之间有看不见的空白间隔是什么原因引起的?有什么解决办法?
行框的排列会受到中间空白(回车\空格)等的影响,因为空格也属于字符,这些空白也会被应用样式,占据空间,所以会有间隔,把字符大小设为0,就没有空格了
用css分别实现某个DIV元素上下居中和左右居中。
方法一:
#one {
width: 100px;
height: 100px;
border: 4px solid red;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
方法二:
#one {
width: 100px;
height: 100px;
border: 4px solid red;
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
margin: auto;
}
方法三:
#one {
width: 100px;
height: 100px;
border: 4px solid red;
position: absolute;
left: 50%;
right: 50%;
margin-left: -50px;
margin-top: -50px;
}
用纯CSS创建一个三角形的原理是什么?
// 把上、左、右三条边隐藏掉(颜色设为 transparent) 默认值。边框颜色为透明
#demo {
width: 0;
height: 0;
border-width: 20px;
border-style: solid;
border-color: transparent transparent red transparent;
}
重绘(redraw)和重排(reflow)
重绘:是一个元素的外观变化所引发的浏览器行为;例如改变visibility、outline、背景色等属性。
重排:是引起DOM树重新计算的行为;又叫回流
很显然,每次重排,必然会导致重绘,那么,重排会在哪些情况下发生?
- 添加或者删除可见的DOM元素
- 元素位置改变
- 元素尺寸改变
- 元素内容改变(例如:一个文本被另一个不同尺寸的图片替代)
- 页面渲染初始化(这个无法避免)
- 浏览器窗口尺寸改变
这些都是显而易见的,或许你已经有过这样的体会,不间断地改变浏览器窗口大小,导致UI反应迟钝(某些低版本IE下甚至直接挂掉),现在你可能恍然大悟,没错,正是一次次的重排重绘导致的!
升华版:
dom树的结构变化 (添加、删除dom)
获取某些属性 offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight。也会引起回流。因为浏览器需要通过回流计算最新值
重排和重绘是DOM编程中耗能的主要原因之一,平时涉及DOM编程时可以参考以下几点:
- 尽量不要在布局信息改变时做查询(会导致渲染队列强制刷新)
- 同一个DOM的多个属性改变可以写在一起(减少DOM访问,同时把强制渲染队列刷新的风险降为0)
- 如果要批量添加DOM,可以先让元素脱离文档流,操作完后再带入文档流,这样只会触发一次重排(fragment元素的应用)
- 将需要多次重排的元素,position属性设为absolute或fixed,这样此元素就脱离了文档流,它的变化不会影响到其他元素。例如有动画效果的元素就最好设置为绝对定位。
参考:http://web.jobbole.com/83164/
https://blog.csdn.net/sinat_37328421/article/details/54575638
vh vw vmin vmax rem em
rem与em都是相对单位,我们使用它们的目的就是为了适应各种手机屏幕。
rem是根据html根节点来计算的,而em是继承父元素的字体。
响应式网页设计技术很大程度上依赖于比例规则。然而,CSS比例不总是每个问题的最佳解决方案。CSS宽度是相对于最近的包含父元素。如果你想使用显示窗口的宽度或高度而不是父元素的宽度将会怎么样?这正是vh和vw单位所提供的。
vh等于viewport高度的1/100.例如,如果浏览器的高是900px,1vh求得的值为9px。同理,如果显示窗口宽度为750px,1vw求得的值为7.5px。
vw:viewpoint width,视窗宽度,1vw等于视窗宽度的1%。
vh:viewpoint height,视窗高度,1vh等于视窗高度的1%。
vmin:vw和vh中较小的那个。
vmax:vw和vh中较大的那个。
实现一个div,左边固定div宽度200px,右边div自适应
三种方法实现
html:
<div class="container">
<div class="left">
left固定宽度200px
</div>
<div class="right">
可变宽度rightrightrightrightrightrightrightrightri
</div>
</div>
方式一:利用bfc
.left{
width:200px;
float:left;
background:red;
}
.right{
overflow:hidden;
background:blue;
}
右边盒子触发bfc,使其不与浮动盒子区域重叠,因此会重新计算宽度。
方式二:左浮动+margin-left
.left{
width:200px;
float:left;
border: 2px solid blue;
background:red;
}
.right{ 可以设置一个高度,div中有没有内容都能实现相应功能
border: 2px solid yellow;
margin-left:200px;
background:blue;
}
方式三:flex布局
.container{
display:flex;/*设为伸缩容器*/
}
.left{
width:200px;
border: 2px solid blue;
background:red;
}
.right{
border: 2px solid yellow;
flex:1;/*这里设置为占比1,填充满剩余空间,如果左右div都有这个属性,则两者宽度平分*/
background:blue;
}
盒子模型
其实盒子模型有两种,分别是 ie 盒子模型和标准 w3c 盒子模型。他们对盒子模型的解释各不相同,先来看看我们熟知的标准盒子模型:
标准 W3C 盒子模型的范围包括 margin、border、padding、content,并且 content 部分不包含其他部分。
IE 盒子模型的范围也包括 margin、border、padding、content,和标准 W3C 盒子模型不同的是:IE 盒子模型的 content 部分包含了 border 和 pading。
例如一个盒子模型如下:margin:20px,border:10px,padding:10px;width:200px;height:50px;
如果用w3c盒子模型解释,那么这个盒子需要占据的位置为
宽度为:202+102+102+200=280px;
高度:202+102+202+50=130px;
盒子的实际宽度大小为:102+102+200=240px;
实际高度:102+102+50=90px;
用ie的盒子模型解释 :盒子在网页中占据的大小为202+200=240px; 高:202+50=90px;
盒子的实际大小为:宽度:200px, 高度:50px;
我们常常理解的盒子模型是w3c这样的盒子模型
加分项回答
1.对于行级元素,margin-top和margin-bottom对于上下元素无效,margin-left和margin-right有效
2.对于相邻的块级元素margin-bottom和margin-top 取值方式
1) 都是正数: 取最大值
距离=Math.max(margin-botton,margin-top)
2) 都是负数: 取最小值
距离=Math.min(margin-botton,margin-top)
3)上面是正数,下面是负数或者 上面是负数,下面是正数: 正负相加
距离=margin-botton+margin-top
参考:https://www.jianshu.com/p/e2eb0d8c9de6
我个人认为W3C定义盒子模型与IE定义的盒子模型,IE定义的比较合理,元素的宽度应该包含border(边框)和padding(填充),这个和我们现实生活的盒子是一样的,W3C也认识到自己的问题了,所以在CSS3中新增了一个样式box-sizing,包含两个属性content-box 和 border-box。
box-sizing常用属性有哪些,分别是什么
content-box
这是由 CSS2.1 规定的宽度高度行为。宽度和高度分别应用到元素的内容框。在宽度和高度之外绘制元素的内边距和边框。
border-box
为元素设定的宽度和高度决定了元素的边框盒。就是说,为元素指定的任何内边距和边框都将在已设定的宽度和高度内进行绘制。通过从已设定的宽度和高度分别减去边框和内边距才能得到内容的宽度和高度。
inherit
规定应从父元素继承 box-sizing 属性的值。
左固定,右自适应的布局
方法一:左边设置左浮动,右边宽度设置100%
.left{
float: left;
}
.right{
width: 100%;
}
【分析】这样的方式简单得让我怀疑,但是效果上确实是实现了。
方法二: 父容器设置 display:flex;Right部分设置 flex:1
body{
display: flex;
}
.right{
flex: 1;
}
【分析】display:flex; 设置为弹性盒子,其子元素可以通过设置 flex 的数值来控制所占空间的比例。
方法三:设置浮动 + 在 css 中使用 calc() 函数
.left{
float: left;
}
.right{
float: left;
width: calc( 100vw - 200px);
}
【分析】
1. 浮动。(注意:为了不影响其他元素,别忘了在父级上清除浮动)
calc() = calc(四则运算) 用于在 css 中动态计算长度值,需要注意的是,运算符前后都需要保留一个空格,例如:width: calc(100% - 10px);
vw: viewport width。1vw = viewport 宽度的 1%, 100vw = viewport width,
同样的还有 vh: viewport height。1vw = viewport 高度的 1%, 100vh = viewport height。
浏览器支持情况: 主流浏览器、IE10+
vw 和 vh 会随着viewport 的变化而变化,因此十分适合于自适应场景来使用。
css3实现三栏布局,左右固定,中间自适应(圣杯布局/双飞翼布局)
<style>
* {
margin: 0;
padding: 0;
}
.middle,
.left,
.right {
position: relative;
float: left;
min-height: 130px;
}
.container {
padding: 0 220px 0 200px;
overflow: hidden;
}
.left {
margin-left: -100%;
left: -200px;
width: 200px;
background: red;
}
.right {
margin-left: -220px;
right: -220px;
width: 220px;
background: green;
}
.middle {
width: 100%;
background: blue;
word-break: break-all;
}
</style>
</head>
<body>
<div class='container'>
<div class='middle'></div>
<div class='left'></div>
<div class='right'></div>
</div>
</body>
CSS居中
transform:translate(-50%,-50%)实现水平垂直居中
.content {
padding:10px;
background:green;
color:#fff;
position:absolute;
top:50%;
left:50%;
border-radius: 5px;
-webkit-transform: translate(-50%,-50%);
-moz-transform: translate(-50%,-50%);
transform:translate(-50%,-50%);
}
当使用:top: 50%;left: 50%;, 是以左上角为原点,故不处于中心位置,
translate(-50%,-50%) 作用是,往上(x轴),左(y轴)移动自身长宽的 50%,以使其居于中心位置。与负margin-left和margin-top实现居中不同的是,
margin-left必须知道自身的宽高(负自身已知宽高的一半),而translate可以在不知道宽高的情况下进行居中,tranlate()函数中的百分比是相对于自身宽高的百分比,所以能进行居中。
JS中常见的异步任务
定时器、ajax、事件绑定、回调函数、async await、promise
defer和async的区别
大概说下实现无缝轮播的思路?
说出以下代码的执行结果
var a = 10;
var obj = {
a: 20,
say: function () {
console.log(this.a);
}
};
obj.say();
这个是被我简化后的版本,具体题目记不太清了,反正就是考的this的指向问题,上题中答案为20。然后面试官继续追问,如何才能打印出10,给出如下方式:
// 方式1
var a = 10;
var obj = {
a: 20,
say: () => { // 此处改为箭头函数
console.log(this.a);
}
};
obj.say(); // -> 10
// 方式2
var a = 10;
var obj = {
a: 20,
say: function () {
console.log(this.a);
}
};
obj.say.call(this); // 此处显示绑定this为全局window对象
// 方式3
var a = 10;
var obj = {
a: 20,
say: function () {
console.log(this.a);
}
};
var say = obj.say; // 此处先创建一个临时变量存放函数定义,然后单独调用
say();
书写bind
Function.prototype.bind = function(context, ...args1) {
if (typeof this !== 'function') {
throw new Error('not a function');
}
let fn = this;
let resFn = function(...args2) {
return fn.apply(this instanceof resFn ? this : context, args1.concat(args2));
};
const DumpFunction = function DumpFunction() {};
DumpFunction.prototype = this.prototype;
resFn.prototype = new DumpFunction();
return resFn;
}
防抖函数、函数节流
防抖节流
防抖(Debounce): 在指定时间A内,连续调用的时间间隔小于A,前面的调用都会被取消,最后一次调用被执行。
移动端 上拉刷新
模糊查询搜索框的 ajax请求
节流(throttle): 在指定时间A内,该函数只会被调用一次。等待时间A过了函数可以被再次调用且执行最后一次调用。
ajax请求的时候,规定时间内设置请求次数,可以减少ajax请求。
resize或者鼠标移动事件,防止浏览器频繁响应事件,严重拉低性能。
防抖(Debounce)
利用延时器就可以实现
实现图片懒加载的几种方案比较
https://juejin.im/post/5dbf7b6a6fb9a0207326b32b
(算法题) 如何从10000个数中找到最大的10个数
以下打印结果
if([]==false){console.log(1)};
if({}==false){console.log(2)};
if([]){console.log(3)}
if([1]==[1]){console.log(4)}
1和2左右被转成数字 3被转成boolean 4 地址不一样
vue源码
从一个无序,不相等的数组中,选取N个数,使其和为M实现算法
以下打印结果
async function async1(){
console.log('async1 start')
await async2()
console.log('async1 end')
}
async function async2(){
console.log('async2')
}
console.log('script start')
setTimeout(function(){
console.log('setTimeout')
},0)
async1();
new promise(function(resolve){
console.log('promise1')
resolve();
}).then(function(){
console.log('promise2')
})
console.log('script end')
这个也很简单 promise 优先于 setTimeout 微任务和宏任务
script start
async1 start
async2
promise1
script end
promise2
async1 end
setTimeout
// await等async 后面的加入异步不知道233333
// 还有最新V8和旧版本V8展示结果不一样promise2 和async1 end略有互换
async function asyncFunc() {
const result = await otherAsyncFunc();
console.log(result);
}
// 等价于:
function asyncFunc() {
return otherAsyncFunc().then(result => {
console.log(result);
});}
箭头函数this是声明确定还是执行确定
安全
问项目也就算了,问的还都是项目安全问题,大概她做的是安全方面的
问加密算法 问https是怎么回事,真的安全吗?问dns解析怎么回事,dns劫持知道吗?
localhost如何不被篡改,对,全部是围绕安全来的
css3特性中的transform:translateZ(0)有什么作用
GPU加速,优化前端性能
列举三种禁止浏览器缓存的头字段,并写出响应的设置值
https://juejin.im/post/5be2fcd7f265da616d53aad0
手动实现Promise,写出伪代码
数据结构:
https://juejin.im/post/5dc25951e51d4561f81ad1d9
请说出以下打印结果
let a = {a: 10};
let b = {b: 10};
let obj = {
a: 10
};
obj[b] = 20;
console.log(obj[a]);
这道题目主要考对JS数据类型的熟练度以及对ES6 中属性名表达式的理解。在上题中 obj[b] = 20的赋值操作后,obj 其实已经变成了 {a: 10, [object Object]: 20},这是因为如果属性名表达式是一个对象的话,那么默认情况下会自动将对象转为字符串[object Object],最后一步获取obj[a]时,a本身也是一个对象,所以会被转换为获取obj['[object Object]']也就是上一步赋值的20。
对象数组如何去重?
面试官跟我说是根据每个对象的某一个具体属性来进行去重,因为考虑到服务端返回的数据中可能存在id重复的情况,需要前端进行过滤,如下:
const responseList = [
{ id: 1, a: 1 },
{ id: 2, a: 2 },
{ id: 3, a: 3 },
{ id: 1, a: 4 },
];
const result = responseList.reduce((acc, cur) => {
const ids = acc.map(item => item.id);
return ids.includes(cur.id) ? acc : [...acc, cur];
}, []);
console.log(result); // -> [ { id: 1, a: 1}, {id: 2, a: 2}, {id: 3, a: 3} ]
实现函数柯里化
代码如下:
const curry = (fn, ...args1) => (...args2) => (
arg => arg.length === fn.length ? fn(...arg) : curry(fn, ...arg)
)([...args1, ...args2]);
// 调用
const foo = (a, b, c) => a * b * c;
curry(foo)(2, 3, 4); // -> 24
curry(foo, 2)(3, 4); // -> 24
curry(foo, 2, 3)(4); // -> 24
curry(foo, 2, 3, 4)(); // -> 24