只是作为自己整理的面试题,题目有难的也有超基础的
html+css问题总结
1、右边宽度固定,左边自适应
第一种方法:
<style>
body{
display: flex;
}
.left{
background-color: rebeccapurple;
height: 200px;
flex: 1;
}
.right{
background-color: red;
height: 200px;
width: 100px;
}
</style>
<body>
<div class="left"></div>
<div class="right"></div>
</body>
复制代码
第二种实现
<style>
div {
height: 200px;
}
.left {
float: right;
width: 200px;
background-color: rebeccapurple;
}
.right {
margin-right: 200px;
background-color: red;
}
</style>
<body>
<div class="left"></div>
<div class="right"></div>
</body>
复制代码
2、未知宽高垂直居中问题
方法一
思路:显示设置父元素为:table,子元素为:cell-table,这样就可以使用vertical-align: center,实现水平居中
优点:父元素(parent)可以动态的改变高度(table元素的特性)
缺点:IE8以下不支持
<style>
.parent1{
display: table;
height:300px;
width: 300px;
background-color: #FD0C70;
}
.parent1 .child{
display: table-cell;
vertical-align: middle;
text-align: center;
color: #fff;
font-size: 16px;
}
</style>
<div class="parent1">
<div class="child">hello world-1</div>
</div>
复制代码
方法二:
思路:使用一个空标签span设置他的vertical-align基准线为中间,并且让他为inline-block,宽度为0
缺点:多了一个没用的空标签,display:inline-block,IE6 7是不支持的(添加上:_zoom1;*display:inline)。 当然也可以使用伪元素来代替span标签,不过IE支持也不好,但这是后话了
<style>
.parent2{
height:300px;
width: 300px;
text-align: center;
background: #FD0C70;
}
.parent2 span{
display: inline-block;;
width: 0;
height: 100%;
vertical-align: middle;
zoom: 1;/*BFC*/
*display: inline;
}
.parent2 .child{
display: inline-block;
color: #fff;
zoom: 1;/*BFC*/
*display: inline;
}
</style>
<div class="parent2">
<span></span>
<div class="child">hello world-2</div>
</div>
复制代码
方法三
思路:子元素绝对定位,距离顶部 50%,左边50%,然后使用css3 transform:translate(-50%; -50%)
优点:高大上,可以在webkit内核的浏览器中使用
缺点:不支持IE9以下不支持transform属性
<style>
.parent3{
position: relative;
height:300px;
width: 300px;
background: #FD0C70;
}
.parent3 .child{
position: absolute;
top: 50%;
left: 50%;
color: #fff;
transform: translate(-50%, -50%);
}
</style>
<div class="parent3">
<div class="child">hello world-3</div>
</div>
复制代码
方法四:
思路:使用css3 flex布局
优点:简单 快捷
缺点:兼容不好吧,详情见:http://caniuse.com/#search=flex
<style>
.parent4{
display: flex;
justify-content: center;
align-items: center;
width: 300px;
height:300px;
background: #FD0C70;
}
.parent4 .child{
color:#fff;
}
</style>
<div class="parent4">
<div class="child">hello world-4</div>
</div>
复制代码
3、盒模型
获取页面元素位置与宽高:
element.clientWidth = content + padding
element.clientHeight = content + padding
javascript总结
1、let与var的区别?
let 为 ES6 新添加申明变量的命令,它类似于 var,但是有以下不同:
- var 声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象
- let 声明的变量,其作用域为该语句所在的代码块内,不存在变量提升
- let 不允许重复声明.
2、ajax请求的时候get和post方式的区别,用jQ写出ajax请求
GET请求:浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
POST请求:浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
$.ajax({
url:url,
data:data,
success:success,
dataType:dataType
});
复制代码
3、操作数组的方法都有哪些?
(pop、push、unshift、shift、splice、reverse、sort)、slice、indexOf、lastIndex、concat(数据的变异 括号中的能改变原数组)
forEach、filter、map(映射)、find、some、every、includes、reduce
4、数组去重
[...new Set([1,2,3,1,'a',1,'a'])]; //[1, 2, 3, "a"]
复制代码
var ary = [1,2,3,5,1,2],obj = {};
for(var i = 0; i < ary.length; i++){
var cur = ary[i];
if(obj[cur] == cur){
ary[i] = ary[ary.length - 1];
ary.length -= 1;
i--;
continue;
}
obj[cur] = cur;
}
obj = null;
console.log(ary);
复制代码
5、怎么判断两个对象相等?
obj={
a:1,
b:2
}
obj2={
a:1,
b:2
}
obj3={
a:1,
b:'2'
}
//转换为字符串进行判断
JSON.stringify(obj)==JSON.stringify(obj2);//true
JSON.stringify(obj)==JSON.stringify(obj3);//false
复制代码
6、请描述cookies、sessionStorage和localStorage的区别
特性 | Cookie | sessionStorage | localStorage |
---|---|---|---|
数据的生命周期 | 一般由服务器生成,可以设置失效时间,如果在浏览器端生成Cookie,默认关闭浏览器后失效 | 仅在当前会话下有效,关闭页面或浏览器后被清除 | 除非被清除,否则永久保存 |
存放数据大小 | 4k左右 | 一般为5m | 一般为5m |
与服务器端通信 | 每次都会携带在HTTP头中,如果保存过多数据,会带来性能问题 | 仅在客户端(即浏览器)中保存,不参与和服务器的通信 | 仅在客户端(即浏览器)中保存,不参与和服务器的通信 |
易用性 | 需要程序员自己封装,源生的Cookie接口不友好 | 源生接口可以接受,亦可再次封装来对Object和Array有更好的支持 | 源生接口可以接受,亦可再次封装来对Object和Array有更好的支持 |
7、重排和重绘
- 部分渲染树(或者整个渲染树)需要重新分析并且节点尺寸需要重新计算。这被称为重排。注意这里至少会有一次重排-初始化页面布局。
- 由于节点的几何属性发生改变或者由于样式发生改变,例如改变元素背景色时,屏幕上的部分内容需要更新。这样的更新被称为重绘。
什么情况会触发重排和重绘?
- 添加、删除、更新 DOM 节点
- 通过 display: none 隐藏一个 DOM 节点-触发重排和重绘
- 通过 visibility: hidden 隐藏一个 DOM 节点-只触发重绘,因为没有几何变化
- 移动或者给页面中的 DOM 节点添加动画
- 添加一个样式表,调整样式属性
- 用户行为,例如调整窗口大小,改变字号,或者滚动。
8、this指向问题
- 自执行函数中的this永远是window
定时器绑定方法中的this是window
在函数执行传递的回调函数中,一般情况下的this都是window,但是我们可以自己指定里面的this指向问题
//改变this关键字的bind方法
function bind(context,fn){
var outerArg=Array.prototype.slice.call(arguments,2);
return function(){
var innerArg=Array.prototype.slice.call(arguments,0);
var arg=outerArg.concat(innerArg);
fn.apply(context,arg);
}
}
复制代码
- 给元素的某一个事件绑定一个方法(DOM0、DOM2事件绑定),在事件触发执行对应方法的时候,方法中的this是当前元素 (在IE6~8中DOM2绑定事件中的this是window)
- 看方法执行前面是否有".",没有就是window,有的话,"."前面是谁this就是谁
- 在构造函数模式中,我们函数体中的this.xxx=xxx是给当前的实例增加私有的属性和方法呢,这里的this就是当前这个类的一个实例
- 使用call和apply强制改变this [非严格模式] 第一个参数不传/传递的是null或者undefined ->this都是window [严格模式] 第一个参数不传/undefined this->undefined 如果传递的是null this->null
9、标准事件模型 冒泡和捕获的过程
事件冒泡:从内到外
事件捕获:从外到内
addEventListener(event,false/true) true,事件捕获;false,事件冒泡。默认false -----attachEvent兼容IE低版本
e.stopPropagation会阻止冒泡 ------e.preventDefault()
- 利用事件冒泡实现:
$("ul").on("mouseover",function(e){
$(e.target).css("background-color","#ddd").siblings().css("background-color","white");
})
复制代码
10、DOM0级事件与DOM2级事件
事件的传播分为两个阶段:捕获阶段、冒泡阶段(先捕获在冒泡)
- DOM零级事件绑定我们能够看到和控制的只有冒泡阶段:子元素的行为触发,父元素的相关行为也会触发,父元素的父元素的相关行为也会触发...
- DOM二级事件绑定可以看到和控制两个阶段
- DOM二级事件绑定:addEventListener:[type],[function],true:在捕获阶段执行/false:在冒泡阶段完成
- 阻止事件冒泡传播:e.stopPropagation()、cancelBubble=true(ie阻止事件冒泡传播)
- 阻止浏览器默认行为:preventDefault()、returnValue=false(ie)
事件对象e本身也存在兼容问题:在标准浏览器中是浏览器默认传递的形参值e、在IE6~8下我们使用的是全局对象window下的event属性 e=e||window.event;
- e.type 存储的是当前的事件行为类型,例如:"click"...
- e.target 存储的是事件源(当前事件发生在哪个元素上) 这个属性不兼容:e.srcElement 例如:e.target=e.target||e.srcElement;
- e.clientX/e.clientY:鼠标触发点距离当前屏幕窗口左上角的X和Y轴的偏移值
- e.pageX/e.pageY:鼠标触发点距离整个文档(第一屏)左上角的X和Y轴的偏移值 但是在IE下是不存在这个属性的
- e.pageY=e.pageY||(e.clientY+(document.documentElement.scrollTop||document.body.scrollTop));
- e.preventDefault ? e.preventDefault() : e.returnValue = false; ---阻止事件的默认行为
- e.stopPropagation ? e.stopPropagation() : e.cancelable = true; ---阻止事件的冒泡传播
oDiv.onclick = function (e) {
e = e || window.event;
}
复制代码
在IE6~8下不兼容我们的addEventListener这个方法---attachEvent("on"+eventType,eventFn) 只有在冒泡阶段发生 (detachEvent移除事件绑定)
10.1 DOM二级事件相对于DOM0级事件的好处:
- DOM2级事件可以相对比较灵活的控制我们的传播机制
- DOM0级事件只能给一个元素的同一个事件类型绑定一个方法,绑定的第二个方法会把我们的第一个覆盖掉;而DOM2级事件可以给一个元素的同一个事件类型绑定多个不同的方法(这些方法都存在事件池中,当我点击的时候,这些方法都会一个个的执行);
- DOM0中的事件类型在DOM2中都可以使用,但是DOM2级事件绑定中提供了一些DOM0没有的事件类型:DOMContentLoaded(HTML结构加载完成)...
10.2 关于DOM2事件的兼容问题
标准浏览器下使用addEventListener(removeEventListener)实现我们的添加和删除;在IE6~8下使用attachEvent(detachEvent)实现绑定和删除;
- this指向问题:addEventListener绑定的那个方法中的this是当前操作的元素;而attachEvent绑定方法中的this是window
- 重复问题:addEventListener给一个元素的同一个事件类型如果绑定了多个相同的方法,默认只执行其中的一个;但是attachEvent不管是否重复都会执行;
- 顺序问题:addEventListener给一个元素的同一个事件类型绑定多个不同的方法,那么这些方法会按照绑定的先后顺序放入到事假池中,当执行的时候,也同样按照绑定的先后顺序执行;但是attachEvent执行的顺序和绑定的顺序没啥关系,执行的时候,顺序是混乱的;
11、Set 和 Map 数据结构
- ES6 提供了新的数据结构 Set 它类似于数组,但是成员的值都是唯一的,没有重复的值。
- ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。
12、浏览器缓存
浏览器缓存分为强缓存和协商缓存。当客户端请求某个资源时,获取缓存的流程如下:
- 先根据这个资源的一些 http header判断它是否命中强缓存,如果命中,则直接从本地获取缓存资源,不会发请求到服务器;
- 当强缓存没有命中时,客户端会发送请求到服务器,服务器通过另一些request header验证这个资源是否命中协商缓存,称为http再验证,如果命中,服务器将请求返回,但不返回资源,而是告诉客户端直接从缓存中获取,客户端收到返回后就会从缓存中获取资源;
- 强缓存和协商缓存共同之处在于,如果命中缓存,服务器都不会返回资源;
- 区别是,强缓存不对发送请求到服务器,但协商缓存会。
- 当协商缓存也没命中时,服务器就会将资源发送回客户端。
- 当 ctrl+f5 强制刷新网页时,直接从服务器加载,跳过强缓存和协商缓存;
- 当 f5 刷新网页时,跳过强缓存,但是会检查协商缓存;
强缓存
- Expires(该字段是 http1.0 时的规范,值为一个绝对时间的 GMT 格式的时间字符串,代表缓存资源的过期时间)
- Cache-Control:max-age(该字段是 http1.1 的规范,强缓存利用其 max-age 值来判断缓存资源的最大生命周期,它的值单位为秒)
协商缓存
- Last-Modified(值为资源最后更新时间,随服务器response返回)
- If-Modified-Since(通过比较两个时间来判断资源在两次请求期间是否有过修改,如果没有修改,则命中协商缓存)
- ETag(表示资源内容的唯一标识,随服务器response返回)
- If-None-Match(服务器通过比较请求头部的If-None-Match与当前资源的ETag是否一致来判断资源是否在两次请求之间有过修改,如果没有修改,则命中协商缓存)
13、CommonJS 中的 require/exports 和 ES6 中的 import/export 区别?
-
CommonJS 模块的重要特性是加载时执行,即脚本代码在 require 的时候,就会全部执行。一旦出现某个模块被”循环加载”,就只输出已经执行的部分,还未执行的部分不会输出。
-
ES6 模块是动态引用,如果使用 import 从一个模块加载变量,那些变量不会被缓存,而是成为一个指向被加载模块的引用,需要开发者自己保证,真正取值的时候能够取到值。
-
import/export 最终都是编译为 require/exports 来执行的。
-
CommonJS 规范规定,每个模块内部,module 变量代表当前模块。这个变量是一个对象,它的 exports 属性(即 module.exports )是对外的接口。加载某个模块,其实是加载该模块的 module.exports 属性。
-
export 命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系。
14、项目做过哪些性能优化?
- 减少 HTTP 请求数
- 减少 DNS 查询
- 使用 CDN
- 避免重定向
- 图片懒加载
- 减少 DOM 元素数量
- 减少 DOM 操作
- 使用外部 JavaScript 和 CSS
- 压缩 JavaScript 、 CSS 、字体、图片等
- 优化 CSS Sprite
- 使用 iconfont
- 字体裁剪
- 多域名分发划分内容到不同域名
- 尽量减少 iframe 使用
- 避免图片 src 为空
- 把样式表放在 中
- 把脚本放在页面底部
vue问题
1、Vue router 除了 router-link 怎么实现跳转?
router.go(1)
router.push('/')
复制代码
2、Vue router 跳转和 location.href 有什么区别?
router 是 hash 改变
location.href 是页面跳转,刷新页面
3、Vue 双向绑定实现原理?
通过 Object.defineProperty 实现的
4、你能实现一下双向绑定吗?
<body>
<div id="app">
<input type="text" id="txt">
<p id="show-txt"></p>
</div>
<script>
var obj = {}
Object.defineProperty(obj, 'txt', {
get: function () {
return obj
},
set: function (newValue) {
document.getElementById('txt').value = newValue
document.getElementById('show-txt').innerHTML = newValue
}
})
document.addEventListener('keyup', function (e) {
obj.txt = e.target.value
})
</script>
</body>
复制代码
摘取文章:
https://blog.ihoey.com/posts/Interview/2018-02-28-alibaba-interview.html