Web前端面试题

1. DOCTYPE 作用,标准模式与兼容模式(怪异模式)的区别?

<!DOCTYPE>声明位于位于HTML文档中的第一行,处于 <html> 标签之前。告知浏览器的解析器用什么文档标准解析这个文档。DOCTYPE不存在或格式不正确会导致文档以兼容模式呈现。
标准模式的排版 和JS运作模式都是以该浏览器支持的最高标准运行。在兼容模式中,页面以宽松的向后兼容的方式显示,模拟老式浏览器的行为以防止站点无法工作。

2. HTML5 为什么只需要写 <!DOCTYPE HTML>?

HTML5 不基于 SGML,因此不需要对DTD进行引用,但是需要doctype来规范浏览器的行为(让浏览器按照它们应该的方式来运行)。
而HTML4.01基于SGML,所以需要对DTD进行引用,才能告知浏览器文档所使用的文档类型。

SGML是标准通用标记语言,简单的说,就是比HTML,XML更老的标准,这两者都是由SGML发展而来的。但是,HTML5不是的。

DTD:文档类型定义(Document Type Definition)

3. 行内元素有哪些?块级元素有哪些? 空(void)元素有那些?

(1)行内元素:a span img input select textarea button label
(2)块级元素:div ul ol li dl dt dd h1~h6 p pre form table tr td th thead tbody tfoot
(3)常见的空元素:br hr img input link meta

dl定义一个列表,dt定义标题,dd定义内容

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

(1)link属于XHTML标签,除了加载CSS外,还能用于定义RSS, 定义rel连接属性等作用;而@import是CSS提供的,只能用于加载CSS;
(2)页面被加载的时,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载;
(3)import是CSS2.1 提出的,只在IE5以上才能被识别,而link是XHTML标签,无兼容问题;
(4)link支持使用js控制DOM去改变样式,而@import不支持;

通过文档对象获取所有样式表对象:
document.styleSheets
通过元素获取样式表对象:
IE: 	element.styleSheet
非IE:  element.sheet
操作样式表中的样式:
	获取样式表对象: var sheet = document.styleSheets[0]
	获取规则列表: var rules = sheet.cssRules || sheet.rules 	//IE使用sheet.rules
	获取第一条规则: var rule = rules[0] 
	获取样式: var style = rule.style
	修改样式: style.backgroundColor = ‘red’ 

5. 浏览器内核的理解?

主要分成两部分:渲染引擎(layout engineer或Rendering Engine)和JS引擎。
渲染引擎:负责取得网页的内容(HTML、XML、图像等等)、整理讯息(例如加入CSS等),以及计算网页的显示方式,然后会输出至显示器或打印机。浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。所有网页浏览器、电子邮件客户端以及其它需要编辑、显示网络内容的应用程序都需要内核。
JS引擎则:解析和执行javascript来实现网页的动态效果。
最开始渲染引擎和JS引擎并没有区分的很明确,后来JS引擎越来越独立,内核就倾向于只指渲染引擎。

6. 常见的浏览器内核有哪些?

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

Webkit是苹果公司基于KHTML开发的。他包括Webcore和JavaScriptCore(SquirrelFish,V8)两个引擎。

小程序内核:
在iOS 上,小程序的 javascript 代码是运行在 JavaScriptCore 中
在Android 上,小程序的 javascript 代码是通过 X5 内核来解析
在开发工具上, 小程序的 javascript 代码是运行在 nwjs(chrome内核) 中

X5内核和chrome内核都是基于webkit内核,可以认为它们是webkit内核的一个分支。
X5内核是腾讯基于优秀开源Webkit深度优化的浏览器渲染引擎,搭载在最新一代的手机QQ浏览器上,更快,更便捷。

7. html5有哪些新特性、移除了那些元素?

绘画 canvas;用于媒体播放的 video 和 audio 元素;
本地离线存储 localStorage 和sessionStorage ;
语意化的标签元素,如 article、footer、header、nav、section;
表单控件:date、time、email、url、search;
新的技术webworker, websocket, Geolocation;

移除的元素:
纯表现的元素:basefont,big,center,font, s,strike,tt,u;
对可用性产生负面影响的元素:frame,frameset,noframes;

8. 如何处理HTML5新标签的浏览器兼容问题?如何区分 HTML 和 HTML5?

(1)IE8/IE7/IE6支持通过document.createElement方法产生的标签,可以利用这一特性让这些浏览器支持HTML5新标签,浏览器支持新标签后,还需要添加标签默认的样式。
(2)可以直接使用成熟的框架、比如html5shim;

<!--[if lt IE 9]>
  	<script> src="http://html5shim.googlecode.com/svn/trunk/html5.js"</script>
<![endif]-->

区分HTML5: DOCTYPE声明或新增的标签元素

9. 简述一下你对HTML语义化的理解?

内容结构化,结构清晰,代码容易阅读,便于维护,有利于SEO。

10. 对Web Workers的理解?

作用:解决因javascript进程的长时间执行导致用户界面的阻塞。

注意事项:

  1. 同源限制,worker线程的脚本文件和主线程的脚本文件必须同源。
  2. 不能访问DOM,不能使用document、window对象,但可以使用navigator和location对象。
  3. worker线程和主线程的通信必须通过消息完成。
  4. 可以使用XMLHttpRequest发起AJAX请求。
    Worker中的self对象实际指向的就是worker对象,而javascript中默认情况下self指向的是window对象。
    消息内容是任何能够被序列化的值。
var worker = new Worker('test.js'); // 创建一个WebWorker对象
worker.onmessage = function (event) { // 处理消息
	var data = event.data // 保存来自Worker的数据
	self.close() // 停止工作,与terminate方法一致
}
worker.postMessage(data); // 发送消息
worker.terminate(); // 停止Worker的工作

11. 对Web Sockets的理解?

作用:实现全双工和双向通信。(全双工:数据在两个方向上传输,A -> B B -> A瞬间同步)

建立的连接会使用HTTP升级,从HTTP协议交换为Web Socket协议,即使用标准的HTTP服务器无法实现Web Socket,只有专门支持这种协议的专门服务器才能正常工作。

不受同源策略的限制。只能通过连接发送纯文本数据。因此发送的数据必须进行序列化,从服务端接受的数据也需要解析。

// 创建一个WebSocket对象
var socket = new WebSocket("ws://www.example.com/server.php");
socket.onmessage = function (event) { // 处理数据
	var data = event.data
}
socket.send(JSON.stringify(message));
socket.close(); // 此时的socket.readyState = 2,关闭后值变为3。

WebSocket的状态(readyState):

  1. WebSocket.OPENING(0): 正在建立连接。
  2. WebSocket.OPENING(1): 已经建立连接。
  3. WebSocket.OPENING(2): 正在关闭连接。
  4. WebSocket.OPENING(3): 已经关闭连接。

事件:
open: 在成功建立连接时触发。
error: 在发生错误时触发。
close: 在连接关闭时触发。

12. HTML5的离线存储的使用以及工作原理?

在用户没有与因特网连接时,可以正常访问站点或应用,在用户与因特网连接时,更新用户机器上的缓存文件。

原理:HTML5的离线存储是基于一个新建的.appcache文件的缓存机制(不是存储技术),通过这个文件上的解析清单离线存储资源,这些资源就会像cookie一样被存储了下来。当网络处于离线状态下时,浏览器会通过被离线存储的数据进行页面展示。

// CACHE MANIFEST - 列出的文件将在首次下载后进行缓存
// NETWORK - 列出的文件需要与服务器连接,且不会被缓存
// FALLBACK - 当页面无法访问时的回退页面(比如 404 页面)

CACHE MANIFEST
  	#comment
  	CACHE:
  	js/app.js
  	css/style.css
  	NETWORK:
  	resourse/logo.png
  	FALLBACK:
  	404.html
  	
// 使用
<html manifest= "/offline.appcache">
// 推荐使用.appcache作为文件的扩展名,也可使用.manifest。

13. 浏览器如何对HTML5的离线储存资源进行管理和加载?

在线的情况下,浏览器发现html头部有manifest属性,它会请求manifest文件,如果是第一次访问app,那么浏览器就会根据manifest文件的内容下载相应的资源并且进行离线存储。如果已经访问过app并且资源已经离线存储了,那么浏览器就会使用离线的资源加载页面,然后浏览器会对比新的manifest文件与旧的manifest文件,如果文件没有发生改变,就不做任何操作,如果文件改变了,那么就会重新下载文件中的资源并进行离线存储。
离线的情况下,浏览器就直接使用离线存储的资源。

14. cookies,sessionStorage 和 localStorage 的区别?

  1. 数据都是存储在客户端。
  2. cookie存储的数据量要比sessionStorage和localStorage存储的数据量要少。cookie存储的数据不能超过4k,而sessionStorage和localStorage存储的数据量可以达到5M或更大。
  3. sessionStorage在用户关闭浏览器时,存储的数据消失。localStorage是持久存储,除非用户主动删除本地的数据。cookie在过期时间之前数据都是有效的。

15. H5如何禁用表单的自动完成功能?

设置autocomplete属性值为off。(默认为on)

16. 如何实现浏览器内多个标签页之间的通信?

方法一: 使用localStorage。

  1. 在一个标签页里面使用 localStorage.setItem(key,value)添加(修改、删除)内容;
  2. 在另一个标签页里面监听 storage 事件。 即可得到 localstorge 存储的值,实现不同标签页之间的通信。
// 页面一
<input id="name">  
<input type="button" id="btn" value="提交">  
<script type="text/javascript">  
    $(function(){    
        $("#btn").click(function(){    
            var name=$("#name").val();    
            localStorage.setItem("name", name);   
        });    
    });    
</script> 

// 页面二
<script type="text/javascript">  
    $(function(){   
        window.addEventListener("storage", function(event){    
            console.log(event.key + "=" + event.newValue);    
        });     
    });  
</script>

方法二:使用cookie + setInterval。
将要传递的信息存储在cookie中,每隔一定时间读取cookie信息,即可随时获取要传递的信息。

// 页面一
<input id="name">  
<input type="button" id="btn" value="提交">  
<script type="text/javascript">  
    $(function(){    
        $("#btn").click(function(){    
            var name=$("#name").val();    
            document.cookie="name="+name;    
        });    
    });    
</script> 

// 页面二
<script type="text/javascript">  
    $(function(){   
        function getCookie(key) {    
            return JSON.parse("{\"" + document.cookie.replace(/;\s+/gim,"\",\"").replace(/=/gim, "\":\"") + "\"}")[key];    
             // 将获取到的cookie值转化为对象,先将分号替换为逗号,再将 = 替换为 :
        }     
        setInterval(function(){    
            console.log("name=" + getCookie("name"));    
        }, 10000);    
    });  
</script> 

方法三:使用WebSocket

方法四:使用SharedWorker
共享工作线程允许多个页面共享使用,每个页面都是链接到该共享工作线程的某个端口号上。页面通过该端口与共享工作线程进行通信。

SharedWorker可以被多个window共同使用,但必须保证这些标签页都是同源的(相同的协议,主机和端口号)。

17. 页面可见性(Page Visibility API) 可以有哪些用途?

  1. 通过 visibilityState 的值检测页面当前是否可见。
  2. 检测打开网页的时间。
  3. 在页面被切换到后台时,自动暂停音乐或视频的播放。(标签页之间的切换或浏览器最小化即为进入后台)

API:
document.hidden: 表示当前页面可见还是不可见(boolean)。
document.visibilityState: 返回当前页面的可见状态(四种)。
即:hidden、visible、prerender(预渲染)、preview(预览)

18. 如何在页面上实现一个圆形的可点击区域?

(1)map+area或者svg。

// map + area
<img src="t.jpg" width="1366" height="768" border="0" usemap="#Map" />
<map name="Map" id="Map">
 <area shape="circle" coords="821,289,68" href="www.baidu.com" target="_blank" />
</map>

// svg
<svg><circle cx="100" cy="50" r="40" fill="red" /></svg> 

(2)border-radius。
(3)纯js实现:通过点击的位置判断其是否在圆上。

document.onclick=function(e){
    var r=50;//圆的半径
	var x1=100,y1=100,x2= e.clientX;y2= e.clientY;
	//计算鼠标点的位置与圆心的距离
    var len=Math.abs(Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2)));
    if(len<=50){
        console.log("内")
    }else{
        console.log("外")
    }
}

19. 盒子模型的理解?

  1. 盒子模型分为两种:IE盒子模型和w3c盒子模型。
  2. 盒模型: 边界(margin)、 边框(border)、填充(padding)、内容(content)。
  3. IE盒子模型中的width包含border、padding和content。而w3c盒子模型中的width即为content部分。即IE盒子的宽高:margin + width | height。w3c盒子模型的宽高:margin + border + padding + height | width

附:在调试时所看到的宽高包含了border、padding以及元素的宽高。不包含margin。

20. 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。
css选择器学习地址:http://www.runoob.com/cssref/css-selectors.html

21. 实现div元素的垂直水平居中

// 方法一
div {
	position: absolute;
	top: 0;
	left: 0;
	right:0;
	bottom: 0;
	width: 200px;
	height: 200px;
	margin: auto;
}

// 方法二
div {
	position: absolute;
	left: 50%;
	top: 50%;
	margin-left: -100px;
	margin-top: -100px;
	width: 200px;
	height: 200px;
}

// 方法三
div {
	position: absolute;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%);
	width: 200px;
	height: 200px;
}

// 方法四
.container {
	display: flex;
}
div {
	width: 200px;
	height: 200px;
	margin: auto;
}

// 方法五
.container {
	display: flex;
	justify-content: center;
	align-items: center;
}
div {
	width: 200px;
	height: 200px;
}

22. position定位

  1. static :默认值,元素出现在正常流中。
  2. relative:相对定位,相对于正常位置定位,原位置被占据。
  3. fixed:固定定位,相对于浏览器窗口定位。
  4. absolute:绝对定位,相对于static定位以外的第一个父元素定位,如果没有定位的祖先元素,则相对于最初的包含块定位。后继元素会占据它原本的空间,元素脱离文档流。
  5. sticky:基于用户的滚动位置来定位。在 position:relative 与 position:fixed 定位之间切换。
    它的行为就像 position:relative; 而当页面滚动超出目标区域时,它的表现就像 position:fixed;,它会固定在目标位置。
    元素定位表现为在跨越特定阈值前为相对定位,之后为固定定位。
    这个特定阈值指的是 top, right, bottom 或 left 之一,换言之,指定 top, right, bottom 或 left 四个阈值其中之一,才可使粘性定位生效。否则其行为与相对定位相同。
  6. inherit:从父元素继承 position 属性的值。

23. 用CSS创建一个三角形的原理?

把上、左、右三条边隐藏掉(颜色设为 transparent)
  #demo {
    width: 0;
    height: 0;
    border-width: 20px;
    border-style: solid;
    border-color: transparent transparent red transparent;
  }

24. 满屏的"品"字布局设计?

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <style type="text/css">
        *{
            margin: 0;
            padding: 0;
        }
        html, body{
            height: 100%;
        }
        .header{
            height: 50%;
            width: 50%;     
            background: #ccc;           
            margin: 0 auto;
        }
        .main{
            width: 100%;
            height: 50%;
            background: #ddd;
        }
        .left,.right{
            float: left;
            width: 50%;
            height: 100%;
            background: yellow;
        }
        .right{
            background: green;
        }
    </style>
</head>
<body>
<div class="header"></div>
<div class="main">
    <div class="left"></div>
    <div class="right"></div>
</div>
</body>
</html>

附: html、body元素均为块级元素(display:block)。
head、style、meta元素表现为display: none。
li元素表现为display: list-item(作为列表显示)。

25. 实现css多列等高的效果?

父元素设置overflow: hidden,子元素设置padding-bottom、margin-bottom正负相抵,此时父容器的高度为没有设定padding-bottom时的高度,当其中任一列高度增加,则父容器的高度会被撑到里面最高那列的高度,其他比这列矮的列会用padding-bottom补偿这部分高度差。

<!DOCTYPE html>
<html>
  <head>
  <meta charset="utf-8">
  <style>
 .container {
    margin: 0 auto;
    overflow: hidden;
    width: 300px;
  }
  .common {
    margin-bottom: -1000px;
    padding-bottom: 1000px;
  }
  .left, .right {
    float: left;
  }
  .left {
    width: 250px;
    background-color: pink;
  }
  .right {
    width: 50px;
    background-color: skyblue;
  }
  </style>
</head>
<body>
<div class="container">
  <div class="left common">
    <p>自适应高度</p>
  </div>
  <div class="right common">
    内容内容内容内容内容内容内容内容内容内容内容内容内容
  </div>
</div>
</body>
</html>

26. CSS中<li>之间的空白间隔如何解决或inline-block元素产生的空白?

<html>
  <head>
    <title>demo</title>
    <style type="text/css">
    * {
      margin:0;
      padding:0;
    }
    li {
      width: 100px;
      height: 100px;
      display: inline-block;
      list-style: none;
    }
    #li1 {
      background: red;
    }
    #li2 {
      background: blue;
    }
    #li3 {
      background: yellow;
    }
    #li4 {
      background: black;
    }
    </style>
  </head>
  <body>
    <ul>
      <li id="li1"></li>
      <li id="li2"></li>
      <li id="li3"></li>
      <li id="li4"></li>
    </ul>
  </body>
  </html>

产生原因: 浏览器会把inline元素间的空白字符(空格、换行、Tab等)渲染成一个空格。

解决方法:

  1. 为 li 设置float: left。不足:有些容器是不能设置浮动,如左右切换的焦点图等。
  2. 将所有 li 写在同一行。不足:代码不美观。
  3. 将 ul 内的字体大小设为0,即font-size: 0,子元素 li 的font-size值重新设置。不足: 不兼容Safari浏览器。
  4. 消除 ul 的字符间隔letter-spacing: -8px,而这也设置了 li 内的字符间隔,因此需要将 li 内的字符间隔设为默认letter-spacing: normal(Firefox、Safari空白间隔为4px,Chrome为8px) 。
  5. 设置margin-left负值。
  6. 设置word-spacing负值,原理等同于letter-spacing。

27. img元素底部出现空白的原因及解决办法?

原因:受vertical-align的影响,元素默认的对齐方式为基线对齐,即vertical-align: baseline; 而空白的间隔即为baseline和bottom之间的距离。

解决办法:

  1. vertical-align: top | middle | bottom;
  2. display: block;
  3. line-height: 0;
  4. font-size: 0;

设置line-height: 0生效的原因:line-height值为两个基线之间的距离,其值为0表明baseline和bottom之间的距离为0,故生效。而line-height的默认值为normal,一般认为其值为1或1.2,受font-size的影响,因此设置font-size: 0也可生效。
vertical-align只能作用于inline以及table-cell元素。设置display: block后vertical-align失效。

28. line-height设置为数值和百分比值的区别?

数值:
根据父元素的font-size值计算line-height的值,子元素继承line-height的数值,根据自身的font-size再次计算line-height的值。

百分比值:
根据父元素的font-size值计算line-height的值,子元素继承计算后的line-height值。

<div style="line-height:200%;font-size:32px"> <!-- line-height为200%*32 = 64 -->
    <p style="font-size:24px;">行间距</p> <!-- line-height为64px -->
</div>

<div style="line-height:2;font-size:32px"> <!-- line-height为64px -->
    <p style="font-size:24px;">行间距</p> <!-- line-height为48px -->
</div>

29. 什么是 FOUC?你如何来避免 FOUC?

FOUC:Flash Of Unstyled Content ,无样式内容闪烁。
产生原因: 使用@import导入css文件。
页面加载时会加载DOM,最后再导入引入的css文件,导致页面的内容一段时间可能没有样式。
解决方法: 使用 link 标签引入css文件。

30. css包含块的理解?

包含块(Containing Block)与框模型类似,可以理解为一个矩形,这个矩形的作用是为它里面包含的元素提供一个参考,元素的尺寸和位置的计算往往是由该元素所在的包含块决定的。

包含块简单说就是定位参考框,或者定位坐标参考系,元素一旦定义了定位显示(相对、绝对、固定)都具有包含块性质,它所包含的定位元素都将以该包含块为坐标系进行定位和调整。

包含块的定义:

  1. 用户代理(比如浏览器)选择根元素作为 containing block(称为初始 containing block)。
  2. 非定位元素containing block 由最近的块级祖先元素盒子的内容边界组成。
  3. position:fixed的元素的containing block 由视口建立。
  4. position:absolute的元素的containing block 由非 static定位的祖先建立,按下面的步骤:

(1) 祖先是块级元素,containing block 由祖先的 padding edge(padding+content区域) 形成。
(2) 祖先是内联元素,containing block 取决于祖先的 direction 属性。
①direction 是 ltr,祖先产生的第一个盒子的上、左内容边界是 containing block 的上方和左方,祖先的最后一个盒子的下、右内容边界是 containing block 的下方和右方。
②direction 是 rtl,祖先产生的第一个盒子的上、右内容边界是 containing block 的上方和右方,祖先的最后一个盒子的下、左内容边界是 containing block 的下方和左方。
(3) 没有祖先,根元素盒子的内容边界为containing block。

31. visibility: collapse的作用?
当在表格元素中使用时,可删除一行或一列,表现形式等同于display: none;如果用在其他的元素上则表现为visibility: hidden。

32. position、float、display特性的相互作用?

  1. 如果元素的display为none,那么元素不被渲染,position、float不起作用。
  2. 如果元素设置了position: absolute;或者position: fixed;此时设置float失效。
  3. 元素设置float:非none,position: absolute,position: fixed时元素会脱离文档流。
  4. 浮动、绝对定位、inline-block属性的元素,竖直方向上的margin不会重叠,只有普通文档流中块框的垂直边界才会发生重叠。

33. 对 BFC 和 IFC 的理解?

BFC用法见:https://segmentfault.com/a/1190000009545742
BFC:决定一个元素如何定位以及与其它元素之间的相互作用。

形成BFC的条件:

  1. 根元素
  2. float的属性不为none
  3. position为absolute或fixed
  4. display为inline-block,table-cell,table-caption
  5. overflow不为visible

BFC布局规则:

  1. 内部的盒子会在垂直方向上一个个地放置。
  2. 盒子垂直方向的距离由margin决定,属于同一个BFC的两个相邻Box的上下margin会发生重叠。
  3. 每个元素的左边,与包含的盒子的左边相接触,即使存在浮动也是如此。
  4. BFC的区域不会与float重叠。
  5. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之也如此。
  6. 计算BFC的高度时,浮动元素也参与计算。

IFC布局规则:

  1. 在一个行内格式化上下文中,盒是一个接一个水平放置的,从包含块的顶部开始。
  2. 这些盒之间的水平方向的margin,border和padding都有效。

34. 为什么需要清除浮动以及清除浮动的方式?

浮动的元素会导致父元素高度塌陷,影响后面的布局。

清除浮动的方法:

  1. 给父元素设置overflow: hidden,触发父元素的BFC,在计算高度时会包含float元素的高度。
  2. 增加一个子元素,设置clear: both。
  3. 给父元素设置float。
  4. 使用伪类:
.clearfix::after,.clearfix::before{
    content: "";
    height:0;
    line-height: 0;
    display: block;
    visibility: hidden;
    clear: both;
}

35. 什么是外边距合并?
两个垂直外边距相遇时会合并成一个外边距,合并后的外边距的高度等于两个外边距高度中的最大者。

36. 对zoom: 1的理解?
zoom可以用来解决IE下外边距重叠,清除浮动,触发ie的haslayout属性。
zoom的值用来表示当前元素扩大或缩小多少,设置后会使当前元素重新计算高度和宽度。

37. 媒体查询的了解?
@media 可以针对不同的屏幕尺寸设置不同的样式,用于设计响应式页面。
附:@media中的 max-width 和 min-width 的区别:
max-width 表明页面的 width <= max-width 时生效,min-width 表示页面的 width >= min-width 时生效。

38. css匹配规则?
从上到下,从右到左。
从右到左的优势:如果是从左到右,会一个节点一个节点的往下找,没有找到需要回溯到上一个节点,损失性能。而从右到左在开始时就会过滤到许多节点,更加的高效。

39. CSS 优化、提高性能的方法?
(1) 将样式写在单独的css文件中。
优点:
1. 内容和样式分离,便于管理和维护。
2. 减少页面体积。
3. css文件可以被缓存。
(2) 不使用@import。
(3) 选择器层级越少越好。
简洁的选择器可以减少css文件大小,提高页面的加载性能,浏览器解析时更加高效。
(4) 精简页面的样式文件,去掉不用的样式。
(5) 利用CSS继承减少代码量。

40. 浏览器是怎样解析CSS选择器的?

从上到下,从右到左
从右到左的优势:如果是从左到右,从当前节点一个一个向下找,如果没找到则需要回溯,损失性能。而从右到左则只需向上寻找,过滤了很多节点,提升了性能。

41. 如何使Chrome支持小于12px 的文字?

  1. 使用图片替代。
  2. 设置如下样式:
	font-size : 12px;
	-webkit-transform : scale(0.84,0.84) ;
	*font-size:10px; // IE
	// IE 和 Firefox允许设置的字体小于12px

42. IOS下设置overflow: scroll时滑动卡顿?

// 设置
-webkit-overflow-scrolling: touch; // 启用了硬件加速特性,所以滑动很流畅

43. 高度自适应的div中有两个div,一个高度200px,希望另一个填满剩下的高度?

<div class="container" id="div">
      <div></div>
      <div></div>
 </div>

方法一:使用flex布局

	.container {
      background-color: silver;
      width: 400px;
      height: 600px;
      display: flex;
      flex-direction: column; 
      // 实际上使得flex在纵向起作用,若div1设置flex: 2, div2设置flex: 1,则div1占高度的2/3,div2占高度的1/3。
    }
    .container div:nth-of-type(1) {
      width: 200px;
      height: 200px;
      background-color: red;
    }
    .container div:nth-of-type(2) {
      width: 200px;
      flex: 1;
      background-color: pink;
    }

方法二:使用calc函数

    .container {
      background-color: silver;
      width: 400px;
      height: 600px;
    }
    .container div:nth-of-type(1) {
      width: 200px;
      height: 200px;
      background-color: red;
    }
    .container div:nth-of-type(2) {
      width: 200px;
      height: calc(100% - 200px);
      background-color: pink;
    }

方法三:使用绝对定位

    .container {
      position: relative;
      background-color: silver;
      width: 400px;
      height: 600px;
    }
    .container div:nth-of-type(1) {
      width: 200px;
      height: 200px;
      background-color: red;
    }
    .container div:nth-of-type(2) {
      position: absolute;
      top: 200px;
      bottom: 0;
      width: 200px;
      background-color: pink;
    }

44. js有哪些内置对象?

 数据封装类对象:Object、Array、Boolean、Number 和 String
 其他对象:Function、Arguments、Math、Date、RegExp、Error

45. 原型和原型链?

每个对象内部都有一个属性,即prototype属性,称为原型属性,当我们访问一个对象的属性时,如果对象内部没有这个属性,那么他会去它的原型上找这个属性,这个原型内部又有自己的prototype属性,如果没找到就会一直找下去,构成一个原型链。

var obj = new Object();
obj.__proto__ // obj对象的原型
obj.__proto__ === Object.prototype // true
Object.prototype.constructor === Object // true

Object.prototype对于Object来说是它的原型属性,而对于创建的实例来说是它的原型对象,其内部封装了许多属性和方法,为创建的所有实例所共享。

46. Javascript作用域链?

在当前作用域访问某个变量或方法时,如果当前作用域没有,则会去它的上层作用域中寻找,直至全局作用域,形成作用域链。

47. this的理解?

this总是指向函数的调用者,this不是在函数定义时确定的,而是在函数执行的时候确定的。
在事件中,this指向触发这个事件的对象,特殊的是,IE中的attachEvent中的this是指向全局对象Window。

48. eval函数的理解?
参数:接受一个字符串,如果不是直接返回,不做处理。
特点:

  1. 执行内部的javascript代码。
  2. 可以将JSON数据解析成JSON对象(JavaScript对象)。
  3. 不安全,如果解析第三方JSON数据,可能数据中含有恶意代码。

详细用法见:https://www.cnblogs.com/zichi/p/5202825.html

49. DOM对象和BOM对象的理解?
BOM对象的顶级对象是window对象,DOM对象的顶级对象是document对象,document对象是window对象的一个属性。
即 window.document === document
BOM对象中的navigator、location、screen、history对象均是window对象的一个属性。

50. null 和 undefined的区别?

(1) null表示一个空对象,undefined表示一个变量声明未赋值。
(2) null转化为数值时为0,undefined转化为数值为NaN。
(3) null是原型链的终点。

Object.prototype.__proto__  === null // ture
Object.getPrototypeOf(Object.prototype) === null // true

值为undefined的情况:

  1. 变量声明未赋值。
  2. 调用函数时,应该传入的参数未传入,该参数为undefined。
  3. 访问对象中不存在的属性或数组中不存在的数据。
  4. 函数没有返回值,默认为undefined。

51. [“1”, “2”, “3”].map(parseInt) 的结果?

分析:传入parseInt相当于传入parseInt指向的函数,接受两个参数为str(字符串类型)和radix(进制),表示用指定进制解析str,如parseInt(“11”, 2)返回3。
map函数默认传入element,index,array。因此运算类似于:

parseInt("1", 0) // 1
parseInt("2", 1) // NaN
parseInt("3", 2) // NaN
运算结果为:[1, NaN, NaN]

52. 使用JS方式将两个数的值互换?

// 方法一: 
var temp;
temp = x;
x = y;
y = temp;

// 方法二:
x = x + y;
y = x - y;
x = x - y;

// 方法三:(使用位运算符异或,原理:x ^ x = 0)
x = x ^ y
y = x ^ y
x = x ^ y

53. IE与火狐的事件机制有什么区别? 如何阻止冒泡?

IE8及更早版本只支持是事件冒泡,Firefox支持两种事件机制,事件捕获和事件冒泡。
阻止冒泡:
非IE:e.stopPropagation() (即能阻止事件捕获也能阻止事件冒泡)
IE:e.cancelBubble = true

附:
事件流分为三个阶段:事件捕获、目标阶段、冒泡阶段。
事件的目标阶段通过addEventListener中的第三个参数设置其在捕获阶段触发还是在冒泡阶段触发,默认为false在冒泡阶段触发。IE中的attachEvent只支持冒泡事件。

54. "use strict"的使用及优点?

“use strict”:启用严格模式。

  1. 使用未声明的变量会报错。
  2. 不允许使用delete删除变量或对象。
  3. 全局中的this值为undefined。
  4. 不允许使用with等。

优点:消除了代码的不安全,提高了编译器效率,提升了运行速度。

附:
with作用:将代码的作用域设置到一个特定的作用域中。
缺点:js解释器会检查with块中的变量是否属于with包含的对象,降低了with语句的执行效率。

55. 判断某个变量的类型?

使用Object.prototype.toString.call()

例:

var arr = [];
Object.prototype.toString.call(arr); // "[object Array]"

var num = 10;
Object.prototype.toString.call(num); // "[object Number]"

56. JavaScript中查找属性时,不会去原型上查找的函数是?

hasOwnProperty()

57. 解释下列代码?

 [].forEach.call($$("*"),function(a){a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16)})

运行效果:在Chrome浏览器的控制台中输入这段代码,会发现不同HTML层都被使用不同的颜色添加了一个高亮的边框。

$$('*') 等价于 document.querySelectorAll("*"),获取当前页面的所有元素节点,返回一个NodeList对象。

~ :按位取反:先把二进制的编码加上一位,再取反。
~~ 替代了Math.floor,运算效率更高。

详见:https://my.oschina.net/l3ve/blog/330358

58. 如何解决跨域问题?

jsonp、postMessage、 document.domain、webSocket、window.name

详见:https://blog.csdn.net/Joyhen/article/details/21631833?utm_source=blogxgwz0

59. 异步加载JS的方式?

(1) defer,只支持IE。
(2) async。
(3) 创建script,插入到DOM中,加载完毕后callBack。

function addScriptTag(src){
	var script = document.createElement('script');
	script.setAttribute("type","text/javascript");
	script.src = src;
	document.body.appendChild(script);
}
window.onload = function(){
	addScriptTag("js/index.js");
}

60. documen.write和 innerHTML的区别?

document.write能重绘整个页面,innerHTML重绘页面的一部分。

61. innerHTML 和 innerText 的理解?

innerHTML:获取值时返回所有的子节点(包括元素、注释和文本节点)。
innerText:获取值时返回子节点中所有文本拼接后的值,会解析转义后的字符。

innerHTML:设置值时,如果为字符串直接写入,如果为HTML字符串,浏览器会将此字符串解析为相应的DOM树(会对字符转义)。因此再获取值时和设置的值有所不同:
innerText:设置值时,如果为HTML字符串,会将其转义,使用innerHTML获取的值为转义后的值,再次使用innerText获取的值即为设置的值,因为其会对转义后的字符再次转义。

    div.innerHTML = "<p>hello & world</p>";
    console.log(div.innerHTML) // <p>hello &amp; world</p>
<body>
    <div class="container" id="div">
      <div>111&amp;</div>
    </div>
</body>
<script>
    var div = document.getElementById("div");
    console.log(div.innerHTML)  // <div>111&amp;</div>
    console.log(div.innerText) // 111&
    div.innerText = "<p>hello & world</p>";
    console.log(div.innerText) // <p>hello & world</p>
    console.log(div.innerHTML) // &lt;p&gt;hello &amp; world&lt;/p&gt;
</script>

附:并不是所有的元素都支持innerHTML属性,如head,style,html就不支持。

过滤掉所有的HTML标签的方法:div.innerText = div.innerText。

62. DOM操作?

(1) 创建节点
文本节点:document.createTextNode()
元素节点:document.createElement()
文档片段:document.createDocumentFragment()
注释节点:document.createComment()

(2)添加、插入、替换、复制节点
appendChild()
insertBefore()
replaceChild()
cloneNode() // true深复制,false为浅复制,只复制节点本身

(3)获取元素节点
document.getElementById()
document.getElementsByTagName()
document.getElementsByName()
document.getElementsByClassName()
document.querySelector()
document.querySelectorAll()

(4)其它属性
childNodes
parentNode
firstChild
lastChild
previousSibling
nextSibling

63. call和apply的区别?

作用:都是将函数绑定到另一个对象上运行。

区别:apply传递的是参数数组而call传递的是参数列表,即参数需要一个一个列举出来。

64. 内存泄漏可能的情况?

  1. 闭包(函数中存在变量的引用,不会被gc回收)。
  2. 清除dom时未清除其绑定的事件(IE不会做出恰当的处理)。
  3. 对未声明的变量的引用(在全局对象内创建一个新变量)。
function fn() {
    s = "hello"
}
// 等价于
function fn () {
	window.s = "hello"
}
// 解决办法:启用严格模式,"use strict";

65. JavaScript实现千位分隔符?

function commafy(num) {
      return num && num
          .toString()
          .replace(/(\d)(?=(\d{3})+\.)/g, function($0, $1) {
              return $1 + ",";
          });
  }
  console.log(commafy(1234567.90)); //1,234,567.90

66. 如何检测浏览器版本?

使用navigator.userAgent

67. What is a Polyfill?

兼容旧版浏览器,检查浏览器是否支持某个标准 API,如果不支持,就使用旧的技术对浏览器做兼容处理,使新标准的 API能够在旧的浏览器上使用。

68. IE 与其他浏览器不一样的特性?

  1. 非IE中使用event表示事件对象,IE中使用window.event表示事件对象。
  2. 事件目标:
    IE中window.event.srcElement
    Firefox下,e.target
    Chrome下,e对象同时具有target和srcElement属性
  3. 事件监听:
    IE:attachEvent
    非IE:addEventListener
  4. 阻止默认行为:
    IE:window.event.returnValue = false
    非IE:event.preventDefault()
  5. 阻止事件冒泡:
    IE:window.event.cancleBubble = true
    非IE:event.stopPropagation()
// 兼容性写法:
// 阻止默认行为
if (event && event.preventDefault) {
	event.preventDefault();
} else {
	window.event.returnValue = false;
}

// 阻止事件冒泡
if (event && event.stopPropggation) {
	event.stopPropagation();
} else {
	window.event.cancelBubble = true;
}

69. 前端性能优化的方法?

  1. 减少http请求次数,代码压缩,使用合适的图片大小。
  2. 减少Dom操作。
  3. 避免使用css表达式(expression)。
  4. 将js脚本至底。
  5. 使用浏览器缓存文件。
  6. 使用CDN加速。

70. 什么是置换元素?

置换元素:浏览器根据元素的标签和属性来决定元素显示的内容,一般来说,置换元素都是空元素,如input、textarea、select、img。

71. 浏览器线程有哪些?

  1. GUI 渲染线程
  2. JavaScript引擎线程
  3. 定时触发器线程
  4. 事件触发线程
  5. 异步http请求线程

GUI渲染线程与JavaScript引擎为互斥的关系,当JavaScript引擎执行时GUI线程会被挂起,GUI更新会被保存在一个队列中等到引擎线程空闲时立即被执行。

详见:http://www.imweb.io/topic/58e3bfa845e5c13468f567d5

72. 待续。。。?

React部分:

1. 调用this.setState做了什么?

React中的setState有两种模式,分别是普通模式和批量更新模式,普通模式下,当调用setState时React会将setState中的对象与当前组件的状态合并,重新构建虚拟DOM并将当前的DOM树和上一次的DOM树进行对比,通过diff算法计算出相应的更新策略,然后只更新变化的那部分。批量更新模式则是先把setState中的对象存入一个更新队列中,稍后会将队列中新的状态合并到state中,再重新触发render。

附:调用setState时一定会触发重新渲染,即使新的state和旧的state相同,此时如果不希望重新渲染可以通过shouldComponentUpdate(nextProps, nextState)控制,return true表示重新渲染,return false表示不渲染,并且必须有return语句。

2. React中元素和组件的区别?

元素:React元素不是真实的DOM元素,只是普通的JS对象。

// React元素
const element = <div className="element">I'm element</div>

组件:React组件是由元素构成的,组件可能是个类也可能是个函数。

3. React中什么时候使用类组件,什么时候使用函数式组件?

组件具有状态( state )或生命周期方法时使用类组件。否则,使用函数式组件。

附:函数式组件只有props,没有state,有state的称为有状态组件,无state称为无状态组件。状态会带来管理的复杂性,所以应尽量多写无状态组件,少写有状态组件,即多使用函数式组件。

4. refs的理解?

可以refs来直接访问DOM元素或组件实例。

import React from 'react'
export default class Input extends React.Component {
  constructor(props) {
    super(props);
    this.focusTextInput = this.focusTextInput.bind(this);
  }
  focusTextInput() {
    this.input.focus();
  }
  render() {
    return (
      <div>
        <input
          type="text"
          ref={input => this.input = input} />  
        <input
          type="button"
          value="Focus the text input"
          onClick={this.focusTextInput}
        />
      </div>
    );
  }
}

5. React的受控组件和非受控组件的区别?

  1. 受控组件是由React来控制表单元素的值,一般来说,表单元素的值存在组件的状态中,修改表单元素值时只需调用setState即可。
  2. 受控组件中需要为数据可能发生变化的每一种方式都编写一个事件处理程序,比较繁琐。
  3. 受控组件支持即时字段验证,允许有条件地禁用/启用按钮,强制输入格式。
  4. 非受控组件使用ref从dom元素中获取表单的值,将真实的数据保存在dom中。

6. 哪些生命周期函数中不能调用setState?

  1. componentWillUpdate,shouldComponentUpdate,render会导致不断循环更新,造成死循环。
  2. componentWillUnMount:组件即将被卸载,setState是为了更新组件,在一个即将卸载的组件上更新state显然是无意义的。

附:componentDidUpdate中调用setState需要加判断条件,否则也会造成死循环。

7. React应该在哪个生命周期中请求数据?

应该在componentDidMount中请求数据,不提倡在componentWillMount中请求数据,原因:未来的React可能为了提高性能多次触发componentWillMount,这样就会使得数据请求多次。

附:在componentWillMount中直接调用this.setState并不会重新触发render,而是将当前的setState中的对象与组件状态合并,只会触发一个render方法。而不是先触发一个render,调用setState再触发一次render。如果想要再次触发render,可以将setState置于setTimeout中。

只有在render和componentDidUpdate中才能获取到更新后的state。

8. 组件更新时生命周期函数的调用顺序?

componentWillReceiveProps -> shouldComponentUpdate -> componentWillUpdate -> render -> componentDidUpdate

即:组件收到新的props(props中的数据并不一定真正发生变化)-> 决定是否需要继续执行更新过程 -> 组件代表的虚拟DOM即将更新 -> 组件重新计算出新的虚拟DOM -> 虚拟DOM对应的真实DOM更新到真实DOM树中。

9. render次数和浏览器界面更新次数一致吗?

不一致,如下:

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      bgColor: "red"
    }
  }
  render() {
    var {bgColor} = this.state
    return (
      <div style = {{backgroundColor: bgColor}}> 
        Test
      </div>
    );
  }
  componentDidMount() {
    this.setState({
      bgColor: "yellow"
    })
  }
}

浏览器渲染页面时并不会从红色变为黄色,而是直接显示为黄色。
原因:虽然render方法被调用了两次,但这并不会导致浏览器界面更新两次,实际上,两次DOM的修改会合并成一次浏览器界面的更新。虽然JS的执行和DOM的渲染分别由浏览器不同的线程完成,但JS的执行会阻塞DOM的渲染,而上面的两次render是在一个JS事件周期内执行的,所以在两次render结束前,浏览器不会更新界面。

10. 为什么要使用 React.Children.map(props.children,() => {} ) 而不是 props.children.map( () => {} )?

原因:props.children时返回的可能是一个对象(只有一个子元素)也可能是一个数组(有多个子元素)。如果返回的是一个对象调用map方法时就会报错。

11. react性能优化是哪个周期函数?

shouldComponentUpdate 这个方法用来判断是否需要调用render方法重新描绘dom。因为dom的描绘非常消耗性能。

12. diff算法的理解?

  1. 把树形结构按照层级分解,只比较同级元素。

  2. 给列表结构的每个单元添加唯一的key属性,方便比较。

  3. React 只会匹配相同 class 的 component(这里面的class指的是组件的名字)。

  4. 合并操作,调用 component 的 setState 方法的时候,React 将其标记为 dirty.到每一个事件循环结束, React 检查所有标记 dirty 的 component 重新绘制。

附:React的diff算法复杂度由 O(n^3) 变为 O(n) 。

React的diff算法给树进行编号,只需要比较同一级的,故复杂度为O(n)。

传统的diff算法:需要将两个树的节点,两两比较,这就有n*n的复杂度了。 然后还需要编辑树,编辑的树可能发生在任何节点,需要对树进行再一次遍历操作,因此复杂度为n。加起来就是n^3了。

13. React性能优化?

(1)重写shouldComponentUpdate来避免不必要的dom操作。

(2)使用 production 版本的react.js。

(3)使用key来帮助React识别列表中所有子组件的最小变化。

(4)给函数绑定this时在constructor构造函数中绑定,不要在React元素或组件上绑定this。

class App extends React.Component {
	constructor(props) {
		super(props)
		this.handleClick = this.handleClick.bind(this)
	}
	handleClick () {
		...
	}
	render () {
		return (
			<div>
				<button onClick={this.handleClick}>btn</button>
				<button onClick={this.handleClick.bind(this)}>btn</button>
				<button onClick={() => this.handleClick()}>btn</button>
				{/* 此处的this.handleClick()的括号不能省略*/}
			</div>
		)
	}
}
// 第一种,构造函数每一次渲染的时候只会执行一遍;
// 第二种,在每次render()的时候都会重新执行一遍函数;
// 第三种,每一次render()的时候,都会生成一个新的箭头函数,即使两个箭头函数的内容是一样的。

14. 待续。。。?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值