前端面试题及答案整理(二)


Posted in Javascript onAugust 26, 2016

Part1 CSS相关

1 内联元素(inline-element)和块元素(block element)分别有哪些

常见内联元素(行内元素)有a、b、span、i 、em、input、select 、img等
常见的块元素有div、ul、li、h1~h6、talbe、ol、 ul、td、p等

2 浮动相关

浮动布局指将元素脱离普通流/文档流,使其可以左右移动,直至它的外边缘遇到包含框或者另一个浮动框的边缘。浮动框不属于文档中的普通流,当一个元素浮动之后,不会影响到块级元素的布局而只会影响内联元素的排列。
正因为浮动元素脱离了文档流,其父级元素并不知道它的存在,因此会表现为高度为0,无论浮动元素如何变化,其父级元素也不会随它变化将其包裹,这种现象也叫作“高度塌陷”。
下面的例子中,不管#floatDom高度如何变化,#parent高度始终为0,这将导致父元素边框不能被撑开,背景不能显示等问题

<div id="parent">
 <div id="floatDOM" style="float:left;width:300px;height:300px;">
 <div style="clear:both">
</div>

因为高度塌陷的存在(这往往不是我们所期望的),必须要清除浮动,下面介绍清除浮动的几种方式:
•在浮动元素后添加样式含有“clear:both”的元素

<div id="parent">
 <div id="floatDOM" style="float:left;width:300px;height:300px;">
 <div style="clear:both">
</div>

也可以添加br标签,其自带clear:both属性

<div id="parent">
 <div id="floatDOM" style="float:left;width:300px;height:300px;">
 <br/>
</div>

利用这种方式清除浮动的优点在于通俗易懂,容易掌握,缺点也很明显,增加了很多无意义的标签,这个在后期维护中是很痛苦的。
•为父元素添加样式“overflow:hidden"

<div id="parent" style="overflow:hidden">
 <div id="floatDOM" style="float:left;width:300px;height:300px;">
</div>

利用这种方式不存在结构和语义化问题而且代码量极少,然而在内容增多的时候容易造成不会自动换行导致内容被隐藏掉,无法显示需要溢出的元素。
•利用:after伪元素

<style type="text/css">
 .clearfix:after {content:"."; display:block; height:0; visibility:hidden; clear:both; }
 .clearfix { *zoom:1; }
</style>

<div id="parent" class="clearfix">
 <div id="floatDOM" style="float:left;width:300px;height:300px;">
</div>

利用这种方式,仅需在目标元素上添加一个类,也是目前使用最多的一种方式。

Reference
iyunlu.com/view/css-xht

3 相对布局(relative)和绝对布局的区别(absolute)

相对布局和绝对布局最本质的区别在于是否脱离文档流。
相对布局未脱离文档流,即设置元素相对布局后,文档流仍然保持其原始的位置,通过设置top、left等属性可设置其相对于原始位置的偏移量。
绝对布局是脱离文档流的,即文档流中的要素并不知道该绝对布局要素的存在,绝对布局的定位是相对于父元素中具有相对布局或绝对布局的要素,若都不存在则相对于body布局。

4 盒模型(Box Model)

盒模型定义了一个元素的显示形式,包括content(内容)、padding(内边距)、border(边界)以及margin(外边距)几部分组成,目前有两种盒模型标准,一种是W3C标准盒子模型,还有一种是IE盒子模型,采用的是Microsoft自己的标准。

这两种盒模型的区别主要在于元素宽度的计算。标准模式下css中定义的width即为content(内容)的宽度,整个元素在页面中占有的宽度,计算公式为:

  DOM_Width =  width + padding + border + margin

而在IE盒子模型中,css中定义的width为content + padding + border,因此在IE盒子模型中,整个元素在页面中占有的宽度为(高度同理)

 

 DOM_Width =  width + margin

在CSS3中利用box-sizing保留了两种盒子模型,当我们设置box-sizing: content-box(默认),采用的是W3C标准盒模型,当设置box-sizing:border-box时,采用的是IE盒模型。

5 CSS reset(重置)

每个浏览器都有一些自带的样式,而且各个浏览器这些自带的样式往往又存在不同,这给我们布局上带来了一些不便。因此在实践中往往需要对浏览器的css样式进行“清零”,即CSS reset。最简单的一种reset代码如下:

*{
 margin:0;
 padding:0;
}

这种方式虽然简单但太过“暴力”,因为很多要素像div、li等本身默认就没有margin、padding样式,这无异于造成大量冗余,更推荐的方式根据自己需要编写reset代码。

Reference:
www.zhangxinxu.com/wordpress/2010/08/html5-css-reset

6 CSS hack

由于不同的浏览器对CSS的解析和支持是不同的,这会导致相同的CSS代码在不同浏览器中的显示方式并不是完全一致的,这就需要通过CSS Hack来解决不同浏览器的兼容性问题。针对不同浏览器写不同的样式的这个过程就称为CSS hack。

CSS Hack常见的形式有如下几种:
•属性Hack

比如IE6能识别_width以及*width,而在IE7中能识别*width,但是不能识别_width,在FireFox中两个都不识别。
•选择符Hack

比如IE6能识别*html .class{},IE7能识别*+html .class{}或者*:first-child+html .class{}
•条件Hack

IE条件注释是微软从IE5开始就提供的一种非标准逻辑语句。比如针对所有IE:

<!?[if IE]>
 <!?Your Code?>
 <![endif]?>

针对IE6及以下版本:

<!?[if lt IE 7]>
<!?Your Code?>
<![endif]?>

这类Hack不仅对CSS生效,对写在判断语句里面的所有代码都会生效。

Reference

7 优雅降级(graceful degradation)与渐进增强(progressive enhancement)

渐进增强指针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。

优雅降级指一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。

两者的区别在于优雅降级是从复杂的现状开始,并试图减少用户体验的供给,而渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要。降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带。

8 说出遇到的浏览器兼容问题
•不同浏览器中显示的内边距、外边距不同,如ul标签在FireFox中默认是有padding值的,而在IE中只有margin有值

利用CSS Reset(参见第5条)
•IE6的双倍边距BUG,在块级元素浮动后本来外边距10px,但IE解释为20px

将其该块级元素display设置为inline
•IE6中不支持min-height

min-height的作用是作用是当容器的内容较少时,能保持一个最小的高度,以免破坏了布局或UI设计效果。而当容器内的内容增加的时候,容器能够自动的伸展以适应内容的变化。

通过这种下面的方式可以解决:

#targetDom{
  background:#ccc;
  min-height:100px;
  height:auto!important;
  height:100px;
  overflow:visible;
 }

•在标准的事件绑定中绑定事件的方法函数为addEventListener,而IE使用的是attachEvent

通过条件判断分别写两条绑定语句或者使用jquery这类web框架库绑定。
•标准浏览器采用事件捕获的方式,而IE采用的是事件冒泡机制

后来标准认为冒泡更合理,利用设置addEventListener第三个参数兼容两种机制,事件冒泡为默认值。
•事件处理中的event属性IE中获取方式和标准浏览器不同

标准浏览器是作为参数带入,而ie是window.event方式获得,获得目标元素ie为e.srcElement 标准浏览器为e.target

Part2 其它

1 了解常用http状态码

200 OK 一切正常,对GET和POST请求的应答文档跟在后面。

201 Created服务器已经创建了文档,Location头给出了它的URL。

202 Accepted 已经接受请求,但处理尚未完成。

304 Not Modified 客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。服务器告 诉客户,原来缓冲的文档还可以继续使用。

400 Bad Request 请求出现语法错误。

404 Not Found 无法找到指定位置的资源。这也是一个常用的应答。

405 Method Not Allowed 请求方法(GET、POST、HEAD、DELETE、PUT、TRACE等)对指定的资源不适用。(HTTP 1.1新)

500 Internal Server Error 服务器遇到了意料不到的情况,不能完成客户的请求。

502 Bad Gateway 服务器作为网关或者代理时,为了完成请求访问下一个服务器,但该服务器返回了非法的应答。

2 手写ajax请求

//在IE5和IE6中模拟XMLHttpRequest方法
if(window.XMLHttpRequest === undefined){
 window.XMLHttpRequest = function(){
  try{
   return new ActiveXObject("Msxml2.XMLHttp.6.0"); //可用,使用最新ActiveX对象
  }
  catch(e1){
   try{
    return new ActiveXObject("Msxml2.XMLHttp.3.0");//不可用,退后更早的版本
   }
   catch(e2){
    throw new Error("XMLHttpRequest is not supported");
   }
  }
 }
}

//get请求
function xhrGet(url,callback){
 var request = new XMLHttpRequest();
 request.open('GET',url,true);
 request.onreadystatechange = function(){
  if(request.readyState === 4 && request.status == 200){
   callback&&callback(request.responseText);
  }
 };
 request.send(null);
}

//post请求
function xhrPost(url,data,callback){
 var request = new XMLHttpRequest();
 request.open('POST',url,true);
 request.setRequestHeader('Content-Type','application/json');
 request.onreadystatechange = function(){
  if(request.readyState === 4 && request.status == 200){
   callback&&callback(request);
  }
 };
 request.send(JSON.stringfy(data));
}

这是XMLHttpRequest传统的用法,XMLHttpRequest Level 2提出了很多新的方法,我们常提到的CORS也是源自该方法。

要了解详细XHR2推荐 XMLHttpRequest Level 2 使用指南

3 跨域问题

当我们在页面中通过ajax请求其它服务器的数据时,由于浏览器对于JavaScript的同源策略,客户端就会发生跨域问题。所谓同源策略,指的是一段脚本只能请求来自相同来源(相同域名、端口号、协议)的资源。

如果上面XMLHttpRequest请求的服务地址与当前文件不同源的话,浏览器中会出现如下错误:

那么该如何解决这类跨域问题?

(1)利用CORS跨域

"跨域资源共享"(Cross-origin resource sharing,简称CORS)。CORS是是在XHR2中拓展的能力,使用方法很简单,在服务端设置:
Header set Access-Control-Allow-Origin * 

这种设置将接受所有域名的跨域请求,也可以指定具体网址,也可以对域名进行限定:
Header set Access-Control-Allow-Origin http://www.test.com 

然而,这种方式的局限性在于要求客户端支持,并且服务端进行相关设置。在这两者满足的情况下,通过CORS进行跨域不仅支持所有类型的HTTP请求,而且开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。

(2)利用JSONP实现跨越

对于较老的浏览器,它们往往不支持CORS,因此使用JSONP进行跨域也是很常见的一种方式。
我们知道在网页中通过<script>元素的src指定加载目标脚本时是不受同源策略的影响的,因此可以使用它们从其他服务器请求数据,这种利用<script>元素作为Ajax传输的技术就称为JSONP。

JSONP实现的原理如下:

function getJSONP(url, callback){
  var funcName = getUniqueName();//利用时间戳或指自增计数器获得唯一函数名
  
  url += "?callback=" + funcName; //将函数名作为参数添加至url中
  
  var script = document.createElement('script');//动态构建script标签
  
  //回调函数
  getJSONP[funcName] = function(response){
   try{
    callback(response); //处理响应数据
   }
   finally{
    //即使回调函数或响应抛出错误,清除动态增加内容
    delete getJSONP[funcName];
    script.parentNode.removeChild(scirpt);
   }
  }
  
  //触发HTTP请求
  script.src = url;
  document.body.appendChild(script);
 }

JSONP也存在一些弊端,首先JSONP支持GET不支持POST方法,另外使用<script>元素进行Ajax请求,这意味着允许Web页面可以执行远程服务器发送过来的任何JavaScript代码,因此对于不信任的服务器,不应该采用该技术。

(3)利用window.name进行跨域

window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置,因此可以借助window.name在不同源的页面中传递数据。

如www.a.com/a.html想要获得www.b.com/b.html中的数据,原理如下:

a) 在b.html中将数据存储在window.name中

b) 在a.html中构建一个隐藏(display:none)的iframe标签,假设id设为proxy,src设置为和a.html同源即可。

c) 通过如下代码在a.html中获取到data

var proxy = document.getElementById('proxy');
 proxy.onload = function(){
  var data = proxy.contentWindow.name;//获取到数据
 }

d) 移除相关元素

(4) 使用window.postMessage进行跨域

这种方式比较简单,在a页面中利用windowObj.postMessage(message, targetOrigin)向目标页面发送信息,而在b页面中通过监听message事件获取信息。这种方式是在HTML5中新增的方法,对于IE6、IE7等老版本浏览器无法使用。

4 如何提高网站性能

请参看博主的另外两篇文章:

关于提高网站性能的几点建议

关于提高网站性能的几点建议2

发现新内容会持续更新...

博文作者:vicfeel

Javascript 相关文章推荐
Javascript 获取链接(url)参数的方法
Feb 15 Javascript
jQuery+jqmodal弹出窗口实现代码分明
Jun 14 Javascript
超酷的网页音乐播放器DewPlayer使用方法
Dec 18 Javascript
JavaScript 判断日期格式是否正确的实现代码
Jul 04 Javascript
基于JavaScript 数据类型之Boolean类型分析介绍
Apr 19 Javascript
jQuery中dequeue()方法用法实例
Dec 29 Javascript
在JavaScript中使用NaN值的方法
Jun 05 Javascript
jQuery插件Validate实现自定义校验结果样式
Jan 18 Javascript
JavaScript实现的MD5算法完整实例
Feb 02 Javascript
canvas时钟效果
Feb 16 Javascript
关于使用axios的一些心得技巧分享
Jul 02 Javascript
基于ionic实现下拉刷新功能
May 10 Javascript
js前端面试题及答案整理(一)
Aug 26 #Javascript
JavaScript中ES6字符串扩展方法
Aug 26 #Javascript
总结十个Angular.js由浅入深的面试问题
Aug 26 #Javascript
Jquery遍历select option和添加移除option的实现方法
Aug 26 #Javascript
响应式表格之固定表头的简单实现
Aug 26 #Javascript
jQuery基于BootStrap样式实现无限极地区联动
Aug 26 #Javascript
BootStrap无限级分类(无限极分类封装版)
Aug 26 #Javascript
You might like
让你同时上传 1000 个文件 (一)
2006/10/09 PHP
不错的一篇面向对象的PHP开发模式(简写版)
2007/03/15 PHP
php 破解防盗链图片函数
2008/12/09 PHP
php页码形式分页函数支持静态化地址及ajax分页
2014/03/28 PHP
PHP 如何获取二维数组中某个key的集合
2014/06/03 PHP
页面利用渐进式JPEG来提升用户体验度
2014/12/01 PHP
Yii2 assets清除缓存的方法
2016/05/16 PHP
PHP请求Socket接口测试实例
2016/08/12 PHP
javascript Math.random()随机数函数
2009/11/04 Javascript
JavaScript Event学习第十章 一些可替换的事件对
2010/02/10 Javascript
web前端开发也需要日志
2010/12/09 Javascript
javascript 手动给表增加数据的小例子
2013/07/10 Javascript
纯文字版返回顶端的js代码
2013/08/01 Javascript
JS和JQ的event对象区别分析
2014/11/24 Javascript
node.js中的fs.createReadStream方法使用说明
2014/12/17 Javascript
bootstrap实现弹窗和拖动效果
2016/01/03 Javascript
json格式数据的添加,删除及排序方法
2016/01/21 Javascript
浅谈如何实现easyui的datebox格式化
2016/06/12 Javascript
js css实现垂直方向自适应的三角提示菜单
2016/06/26 Javascript
JS实现简单拖拽效果
2017/06/21 Javascript
如何重置vue打印变量的显示方式
2017/12/06 Javascript
JS随机数产生代码分享
2018/02/24 Javascript
讲解vue-router之命名路由和命名视图
2018/05/28 Javascript
JS闭包经典实例详解
2018/12/20 Javascript
微信小程序单选radio及多选checkbox按钮用法示例
2019/04/30 Javascript
Jquery cookie插件实现原理代码解析
2020/08/04 jQuery
[00:32]2018DOTA2亚洲邀请赛Liquid出场
2018/04/03 DOTA
遍历python字典几种方法总结(推荐)
2016/09/11 Python
使用 Python 合并多个格式一致的 Excel 文件(推荐)
2019/12/09 Python
在Ubuntu 20.04中安装Pycharm 2020.1的图文教程
2020/04/30 Python
SteelSeries赛睿官网:游戏外设和配件的领先制造商(耳机、键盘、鼠标和鼠标垫)
2018/06/17 全球购物
英国领先的独立时装店:Van Mildert
2019/10/28 全球购物
大一学生职业生涯规划
2014/03/11 职场文书
就业意向书范本
2015/05/11 职场文书
行政二审代理词
2015/05/25 职场文书
解析高可用Redis服务架构分析与搭建方案
2021/06/20 Redis