前端面试总结

前端面试总结

个人前端BAT暑期实习面试题总结和从朋友同学那打听来的题,既可以准备笔试面试,也可以对自己的基础知识查漏补缺

1. position的值各是什么意思?

(1)static:HTML元素的默认值,即没有定位,元素出现在正常的流中。静态定位的元素不会受到top left bottom right z-index 这些值的影响。
(2)fixed:元素的位置相对于浏览器窗口是固定位置。即使窗口是滚动的它也不会移动,元素的位置通 过 “left”, “top”, “right” 以及 “bottom”属性进行规定。fixed定位 使元素的位置与文档流无关,因此不占据空间。fixed定位的元素和其他元素重叠
(3)relative:相对定位元素的定位是相对其正常位置,它原本所占的空间不会改变,。
(4)absolute:生成绝对定位的元素,相对于static定位以外的第一个父元素进行定位。元素的位置通过”left”,”top”, “right” 以及 “bottom” 属性进行规定。与文档流无关 ,因此不占据空间。

2. 跨域的方法有哪些,及其原理

(1)jsonp是用script标签的src属性是不跨域的这一性质,所以其实是封装了这个功能而已,jquery会创建一个script标签,把src的地址指向后端,src会带一个callback参数,一般是一个函数名,后端根据这个请求,获取参数,然后把需要返回的数据包裹在这个函数内,前端获得了这些js代码,就会执行这个callback,自然就把数据传到客户端了。只支持GET请求参考文档。缺陷是只支持GET,并且参数都在url中,url的大小是有限制的。
(2)cors(cross-origin resource sharing)就是服务端加上一句 header(“Access-Control-Allow-Origin:“); 支持所有请求,但是兼容性不太好,支持IE9+,chrome3+。 如果需要携带cookie,那么需要加上header(“Access-Control-Allow-Credentials”, true)。同时,origin不能为\,必须为单个host,一般为请求的origin。
(3)window.name.一个窗口window的生命周期内,窗口载入的页面共享一个window.name,每个页面都有读写权限,
data.html里面就写上window.name=”data..”;然后在a.html里用一个隐藏的iframe载入data.html,然后在a.html里用js把iframe的src设为同源的一个页面。
(4)修改document.domain的方法只适用于不同子域的框架间的交互。比如http://www.example.com/a.html和 http:example.com/b.html 在两个页面中都修改document.domain为”example.com”
(5)img标签的src也是不跨域的,所以可以

1
img.src=“http://example.com/data?value=123

但是这种方法只能用来发送请求.
(6)HTML5有一个postMessage(data,origin)方法,可以向当前页面中的iframe或者当前页弹出的窗口发送消息
(7)最佳实践,嵌套一个同域的iframe,然后使用postMessage通信,请求交由同域的iframe里发送,结果通过postMessage发送回来。

3. meta标签都有那些属性和值?

属性主要有name和http-equiv,content 属性始终要和 name 属性或 http-equiv 属性一起使用。name属性主要有author、description、keywords。使用带有 http-equiv
属性的 < meta > 标签时,服务器将把名称/值对添加到发送给浏览器的内头部。主要有expires
(网页到期时间)、Set-Cookie、content-Type(content=”text/html; charset=gb2312”),
refresh(自动刷新 http-equiv=”refresh”content=”5; url=http://www.111cn.net/")
js可以实现自动刷新的方法: Javascript刷新页面 的几种方法:
1 history.go(0)
2 location.reload()
3 location=location
4 location.assign(location)
5 document.execCommand(‘Refresh’)
6 window.navigate(location)
7 location.replace(location)
8 document.URL=location.href

4. css3中动画有哪些属性可以实现?

1)animation: myfirst 5s;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
div
{
width:100px;
height:100px;
background:red;
animation:myfirst 5s;
animation-name: myfirst;
animation-duration: 5s;
animation-timing-function: linear;
animation-delay: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-play-state: running;
-moz-animation:myfirst 5s; /* Firefox */
-webkit-animation:myfirst 5s; /* Safari and Chrome */
-o-animation:myfirst 5s; /* Opera */
}

@keyframes myfirst
{
from {background:red;}
to {background:yellow;}
}
@keyframes myfirst
{
0% {background: red;}
25% {background: yellow;}
50% {background: blue;}
100% {background: green;}
}

CSS动画
2)css3中的transition transform

5. 响应式布局有哪些方法

  1. media query
  2. 内容居中

6. 网站性能优化有哪些方法

优化静态资源加载速度

  1. 合并静态资源,减少http请求数量,减少整体的请求时间。图片sprites(合并图片,然后用CSS background-position等属性制定图片位置的方法)
  2. 减少静态的体积,减少资源的下载时间。压缩代码,比如js css等代码进行压缩,图片压缩。
  3. 优化资源本身的请求速度。比如使用cdn,内容分发网络,即把内容都分布在各个节点,客户端就可以找最快的节点进行下载。同时有利于并发请求,因为一次对同一个网站的并发请求数是有限制的。
  4. 使用HTTP缓存,直接从缓存中读取,就直接不需要发起请求了。如果需要极致的优化,可以使用localStorage,缓存静态资源。
  5. 静态资源使用无cookie的域。

    渲染优化

  6. css 放在head js放在body后,因为如果放在前面的话,页面会等js加载完才渲染
  7. 延迟加载,一些不需要在首屏出现的内容比如图片可以延迟加载,加快首屏的渲染时间,提升用户体验。
  8. 同构,后端使用nodejs直接支出首屏。

    代码层面的优化

  9. 减少DOM数量
  10. 使用DocumentFragment减少DOM的插入操作,减少重排
  11. 使用修改className的形式修改css样式,而不是用js一个一个属性进行修改,减少重绘
  12. 对于会频繁触发重排的动画元素,使其position为absolute或者fixed,可以减少对其他元素的影响。
  13. 尽量减少使用全局变量,因为全局变量不会被回收,会一直在内存中。
    参考文档1
    参考文档2
    参考文档3

7. 数据库查询优化方法

  1. 建索引
  2. 查询语句的优化,比如避免全盘扫描之类的。

8. HTML5 css3中有哪些特性,session和本地存储、cookie的区别?

HTML5:语义化标签(header nav footer article) audio video canvas svg localstorage sessionStorage 地理定位 新的表单控件比如date time email等

css3:transform:translate rotate scale skew matrix,transition,animation,text-shadow,border-radius,box-shadow,新增伪类
p:first-of-type 选择属于其父元素的首个 p 元素的每个 p 元素。
p:last-of-type 选择属于其父元素的最后 p 元素的每个 p 元素。
p:only-of-type 选择属于其父元素唯一的 p 元素的每个 p 元素。
p:only-child 选择属于其父元素的唯一子元素的每个 p 元素。
p:nth-child(2) 选择属于其父元素的第二个子元素的每个 p 元素。
:enabled :disabled 控制表单控件的禁用状态。
:checked 单选框或复选框被选中。

session是在服务端,会在一段时间后消失,cookie是在客户端,会在每次请求时被发送到服务端,所以可以在服务端被读取和修改,cookie有实效性、大小有限制,localStorage不可以被后端读取,无实效性,可以达到5M。sessionStorage当前浏览器窗口关闭就自动删除

9. 什么是模块化开发,以及为什么要进行模块化开发

解决命名冲突和文件依赖,异步加载模块的话,还可以提高性能。可以实现模块的版本管理。每个模块单独一个文件,极大的提高了可维护性。接入已有的功能模块,开发不存在的功能模块。

10. MVVM

就是Model View ViewModel,都是MV*,ViewModel负责逻辑控制,View没有业务逻辑,
它采用双向绑定(data-binding):View的变动,自动反映在ViewModel上。Anjularjs 就是MVVM模式。

11. 清楚浮动有哪些方法?

参考文章
参考文章2;
其实都是触发父元素的BFC,然后让它重新计算高度,解决高度塌陷的问题。

  1. 在浮动元素末尾添加一个空的标签例如或者用br标签, 因为它有 clear=“all | left | right | none” 属性

    1
    <div style=”clear:both”>
  2. 父元素设置 overflow 除了visible 以外的值(hidden,auto,scroll )

  3. 父元素使用:after 伪元素

    1
    2
    3
    4
    .clearfix:after {
    content:"."; display:block; height:0; visibility:hidden; clear:both;
    }
    .clearfix { *zoom:1; }
  4. 父元素 float 除了none以外的值

  5. 父元素display (table-cell,table-caption,inline-block)
  6. 父元素position(absolute,fixed)
    最好的方法是:after伪元素,后三种方法会影响整个的布局,而我们的目的只是清除浮动而已,所以用一个伪元素是最好的方法。

12. 解释下js的原型链? 封装 继承

javascript每一个对象A都有一个私有变量prototype指向另一个对象B,B对象就是A的原型,B也和A一样,依次类推,直到这个私有变量为null,这样就形成一个链条。这样就是A继承B。
js中可以定义命名空间,但是这个命名空间其实就是一个包含属性、方法、对象的对象。和其他对象没有区别。js实现继承,最好是使用构造函数加原型链的方式,可以获得原型的方法,但是并不知道方法的具体实现,这样就实现了封装和继承。
MDN的说明
js实现继承

13. ES6新特性

阮一峰的文章
ES6功能检测库

  1. 箭头( => )。是匿名函数定义的缩写,比如element.addEventListener(‘click’, (e) => console.log(e));
  2. Class类。语法糖,其实还是基于原型链
  3. String Array Math Number等内置对象增加了一些函数,比如String.include(),Array.find() Number.isNaN() 等
  4. 模块化加载器,可以export import
  5. let关键字实现了块级作用域,const实现了常量。let跟var的区别在于let能限定变量在当前块的作用域下。
  6. 函数支持默认参数、剩余参数、参数展开为数组
  7. 模板字符串
  8. 原生提供promise
  9. 添加Map和Set数据结构
  10. yield生成器,执行到yield时就会停止,直到调用next方法,就会执行一步,遇到yield又会停止。
  11. Iterator构造函数,传入想要迭代其值的对象,然后调用next。如果是数组,返回的数组第一个元素是索引,如果是对象,第一个元素是属性名,第二个是属性值。

14. js中如何检测未定义的变量?

tyepof a===”undefined” //定义了但没赋值也是true,但是定义了没有赋值和没有定义对于我们来说是一样的,因为你都没法在上面进行操作,只能赋值。

15. 解释下js中的闭包?

闭包就是能够读取其他函数内部变量的函数。可以把闭包简单理解成”定义在一个函数A内部的函数B”。然后把这个函数Breturn,在外部调用这个函数B时,这个函数就可以调用A函数内的变量。

1
2
3
4
5
6
7
8
9
function f1(){
    var n=999;
    function f2(){
      alert(n);
    }
    return f2;
  }
  var result=f1();
  result(); // 999

闭包还有一个作用就是可以让变量保存在内存中,比如
这是不用闭包的代码

1
2
3
4
5
6
7
8
9
function createFunctions(){
var result = new Array();
for (var i=0; i < 10; i++){
result[i] = function(){
return i;
};
}
return result;
}

结果是result里面的值全是10,并没有达到我们想要的结果。
这是使用闭包的代码

1
2
3
4
5
6
7
8
9
10
11
function createFunctions(){
var result = new Array();
for (var i=0; i < 10; i++){
result[i] = function(num){
return function(){
return num;
};
}(i);
}
return result;
}

16. 尽可能的说明下ajax的工作原理?

ajax 的全称是Asynchronous JavaScript and XML。异步请求
ajax的原理简单来说就是利用XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,
XMLHttpRequest这个对象的属性。它的属性有:

字段 说明
onreadystatechange 每次状态改变所触发事件的事件处理程序。
responseText 从服务器进程返回数据的字符串形式。
responseXML 从服务器进程返回的DOM兼容的文档数据对象。
status 从服务器返回的数字代码,比如常见的404(未找到)和200(已就绪)
status Text 伴随状态码的字符串信息
readyState 对象状态值(0 (未初始化) 对象已建立,但是尚未初始化(尚未调用open方法)1 (初始化) 对象已建立,尚未调用send方法。 2 (发送数据) send方法已调用,但是当前的状态及http头未知。3 (数据传送中) 已接收部分数据,因为响应及http头不全,这时通过responseBody和responseText获取部分数据会出现错误。4 (完成) 数据接收完毕此时可以通过通过responseXml和responseText获取完整的回应数据)

对于XmlHttpRequest的两个方法,open和send,其中open方法指定了:
a、向服务器提交数据的类型,即post还是get。
b、请求的url地址和传递的参数。
c、传输方式,false为同步,true为异步。默认为true。如果是异步通信方式(true),客户机就不等待服务器的响应;如果是同步方式(false),客户机就要等到服务器返回消息后才去执行其他操作。我们需要根据实际需要来指定同步方式,在某些页面中,可能会发出多个请求,甚至是有组织有计划有队形大规模的高强度的request,而后一个是会覆盖前一个的,这个时候当然要指定同步方式。
Send方法用来发送请求。
在IE和非IE下创建XmlHttpRequest有点区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function CreateXmlHttp() {

//非IE浏览器创建XmlHttpRequest对象
if (window.XmlHttpRequest) {
xmlhttp = new XmlHttpRequest();
}

//IE浏览器创建XmlHttpRequest对象
if (window.ActiveXObject) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) {
try {
xmlhttp = new ActiveXObject("msxml2.XMLHTTP");
}
catch (ex) { }
}
}
}

17. 基本的http状态码有哪些,各代表什么意思?

状态码 意义
200 请求ok
206 Partial Content,request必须带上Range
301 请求的资源被永久的移到新位置Moved Permanently
302 请求的资源临时被移到新位置
303 请求可以在另一个URI上找到,并且使用get方式
304 请求的资源没有变化,请求不会返回内容,将使用缓存 Not Modified
400 bad request
401 Unauthorized,比如有csrf token验证的,验证失败会返回这个
403 Forbidden
404 Not Found
500 服务器错误 Internal Server Error
502 网关错误 Bad Gateway
503 服务器不可用 Service Unavailable
504 超时 Gateway Timeout

18. ‘==’和‘===’有什么区别?

‘==’会做类型转换 ‘0’==0 //true
但是 ‘0’===0 //false
所以永远不要用==

19. CSS预处理器有哪些?

sass less

20. js文件的异步加载

  1. 带有 defer 属性的script标签可以放置在文档的任何位置。对应的 JavaScript 文件将在页面解析到script标签时开始下载,但不会执行,直到 DOM 加载完成,即DOMContentLoaded事件触发前才会被执行。当一个带有 defer 属性的 JavaScript 文件下载时,它不会阻塞浏览器的其他进程,因此这类文件可以与其他资源文件一起并行下载。
  2. HTML 5 为script标签定义了一个新的扩展属性:async。它的作用和 defer 一样,能够异步地加载和执行脚本,不因为加载脚本而阻塞页面的加载。async标签的js会在加载完就立即执行,执行顺序取决于加载完成的顺序,谁先加载完,谁先执行
  3. 动态script标签
  4. 用xhr,用一个动态 script 元素将 JavaScript 代码注入页面。

21. get和post的区别

最主要的区别就是一个是用来获取数据的,一个是用来更新数据的
get和post的真正区别
url长度是webserver的限制,不是get的限制。至于安全,post把数据放在body中传输,一抓包还不是一样的可以看到,根本不是本质区别。有一点小区别,就是get请求可以被缓存,有浏览历史,可被收藏为书签

22. null和undefined的区别

null表示”没有对象”,即该处不应该有值。典型用法是:
(1) 作为函数的参数,表示该函数的参数不是对象。
(2) 作为对象原型链的终点。

1
2
Object.getPrototypeOf(Object.prototype)
// null

null转为数字时为0 Number(null)===0 但是parseInt(null)为NaN Number(undefined)为NaN
undefined表示”缺少值”,就是此处应该有一个值,但是还没有定义。典型用法是:
(1)变量被声明了,但没有赋值时,就等于undefined。
(2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。
(3)对象没有赋值的属性,该属性的值为undefined。
(4)函数没有返回值时,默认返回undefined。
阮一峰的文章

23. commonJS规范

参考文章
CommonJS是服务器模块的规范,Node.js采用了这个规范。
根据CommonJS规范,一个单独的文件就是一个模块。每一个模块都是一个单独的作用域,也就是说,在一个文件定义的变量(还包括函数和类),都是私有的,对其他文件是不可见的。
每个文件的对外接口是module.exports对象。这个对象的所有属性和方法,都可以被其他文件导入。
require方法用于在其他文件加载这个接口
每个模块都有一个module变量,该变量指向当前模块。module不是全局变量,而是每个模块都有的本地变量。
CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。AMD规范则是非同步加载模块,允许指定回调函数。由于Node.js主要用于服务器编程,模块文件一般都已经存在于本地硬盘,所以加载起来比较快,不用考虑非同步加载的方式,所以CommonJS规范比较适用。但是,如果是浏览器环境,要从服务器端加载模块,这时就必须采用非同步模式,因此浏览器端一般采用AMD规范。

24. 什么是xss攻击和csrf攻击

XSS攻击:跨站脚本攻击(Cross Site Scripting)。
它与SQL注入攻击类似,SQL注入攻击中以SQL语句作为用户输入,从而达到查询/修改/删除数据的目的,而在xss攻击中,通过插入恶意脚本,比如对于那种没有实现输入过滤评论,可以在评论内容中注入js代码,等评论展现在其他用户浏览器中的时候,这段js代码就可以获取该用户的cookie等信息,实现对用户游览器的控制。预防方法就是对用户的输入过滤,html标签肯定要过滤或者转义。
CSRF(Cross-site request forgery跨站请求伪造)利用网站对用户标识的信任。欺骗用户的浏览器发送HTTP请求给目标站点,这个请求是带有用户的cookie的。另外可以通过IMG标签会触发一个GET请求,可以利用它来实现CSRF攻击。比如登陆A银行网站,产生了cookie,然后在没有登出A网站的情况下访问B网站,B网站要求发送一个请求到A,比如是发送一个转账请求,那这时就发生了转账操作,攻击实现。参考文章.预防方法:表达增加hash后的cookie,后端验证。增加验证码。每个表单都带一个随机值,后端验证这个随机值。

25. 事件冒泡及事件委托原理

DOM事件流包括事件捕获阶段、处于目标阶段、事件冒泡阶段三个阶段,默认情况下都是在冒泡阶段处理事件。如下所示,第三个参数为true则表示使用捕获阶段处理,默认为false。

1
2
3
document.getElementById("ch").addEventListener("click",function  (argument) {
console.log("ch");
},true);

事件冒泡,就是在当前元素发生的事件,为往父元素冒泡传递,直到window。
事件委托是事件冒泡的一个应用,绑定事件到父元素,在事件处理中判断是哪个元素发生的,再作处理。这样可以减少绑定元素的个数,也不必担心子节点被替换后或者新增加子节点可能需要进行重新的事件绑定。因为事件的捕获和后续代码的执行已经完全委托给了其父节点。如果页面中含有大量元素需要绑定事件,这样做会减少事件绑定数量,为浏览器减负,无疑会提高页面性能。
以下事件不冒泡:blur、focus、load、unload。

1
2
3
4
5
6
7
8
//阻止事件冒泡函数
function stopBubble(e)
{
if (e && e.stopPropagation)
e.stopPropagation()
else
window.event.cancelBubble=true
}

26.快排的javascript实现

在一个数组内移动,标准值取最右边的元素,从left开始,逐个和right位置的值比较,小的则插入sIndex(这个值在最开始为0),zIndex++,即把小于标准值的数从0开始逐个插入,把比他小的值都查好了,那下一个zIndex自然就是标准值的位置,这样就把比标准值小的都在标准值左边,比标准值大的都在右边,然后递归,递归中,left>right时,停止。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//快速排序
var testArr=[10,2,4,3,13,4,1,21,24,123,12,3];
function quickSort (arr,left,right) {
if (left > right) {
return;
}
var length=arr.length;
var sIndex=left;
for(var i=left;i<right;i++){
if(arr[i]<arr[right]){
swap(arr,i,sIndex);
sIndex++;
}
}
swap(arr,sIndex,right);
quickSort(arr,0,sIndex-1);
quickSort(arr,sIndex+1,right);
}
function swap (arr,i,j) {
var temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
quickSort(testArr,0,testArr.length-1);
console.log(testArr);

var a = [5,3,7,1,8,4,3,5,4,7,2,6,8,3,6,1];

function quickSort(arr) {
if (arr.length <= 1) {
return arr;
}
var key = arr[0];
var i = 0;
var j = arr.length - 1;
var temp;

while( i < j) {
while(i < j && arr[j] >= key) {
j--;
}
while(i < j && arr[i] <= key) {
i++;
}
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// 这才真正的完成了一轮排序,把key放到了合适的地方
temp = key;
arr[0] = arr[i];
arr[i] = key;
debugger;
console.log(arr.slice(0, i), arr[i], arr.slice(i + 1));
return quickSort(arr.slice(0, i)).concat([arr[i]], quickSort(arr.slice(i + 1)))
}
console.log(quickSort(a));



function quickSort2(arr) {
var i = 0;
var j = arr.length - 1;
var key = 0;
var temp;
while(i < j) {
while(i < j && arr[j] >= arr[key]) {
j--;
}
temp = arr[key];
arr[key] = arr[j];
arr[j] = temp;
key = j
while(i < j && arr[i] <= arr[key]) {
i++;
}
temp = arr[key];
arr[key] = arr[i];
arr[i] = temp;
key = i;
}
return quickSort(arr.slice(0, i)).concat([arr[i]], quickSort(arr.slice(i + 1)))
}
console.log(quickSort2(a));

27.javascript中实现私有变量和私有方法

1)构造函数中使用var声明的变量和方法。
存在问题,一是构造函数中的私有变量在prototype中没法访问。二是内存消耗,每次new一个新对象时,私有函数都会重新创建一个,最好的应该是共享同一个私有函数。
2) 使用闭包,return一个原型对象,这个原型对象是可以访问内部私有变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//构建一个原型对象
Person.prototype = (function(){
/******私有方法定义*****/

//通过var定义
var toStr = function(){
return this.name + " is " + this.age
}

//直接定义
function privateMethod(){
console.log("in private method");
}


return {//返回的这个函数会返回一个原型对象
constructor:Person,//把原型的constructor属性设置到正确的构造函数

/*******公有方法*******/
printInfo:function(){
console.log("printing info:",toStr.call(this));
},

publicMethod:function(){
privateMethod.call(this);
}
}

})();//注意这里的括号表示立刻执行此匿名函数,返回原型对象


//test case
var p = new Person('Jaskey',24);
p.printInfo();//printing info: Jaskey is 24
p.publicMethod();// in private method
p.toStr();//"undefined is not a function"

参考博文;

28 HTTP和HTTPS的区别,如何优化HTTPS的性能

HTTPS 就是在安全的传输层SSL之上发送HTTP请求的,传输正式的内容之前会先进行ssl连接,客户端和服务端互相确认,建立信任之后,会对接下来的传输进行加密。
HTTPS对速度的影响主要在协议交互所增加的网络和加密解密相关的计算耗时
解决办法:1)在发送syn包的时候也捎上应用层的数据;2)复用session,就是建立SSL连接的时候,保存session,利用session信息提前完成握手,简化握手;3)复用HTTP请求管道,多个请求一起发送。4)优化公私钥计算的算法,或者利用GPU来运算实现加速。

29 tcp三次握手,四次挥手

1.客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态
2.服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
3.客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

在断开连接的时候会进行4次挥手
1.客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送。客户端进入FIN-WAIT-1状态
2.服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。服务端进入CLOSE-WAIT状态,客户端A进入FIN-WAIT-2状态
3.服务器B关闭与客户端A的连接,发送一个FIN给客户端A。 服务端进入LAST-ACK状态
4.客户端A收到后发回ACK报文确认关闭,并将确认序号设置为收到序号加1。进入TIME-WAIT状态,等待30秒后进入CLOSE状态,服务端进入CLOSE状态。

30 原生ajax请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var xmlHttp;
function createxmlHttpRequest(){
if(window.ActiveXObject){
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); //IE 5 6已经不用兼容了
}else if(window.XMLHttpRequest) {
xmlHttp=new XMLHttpRequest();
}
xmlHttp.onreadystatechange=function(){
if(xmlHttp.readyState=4&&xmlHttp.status==200){
xmlHttp.responseText //纯文本
xmlHttp.responseXML //xml文档
}
}
}

31 一个先递增再递减的数组,怎么获取最大值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function findMax(arr,left,right){
if((right-left)==1){
return arr[left]>arr[right]?arr[left]:arr[right];
}
var middle=Math.floor((left+right)/2);
if(arr[middle]>arr[middle-1]&&arr[middle]>arr[middle+1]){
return arr[middle];
}else{
if(arr[middle]<arr[middle+1]){
return findMax(arr,middle,right);
}else{
return findMax(arr,left,middle);
}
}

}
var result=findMax(arrTest,0,arrTest.length-1);
alert(result);

32 从地址栏输入url到页面展现,详细描述下这个过程

  1. 浏览器通过url知道了请求协议和请求的资源。当协议或者请求不合法时,会把输入框中的文字转给搜索引擎
  2. 拉取浏览器的cache,看是否需要更新,否则直接后去缓存。主要看Expires时间、cache设置和浏览器设置.
  3. 看输入的地址是否在HSTS(HTTP严格传输安全)列表,在的话会使用https访问,不在则会使用http请求。
  4. 转换非ASCII的Unicode字符,浏览器检查输入是否含有不是 a-z, A-Z,0-9, - 或者 . 的字符,如果有的话,浏览器会对主机名部分使用 Punycode 编码
  5. DNS查询。浏览器检查域名是否在缓存当中,如果缓存中没有,就去调用 gethostbyname 库函数(操作系统不同函数也不同)进行查询gethostbyname函数在试图进行DNS解析之前首先检查域名是否在本地Hosts里,Hosts的位置不同的操作系统有所不同,如果gethostbyname没有这个域名的缓存记录,也没有在hosts里找到,它将会向DNS服务器发送一条DNS查询请求。
  6. 获得ip和端口号后,就会相应ip所在的服务器通过tcp连接发送请求。
  7. 浏览器接收HTTP响应,或许关闭TCP连接,或许用于其他请求
  8. 浏览器检查这次响应是否重定向(3XX 状态码),如果是重定向,浏览器会重新发送一次请求,或是一次授权请求(401)错误请求(4XX 和 5XX)等等,如果是错误请求会展现错误页。这些和正常响应(2XX)的处理有所不同。
  9. 请求成功会返回一个数据包和比如要不要缓存、更新时间、压缩编码方式之类的信息。
  10. 取得内容后,如果要缓存则进行缓存,然后开始解码。开始解析html,创建DOM树,接着开始下载javacript css 那些需要html解析完才下载的外部资源.
  11. 通过DOM树和css,创建渲染树,计算每个节点的css样式,得到需要展现在浏览器中的框框。
  12. 将渲染树得到的布局绘制到屏幕中。
    参考文章;

33请求头和返回头各有些什么信息

一个请求头
GET /mumue/archive/2012/04/23/2467072.html HTTP/1.1
Host: www.cnblogs.com
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36
Referer: https://www.google.com.hk/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
Cookie: CNZZDATA1255778100=388437504-1442227353-null%7C1442227353; _ga=GA1.2.1845097067.1442111906; _gat=1
If-Modified-Since: Tue, 15 Sep 2015 07:16:13 GMT

一个返回头
HTTP/1.1 200 OK
Date: Tue, 15 Sep 2015 07:19:07 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
Vary: Accept-Encoding
Cache-Control: private, max-age=10
Expires: Tue, 15 Sep 2015 07:19:09 GMT
Last-Modified: Tue, 15 Sep 2015 07:18:59 GMT
X-UA-Compatible: IE=10
Content-Length: 34031

34 各种排序算法的时间空间复杂度和稳定性

参见这篇文章;

35 从100个数字中选10个不重复的数。

  1. 直接随机选取,选中一个数后,将这个数从原数组删除

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function randomSelect (arr,count) {
    var result=[];
    for(var i=0;i<count;i++){
    var index=parseInt(Math.random()*arr.length);
    var d=arr[index];
    result.push(d);
    arr.splice(index,1);
    }
    return arr;
    }
  2. 随机打乱原数组顺序,返回前10个

    1
    2
    3
    4
    5
    6
    function randomSelect (arr,count) {
    arr.sort(function(){
    return Math.random()-0.5;
    });
    return arr.slice(0,count);
    }

36 有一个生成均匀1-5随机数的函数,怎么生成同等概率的1-7

如果a > b,那么一定可以用Randa去实现Randb,所以现在必须用rand5得到一个比7更大的随机数,然后再来时实现rand7.
5*(rand5()-1)+rand5() 可以均匀得到1-25,然后从1-21取模,就可以得到1-7了

1
2
3
4
5
6
7
8
9
10
11
12
function rand7(){
x=25;
while(x>21){
x=5*(rand5()-1)+rand5();
}
return x%7+1;
}
计算概率x=1
p(x=1)=3/25+(4/25)*3/25+(4/25)^2*3/25...
=(3/25)*(1-(4/25)^n)/(1-4/25) //等比数列
=(3/25)*(25/21)
=1/7

通用的方法是randb=a*(randa()-1)+randa

37 查找两个节点最近的子节点

1
2
3
4
5
6
7
function commonParentNode(oNode1, oNode2) {
if(oNode1.contains(oNode2)){
return oNode1;
}else{
return commonParentNode(oNode1.parentNode,oNode2);
}
}

37 从一个未知结构的HTML文档里面筛选出最多的三个标签

非常笨的方法,从document开始遍历,记录在obj中,同时比较得到最多的三个标签。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
var tagObj={};
var top3Dom=[];
function getNode (dom) {
var childs=dom.children;
if(childs){
for(var i=0;i<childs.length;i++){
if(!tagObj[childs[i].tagName]){
tagObj[childs[i].tagName]=1;
if(top3Dom.length<3){
var having=false;
for(var j=0;j<top3Dom.length;j++){
if(childs[i].tagName==top3Dom[j]){
having=true;
}
}
if(!having){
top3Dom.push(childs[i].tagName);
}
}

}else{
tagObj[childs[i].tagName]+=1;
if(childs[i].tagName==top3Dom[0]){
}else if(childs[i].tagName==top3Dom[1]){

}else if(childs[i].tagName==top3Dom[2]){

}else if(tagObj[childs[i].tagName]>tagObj[top3Dom[0]]){
top3Dom[0]=childs[i].tagName;
}else if(tagObj[childs[i].tagName]>tagObj[top3Dom[1]]){
top3Dom[1]=childs[i].tagName;
}else if(tagObj[childs[i].tagName]>tagObj[top3Dom[2]]){
top3Dom[2]=childs[i].tagName;
}
}
getNode(childs[i]);
}
}
}
getNode(document);
console.log(tagObj);
console.log(top3Dom);

38 两栏布局或者三栏布局左边固定,右边自适应

1. 两栏布局,一侧定宽,一侧自适应

1) float+margin:原理是左侧固定的div设置float后,下面的right就上去了,然后设置margin-left,因为宽度会默认为剩下的宽度,所以可以自适应

1
2
3
4
5
6
7
8
9
10
11
12
13
#left{
height:100px;
width:300px;
float:left;
background-color:yellow;
}
#right{
margin-left:300px;
height:100px;
background-color:blue;
}
<div id="left"></div>
<div id="right"></div>

2) absolute+margin:原理是一样的,position:absolute,是left脱离文档流,那right就顶上去了,然后给right设置margin-left;因为宽度会默认为剩下的宽度,所以可以自适应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#left{
position:absolute;
left:0px;
top:0px;
height:100px;
width:300px;
background-color:yellow;
}
#right{
margin-left:300px;
height:100px;
background-color:blue;
}
<div id="left">left</div>
<div id="right">right</div>

3)float+负margin;这要增加一个float,width是100%的dom,然后里面放置right,dom下面放置left。正常流的话,right会和这个dom重叠,这时给right设置margin-left,然后给left设置float,同时margin-left:-100%,那left就会回退到dom的左边,因为正常情况下是在dom的下方的,因为dom的width是100%,但是margin-left=-100%,所以left就会到right空出的那个区域。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<style>
#box{
width: 100%;
float: left;
}
#right{
background-color: blue;
height: 100px;
margin-left: 300px;
}
#left{
background-color: yellow;
height: 100px;
width: 300px;
float: left;
margin-left: -100%;
}
</style>
<div id="box">
<div id="right">right</div>
</div>
<div id="left">left</div>

4)flex

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<style>
.container {
display: flex;
}
.left {
width: 300px;
}
.right {
flex: 1;
}
<style>
<div class="container">
<div class="left"></div>
<div class="right"></div>
</div>

2. 三栏布局,两侧固定,中间自适应

1) 自身浮动,浮动脱离文档流,然后中间区域用margin实现和左右的距离

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.left{
float:left;
width:100px;
}
.main{
height:100%;
margin:0 100px;
}
.right{
float:right;
width:100px;
}
<div id="left"></div>
<div id="right"></div>
<div id="main"></div>

2) margin负值法。首先,中间的主体要使用双层标签。外层div宽度100%显示,并且浮动(本例左浮动,下面所述依次为基础),内层div为真正的主体内容,含有左右210像素的margin值。左栏与右栏都是采用margin负值定位的,左栏左浮动,margin-left为-100%,由于前面的div宽度100%与浏览器,所以这里的-100%margin值正好使左栏div定位到了页面的左侧;右侧栏也是左浮动,其margin-left也是负值,大小为其本身的宽度即200像素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<div class="main">
<div class="body"></div>
</div>
<div class="left"></div>
<div class="right"></div>
.main{
float:left;
height:100%;
width: 10%;
}
.body{
margin:0 210px;
height:100%;
}
.left{
float:left;
width:200px;
margin-left:-100%;
height:100%;
}
.right{
float:left;
margin-left:-200px;
width:200px;
height:100%;
}

3)绝对定位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div class="left"></div>
<div class="right"></div>
<div class="main"></div>
.main{
margin:0 210px;
height:100%;
}
.left{
position:absolute;
left:0px;
width:200px;
height:100%;
}
.right{
position:absolute;
right:0px;
width:200px;
height:100%;
}

39 图片轮播,点击切换

40 赋值坑、代码题

  1. 坑一

    1
    2
    3
    4
    5
    var a = {n:1};  
    var b = a; // 持有a,以回查
    a.x = a = {n:2};
    alert(a.x);// --> undefined
    alert(b.x);// --> {n:2}

    原理:解析器会先找到 a 和 a.x 的指针.如果已有指针,那么不改变它.如果没有指针,即那个变量还没被申明,那么就创建它,指向null.a 是有指针的,指向 {n:1};a.x 是没有指针的,所以创建它,指向 null。然后把上面找到的指针,都指向最右侧赋的那个值,即 {n:2}。所以给a.x赋值时,是给a原来指向的那个x属性,因为b=a,所以b中有这个x属性.但是a被赋值为{n:2}了,所以a.x为undefined。

  2. 坑二

    1
    2
    3
    4
    5
    (function () {
    var a=b=10;
    })();
    alert(typeof a) //undefined
    alert(typeof b) //number;

    从右向左赋值,给b赋值时,没有var,所以自动升级为全局变量,而a是局部变量。

  3. &&和||
    1
    2
    3
    alert(1||2);  //1
    alert(1&&2); //2
    alert(1>2||2>3); //false

41 常遇到的兼容性问题

  1. 绑定事件 IE用atachEvent(“on”+type,fn); chrome 使用addEventListener(type,fn,false);事件移除 removeEventListen,detachEvent,取消冒泡e.stopPropagation() event.cancelBubble=true;获取当前元素 e.currentTarget e.srcElement。阻止默认事件 e.preventDefault() e.returnValue=false;
  2. xhr对象,在IE7+及其他浏览器使用new XMLHttpRequest(),否则使用

    1
    2
    3
    if(window.ActiveXObject){  //IE11 if ("ActiveXObject" in window)
    xhr= new ActiveXObject("Microsoft.XMLHTTP");
    }
  3. 很多标签padding和margin的默认值不一致,在css初始的地方加入*{margin:0;padding:0;}

  4. Chrome和Safari中紧密相连的行内元素换行时会换行显示,并且不会随着布局大小自动换行显示。解决办法加入空格或者换行符。
  5. ios微信中,一个无限循环的transition动画中,长按复制失效,解决办法,要长按之前把动画暂停,长按复制这个逻辑操作结束后恢复动画。

42 Cache-Control的设置

Cache-Control头控制谁在什么条件下可以缓存以及可以缓存多久。http缓存

  1. no-cache 表示必须先于服务器确认返回的响应是否被更改,然后才能使用该响应来满足后续的同一个网址的请求,如果有ETag,no-cache会发起往返通信来验证缓存的响应,如果资源未被更改,可以避免下载。
  2. no-store 禁止缓存,每次都会发送请求,下载新的完整响应
  3. public 表示可以缓存,cdn也可以
  4. private 表示例如cdn等中继缓存不能缓存
  5. max-age 缓存有效时间
    如果要废弃缓存,比如css更新了,给html标记no-cache,给css文件加上版本号或者hash值,所以请求html时,就会请求最新的css。对于没有隐私,比如css可以允许cdn缓存。
    ETag的作用就是在缓存过期,但是资源又没有更改时,就没有必要重新下载新的,发送请求时带上If-None-Match,服务器会验证,如果一致,则返回304 Not Modified跳过下载。缓存重新启用。

43 用css3实现三角形

实现原理就是用让其余三个border为透明色,具体看这里

1
2
3
4
5
6
7
#tn{
width: 0px;
height: 0px;
border: 100px solid;
border-color:#ff3300 transparent transparent transparent ;
}
<div id="tn"></div>

44 如何检查一个变量是不是数组

一般情况下使用 instancof就可以判断,但是如下情况就不行了
example1:

1
2
3
4
5
function A(){}; 
A.prototype = [ ];
var a=new A();
alert( a instanceof Array); true
alert(a.constructor); //function Array(){[native code]}

example2:

1
2
3
4
function t(){};  
t.prototype = Array.prototype
var x = new t();
alert(x instanceof Array);//弹出true

example3:

1
2
3
4
5
6
Array.prototype = {  
splice:function(){alert(11)}
};
var arr = [];
alert(arr instanceof Array);//弹出true,说明与Array的内置原型对象的引用还是保存着的
alert(arr.splice) //弹出function splice(){ [native code]};说明上面的改变Array原型指向的代码失效,浏览器静默失败。

因为instanceof操作符的原理是如果类的原型与对象原型链上的某一个原型是同一个对象,那么instanceof运算将返回true。所以最保险的方案是:

1
2
3
if(Object.prototype.toString.call(a)=="[object Array]"){
return true;
}

45 常见的浏览器内核有哪些

Trident内核:IE,MaxThon,TT,The World,360,搜狗浏览器等。[又称MSHTML]
Gecko内核:Netscape6及以上版本,FF,MozillaSuite/SeaMonkey等
Presto内核:Opera7及以上。 [Opera内核原为:Presto,现为:Blink;]
Webkit内核:Safari,Chrome等。 [ Chrome的:Blink(WebKit的分支)]

46 给你一个正整数怎么判断它是不是平方数

  1. 开方再平方看是否相等
  2. 枚举从n/2开始枚举

47 两个单链表,怎么判断它们有没有重复节点,如何找到第一个交叉节点。

判断有没有重复节点,直接各自遍历到尾节点,看尾节点是否相同即可,因为单链表相交必然是Y型相交。时间复杂度是O(m+n),要找第一个交叉节点,

  • 用指针a,b分别先遍历两个表
  • 会有一个表先到null,这个表就是短表,把先到null的指针记为a,那另一个b则为长表的指针,这时从长表的头用指针c开始遍历,直到前一个长表头遍历指针b到null,这时c已经走了两表之间的长度差的步数
  • 此时d指针从短表开始遍历,指针c d会同时到达尾节点,所以当d==c时,这个节点就是第一个交叉节点.

48 马路上在30分钟内有车通过的概率是90%,10分钟内有车通过的概率是多少?

设10分钟有车通过的概率是x,那30分钟内没有车通过的概率是10%==(1-x)^3,所以x=54%(约等于)

49 有100瓶可乐,其中一瓶有毒,喝完60分钟后会拉肚子,最少用几个人喝酒可以找出有毒的这瓶,如果要在60分钟后立即找出有毒的这瓶,怎么找?

第一个问题,不限时间的话,最少用7个人,第一次一个人喝50瓶,每瓶都喝一点,如果拉肚子,则有毒的这瓶在这50瓶中,如果没有,则在另外50瓶中,这一次就排除了50瓶,然后让第二个人可能存在有毒的50瓶中的25瓶,同理,范围缩小到25,依次让剩下的人喝13 7 4 2 1,所以一共7个人即可。
第二个问题,要在60分钟后立即找出有毒的可乐,找7个人,编码为0-6,100瓶可乐编码为1-100,转成二进制,比如36的二进制编码为0100100,那36瓶就给编号为2 5的人喝,这样100瓶全部喝完,60分钟时看那几个人是拉肚子的,比如编码为1 3 6的人拉肚子,那就是1001010这个组合拉肚子了,那说明是74瓶是有毒的。

50 css垂直居中

  1. 绝对定位,然后margin:auto;top/bottom都为0,直接看代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    .Center-Container {
    position: relative;
    }

    .Absolute-Center {
    width: 50%;
    height: 50%;
    overflow: auto;
    margin: auto;
    position: absolute;
    top: 0; left: 0; bottom: 0; right: 0;
    }
  2. display:table;使用表格的vertical-align属性

    1
    2
    3
    4
    5
    6
    7
    wrapper {
    display:table;
    }
    #cell {
    display:table-cell;
    vertical-align:middle;
    }
  3. 绝对定位,距离top为50%,然后margin-top=-50%*height,缺点就是必须指定高度

    1
    2
    3
    4
    5
    6
    content { 
    position:absolute;
    top:50%;
    height:240px;
    margin-top:-120px; /* negative half of the height */
    }
  4. 在content元素外插入一个浮动div,设置高度为50%,然后margin-bottom:-50%*height;content清除浮动

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    floater {
    float:left;
    height:50%;
    margin-bottom:-120px;
    }
    #content {
    clear:both;
    height:240px;
    position:relative;
    }
  5. 文本垂直居中的话,设置文本line-height为对象的高度就好了

    1
    2
    3
    4
    content {
    height:100px;
    line-height:100px;
    }

效果

51 “attributes” 和 “property” 的区别是什么?

attribute是一个特性节点,该属性中包含着一个NamedNodeMap对象,该对象中包含一个类数组结构,和一些属性和方法。Element元素的每个特性都由一个Attr类型的节点表示,这些节点存储在NamedNodeMap的类数组结构中。通常要获取一个attribute节点直接使用ele.getAttribute()函数来获取,删除就是使用removeAttribute.
1)attributes中的Attr Nodes可以包含任意类型的特性,而只有HTML元素的标准特性才能作为property访问,就是说可以用“.”号来获取。
2)getAttribute()任何情况下都只能返回字符串,而在onclick上绑定事件处理程序时,使用属性方式.onclick会返回JavaScript函数。

52 前端开发中哪些情况会出现内存泄露,怎么避免

  1. DOM对象和JS对象相互引用
  2. 给DOM绑定事件后,有把这个DOM给删除了。

53 “use strict”;是什么意思 ? 使用它的好处和坏处分别是什么?

启用严格模式,消除一些js语法中不够严谨的地方及不安全的地方,增加运行速度。必须放在第一行。
1)去除with关键字;
2)局部变量在赋值前必须先声明,不会出现那种局部变量提升为全局变量的情况了;
3)函数中的this如果没有指定或者为null或者undefined,不会默认为全局。
4)构造函数内有this,如果没用new,而是直接调用的话会抛出异常,因为this会保持为undefined。
5)重复的变量名即重复的属性名均会报错
6)eval在执行时,不会在当前作用域创建变量和函数,但是可以获取eval的返回值

54 mouseover和mouseenter的区别

mouseover是会冒泡的,所以在经过绑定的DOM的子元素的时候也会触发,mouseenter不会

56

优点:解决加载缓慢的第三方内容如图标和广告,可以并行加载脚本.
缺点:iframe会阻塞主iframe的优缺点页面的onload事件,即使内容为空,加载也需要事件,没有语义,不利于seo

57 css的盒子模型

有两种:

  • IE 盒子模型: content部分包含了 border 和 pading;
  • 标准 W3C 盒模型: 内容(content)、填充(padding)、边界(margin)、 边框(border);

58 页面导入样式时,使用link和@import有什么区别?

  1. @import 机制是不同于link的,link是在加载页面前把css加载完毕,而@import url()则是页面全部下载完后再加载,所以会出现一开始没有css样式,闪烁一下出现样式后的页面(网速慢的情况下)。
  2. @import引入的css,无法用js控制DOM来修改,link可以

59 CSS选择符有哪些?哪些属性可以继承?

  1. id选择器(# myid)
  2. 类选择器(.myclassname)
  3. 标签选择器(div, h1, p)
  4. 相邻选择器(h1 + p)
  5. 子选择器(ul > li)
  6. 后代选择器(li a)
  7. 通配符选择器( * )
  8. 属性选择器(a[rel = “external”])
  9. 伪类选择器(a: hover, li:nth-child)
    可以继承的样式有:font-size,font-family,color,text-indent(缩进)

60 bind apply call的区别

61 了解的设计模式

62 css性能

63 flex都有哪些属性

64 什么是同源策略,哪些请求会遇到跨域问题,为什么有同源策略

65 哪些操作会导致页面重绘。

  1. 修改DOM
  2. 修改样式表
  3. 用户事件(鼠标悬停、页面滚动、输入框键入文字等)
    解决办法:
  4. DOM的多个操作放在一起(浏览器会智能把操作集中在一起,然后一次执行),两个读操作之间不要插入写操作,因为这会导致浏览器立即重绘。
  5. 如果某个样式是通过样式重排得到的,把结果缓存,防止再次要用这个值时再重排。
  6. 对样式的修改不要一条一条,最好通过修改class的方式一次改变。
  7. 使用离线DOM,插入DOM使用DocumenFragment、使用cloneNode方法,操作这个克隆node后再替换原始节点。
  8. 需要多次重绘的节点,可以先display:none,操作完再恢复显示。
  9. position为absolute和fixed的元素脱离文档流,重排开销很小。
  10. 使用虚拟DOM,比如React。
  11. 使用requestAnimationFrame、requestIdleCallback()调节动画渲染频次,因为受屏幕的刷新率的限制,超过屏幕的刷新率是没有意义的,只会消耗性能。

66 a标签点击不跳转的方法

  1. 直接在标签上onclick=”return false”
  2. 绑定onclick事件 e.preventDefault(),IE9之前e.returnValue = false;