爱前端

前端面试题目总结(二)

1、CSS HACK 如何书写

这题目第一眼看见,感觉包含了深深的恶意,最不喜欢这类题目,答案太多了,更关键的一点是,我们所熟悉的css hack 大部分是针对 IE 浏览器,尤其是低版本的 IE 浏览器,对于一个很久没有处理IE6兼容问题的我来说,似乎稍有吃力,于是查查资料,总结如下:

  • A: png-24 图片 IE6 不支持,使用 png-8 的图片来解决,或者 做两张图片,分别使用
  • B: 浮动元素 margin 值加倍,给元素增加 display: inline 或 display: inline-block 属性。
  • C: 图片有个 3px margin,增加属性 margin: -3px;
  • D: 条件注释:
<!--[if lte IE 6]> 这段文字仅显示在 IE6及IE6以下版本。 <![endif]-->
<!--[if gte IE 6]> 这段文字仅显示在 IE6及IE6以上版本。 <![endif]-->
<!--[if gt IE 6]> 这段文字仅显示在 IE6以上版本(不包含IE6)。 <![endif]-->
<!--[if IE 5.5]> 这段文字仅显示在 IE5.5。 <![endif]-->
<!--在 IE6及IE6以下版本中加载css-->
<!--[if lte IE 6]> <link type="text/css" rel="stylesheet" href="css/ie6.css" mce_href="css/ie6.css" /><![endif]-->

缺点是在IE浏览器下可能会增加额外的HTTP请求数。

  • E: 通过选择器区分
/* 1、区别IE和其他浏览器 *,IE 都认识,其他浏览器不认识 */
.demo{
    *background: red;
    background: blue;
}
/* IE 浏览器里面是红色,其他浏览器是蓝色的 */
/* 2、区别IE6,IE6 不能识别 !important */
/* 3、区别 IE6,IE6 可识别_ */
.demo{
    _color: red;
    color: green;        
}    
/* IE6 颜色为红色,其他浏览器为绿色 */
  • F: IE 低版本下的圆角,用图片来写,或者优雅降级(IE 低版本里面用直角)
  • G: IE6背景闪烁

如果你给链接、按钮用CSS sprites作为背景,你可能会发现在IE6下会有背景图闪烁的现象。造成这个的原因是由于IE6没有将背景图缓存,每次触发hover的时候都会重新加载,可以用JavaScript设置IE6缓存这些图片:document.execCommand("BackgroundImageCache",false,true);

  • H: 最大、最小高度、宽度,利用js来处理,或尽量避免使用最大、最小宽高
  • I: 100% 高度,IE6 认为是父级的100%,因此要给 html、body等分别设置宽度为100%
  • J: 清除浮动

如果你想用div(或其他容器)包裹一个浮动的元素,你会发现必须给div(容器)定义明确的height、width、overflow之中一个属性(除了auto值)才能将浮动元素严实地包裹。

.container {border:1px solid #333; overflow:auto; height:100%;}
.floated1 {float:left; height:300px; width:200px; background:#00F;}
.floated2 {float:right; height:400px; width:200px; background:#F0F;}

这里简单总结了一些,其实IE里面的bug 远不止这些,hack的方法也多种多样,但反过来想想,现在连微软自己都开始要放弃IE了,作为开发者的我们还是多多劝劝身边那些使用IE6的老人们,跟上时代步伐,舍弃那些不合时宜的东西吧!!!

2、常用的Block-Level Elements 和 Inline-Level Elements 有哪些;Inline Elements 如何操作后可以设置宽高

块状元素:

  • address - 地址
  • blockquote - 块引用
  • center - 举中对齐块
  • dir - 目录列表
  • div - 常用块级容易,也是CSS layout的主要标签
  • dl - 定义列表
  • fieldset - form控制组
  • form - 交互表单
  • h1 - 大标题
  • h2 - 副标题
  • h3 - 3级标题
  • h4 - 4级标题
  • h5 - 5级标题
  • h6 - 6级标题
  • hr - 水平分隔线
  • isindex - input prompt
  • menu - 菜单列表
  • noframes - frames可选内容,(对于不支持frame的浏览器显示此区块内容
  • noscript - 可选脚本内容(对于不支持script的浏览器显示此内容)
  • ol - 有序表单
  • p - 段落
  • pre - 格式化文本
  • table - 表格
  • ul - 无序列表

行内元素:

  • a - 锚点
  • abbr - 缩写
  • acronym - 首字
  • b - 粗体(不推荐)
  • bdo - bidi override
  • big - 大字体
  • br - 换行
  • cite - 引用
  • code - 计算机代码(在引用源码的时候需要)
  • dfn - 定义字段
  • em - 强调
  • font - 字体设定(不推荐)
  • i - 斜体
  • img - 图片
  • input - 输入框
  • kbd - 定义键盘文本
  • label - 表格标签
  • q - 短引用
  • s - 中划线(不推荐)
  • samp - 定义范例计算机代码
  • select - 项目选择
  • small - 小字体文本
  • span - 常用内联容器,定义文本内区块
  • strike - 中划线
  • strong - 粗体强调
  • sub - 下标
  • sup - 上标
  • textarea - 多行文本输入框
  • tt - 电传文本
  • u - 下划线
  • var - 定义变量

Inline Elements 如何操作后可以设置宽高:

定义属性display为block、inline-block或定义元素浮动,或让元素绝对定位、固定定位。

3、常见的网页图像格式有 ico、jpg、png、gif,说说他们各自的应用场景

  • ico:一般作为网页的标题上面的图标出现,文件 favicon.ico一般存放在网站根目录
  • jpg:非常适合作为储存像素色彩丰富的图片、例如照片等等
  • png:分为 png-8 以及 png-24 两种格式
    • png-8 的特性很接近 gif ,支持 256 色以及透明背景的特性
    • PNG-24 则支持了多达 160 万个色彩
  • gif:非常适合用来表现图标、 UI接口、线条插画、文字等部分的输出,也可用来展示小的动画。

4、如何触发页面的reflow、repaint

  • 什么是reflow(重排)、repaint(重绘)

    页面在加载的过程中,需要对文档结构进行解析,同时需要结合各种各样的样式来计算这个页面长什么样子,最后再经过浏览器的渲染页面就出现了。这整个过程细说起来还是比较复杂,其中充满了repaint和reflow。对于DOM结构中的各个元素都有自己的盒子(模型),这些都需要浏览器根据各种样式(浏览器的、开发人员定义的等)来计算并根据计算结果将元素放到它该出现的位置,这个过程称之为reflow;当各种盒子的位置、大小以及其他属性,例如颜色、字体大小等都确定下来后,浏览器于是便把这些元素都按照各自的特性绘制了一遍,于是页面的内容出现了,这个过程称之为repaint。

  • 如何触发reflow:

    • 可见元素的增删
    • 元素的位置, 大小, 内容的改变
    • 页面第一次渲染
    • 插入、删除或者更新页面(文档树)中的节点。
    • 修改页面的内容,例如在input标签中输入内容。
    • 移动节点。
    • 页面中的动画效果。
    • 获取节点的尺寸,例如获取节点的offsetHeight,或者使用getComputedStyle函数获取节点尺寸。
    • 改变节点样式。
    • 改变节点的className属性。
    • 增加或者删除样式表文件。
    • window的resize。
    • 滚动滚动条,即scroll
  • 如何触发repaint

避免或减少reflow、repaint的建议

  • 尽可能限制reflow的影响范围。样式最好加在当前层上面,不要夹在父级上。
  • 通过设置style属性改变结点样式的话,每设置一次都会导致一次reflow。所以最好通过设置class的方式。
  • 实现元素的动画,它的position属性应当设为fixed或absolute,这样不会影响其它元素的布局。
  • 权衡速度的平滑。比如实现一个动画,以1个像素为单位移动这样最平滑,但reflow就会过于频繁,CPU很快就会被完全占用。如果以3个像素为单位移动就会好很多。
  • 不要用tables布局的另一个原因就是tables中某个元素一旦触发reflow就会导致table里所有的其它元素reflow。在适合用table的场合,可以设置table-layout为auto或fixed,这样可以让table一行一行的渲染,这种做法也是为了限制reflow的影响范围。
  • 很多情况下都会触发reflow,如果css里有expression,每次都会重新计算一遍。(这也是避免使用expression的原因)

5、用三个div实现下图现实效果,左边div宽高都为50px,右边div宽100px,高110px,写出html和css

代码需实现的图片

html代码如下:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    <div class="a"></div>
    <div class="b"></div>
    <div class="c"></div>
</body>
</html>

css代码如下:

    *{
          padding: 0;
          margin: 0;
      }
      div{
          background: #000;
          position: absolute;
      }
      .a,.b{
          width: 50px;
          height: 50px;
      }
      .a{
          left: 0;
          top: 0;
      }
      .b{
          left: 0;
          top: 60px;
      }
      .c{
          width: 100px;
          height: 110px;
          left: 60px;
          top: 0;
      }

6、翻译这段文档

ECMAScript uses automatic garbage collection.The specification does not define the details, leaving that to the implementers to sort out.A closure is formed by returning a function object that was created within an execution context of a function call from that function call and assigning a reference to that inner function to a property of another object.

ECMAScript采用自动垃圾收集。规范中没有定义细节,留给实施者整理。关闭是通过返回一个函数对象

7、js中的数据类型有哪些

  • 基础数据类型:null、undefined、string、number、boolean 数据存储在变量中
  • 引用数据类型:Array、Object、Date、RegExp 数据是保存在内存中的对象

8、写出DOM中创建、插入、删除节点的方法,可以使用jquery方法实现

  • 创建DOM:
    • .createElement() // 创建一个具体的元素
    • .createTextNode() // 创建一个文本节点
  • 插入DOM:
    • .appendChild()
    • .replaceChild() // 替换节点
    • .insertBefore() // 在已有的子节点前插入一个新的子节点
  • 删除DOM:.removeChild()

jquery实现方法

  • 创建DOM:
  • 插入DOM:
    • .append() // 在每个匹配元素里面的末尾处插入参数内容。
    • .appendTo() // 将匹配的元素插入到目标元素的最后面
    • .after() // 在匹配元素集合中的每个元素后面插入参数所指定的内容,作为其兄弟节点。
    • .before() // 根据参数设定,在匹配元素的前面插入内容
    • .prepend() // 将参数内容插入到每个匹配元素的前面(元素内部)
    • .prependTo() // 将所有元素插入到目标前面(元素内)
    • .insertAfter() // 在目标元素后面插入集合中每个匹配的元素
    • .insertBefore() // 在目标元素前面插入集合中每个匹配的元素
  • 删除DOM:
    • .remove() // 将匹配元素集合从DOM中删除
    • .empty() // 从DOM中移除集合中匹配元素的所有子节点
    • .unwrap() // 将匹配元素集合的父级元素删除,保留自身(和兄弟元素,如果存在)在原来的位置

9、请编写一个Javascript函数parseQueryString,他的用途是把URL参数解析为一个对象。如果你有多种方法,请简洁说下,并写出这些方法中你认为最好的一种实现方法

10、IE与FF的事件模型有哪些区别,并实现一个bindEvent 方法

一、IE 的事件流叫做事件冒泡(event bubbling),即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档 )。

二、FF 的事件流叫做事件捕获,思想是不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。用意在于在事件到达预订目标之前捕获它。

事件绑定方法如下:

function bindEvent(object,type,fn) { 
    if(object.attachEvent){
        // IE浏览器 
        object.attachEvent("on" + type ,(function (){ 
            return function(event){ 
                window.event.cancelBubble = true;// 停止事件冒泡 
                object.attachEvent = [fn.apply(object)];            } 
        })(object), false);
    }else if(object.addEventListener){
        // 其他浏览器 
        object.addEventListener(type, function(event){ 
            event.stopPropagation();// 停止事件冒泡 
            fn.apply(this);
        }); 
    }else{
        object['on' + type] = fn;
    }
}

11、请编写一个 Javascript 函数isArray,用于判断一个obj是否为数组对象

function isArray(obj) {  
  return Object.prototype.toString.call(obj) === '[object Array]';   
}

其实在ECMAScript5 中已经又了一个判断数组的简单方法 Array.isArray()直接就可以用来判断对象是否为数组对象。

12、小贤是一条可爱的小狗(Dog),它的叫声很好听(Wow),每次看到主人的时候就会乖乖叫一声(Yelp),从这段描述可以得到以下对象:

function Dog(){
    this.wow = function(){
        alert('Wow');
    }
    this.yelp = function(){
        this.wow();
    }
}

小芒和小贤一样,原来也是一条可爱的小狗,可是突然有一天疯了(MadDog),一看到人就会每隔半秒叫一声(wow)地不停交换(yelp)。请根据描述,按示例的形式用代码来实现(提示关键字:继承,原型,setInterval)

function Maddog () {
    this.yelp = function () {
        var me = this;
        setInterval(function () {
            me.wow();
        }, 500);
    };
}
Maddog.prototype = new Dog();
var bbb = new Maddog();
bbb.yelp();

13、HTTP 状态码,200/304/404/500,分别代表什么

  • 200 OK 一切正常,对GET和POST请求的应答文档跟在后面。
  • 304 Not Modified 客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。服务器告诉客户,原来缓冲的文档还可以继续使用。
  • 404 Not Found 无法找到指定位置的资源。这也是一个常用的应答。
  • 500 Internal Server Error 服务器遇到了意料不到的情况,不能完成客户的请求。

14、请简单写一下你对Javascript 异步编程的认识,比如:异步编程的优势和难点,异步编程的主要解决方案

  • 异步编程的优势:避免浏览器假死,失去响应
  • 异步编程的难点:
  • 异步编程解决方案:回调函数、事件监听、发布/订阅、Promises对象

15、对于网站的前端性能,你会关注哪些方面

雅虎的34条军规基本涵盖了前段优化的大部分内容,详细内容可见web前端性能优化小结

16、数组去重

① 思路:

  1. 构建一个新的数组存放结果
  2. for循环中每次从原数组中取出一个元素,用这个元素循环与结果数组对比
  3. 若结果数组中没有该元素,则存到结果数组中
Array.prototype.unique1 = function(){
    var res = [this[0]];
     for(var i = 1; i < this.length; i++){
         var repeat = false;
         for(var j = 0; j < res.length; j++){
             if(this[i] == res[j]){
                 repeat = true;
                 break;
             }
         }
         if(!repeat){
             res.push(this[i]);
         }
     }
     return res;
}
var arr = [1, 'a', 'a', 'b', 'd', 'e', 'e', 1, 0]
alert(arr.unique1());

② 思路:

  1. 先将原数组进行排序
  2. 检查原数组中的第i个元素 与 结果数组中的最后一个元素是否相同,因为已经排序,所以重复元素会在相邻位置
  3. 如果不相同,则将该元素存入结果数组中
Array.prototype.unique2 = function(){
    this.sort(); //先排序
    var res = [this[0]];
    for(var i = 1; i < this.length; i++){
        if(this[i] !== res[res.length - 1]){
            res.push(this[i]);
        }
    }
    return res;
}
var arr = [1, 'a', 'a', 'b', 'd', 'e', 'e', 1, 0]
alert(arr.unique2());

③ 思路:

  1. 创建一个新的数组存放结果
  2. 创建一个空对象
  3. for循环时,每次取出一个元素与对象进行对比,如果这个元素不重复,则把它存放到结果数组中,同时把这个元素的内容作为对象的一个属性,并赋值为1,存入到第2步建立的对象中。 说明:至于如何对比,就是每次从原数组中取出一个元素,然后到对象中去访问这个属性,如果能访问到值,则说明重复。
Array.prototype.unique3 = function(){
    var res = [];
    var json = {};
    for(var i = 0; i < this.length; i++){
        if(!json[this[i]]){
            res.push(this[i]);
            json[this[i]] = 1;
        }
    }
    return res;
}
var arr = [112,112,34,'你好',112,112,34,'你好','str','str1'];
alert(arr.unique3());

17、写一个jsonp的工具函数

JSONP是JSON with Padding的略称。它是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)

18、对闭包、原型连的理解

原型链:基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。(每个构造函数都有一个原型对象,原型对象都包含一个指定构造函数的指针,而实例都包含一个指向原型对象的内部指针。)

19、css3动画的实现

20、如何判断一个div是否在页面当前的视窗内

html和css代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>demo</title>
    <style>
    *{
        padding: 0;
        margin: 0;
    }
    body{
        width: 100%;
        height: 3000px;
    }
    .demo{
        width: 300px;
        height: 300px;
        margin: 50px auto;
        background: red;
        border: 5px solid #cdcdcd;
    }
    </style>
</head>
<body>
    <div class="demo" id="demo"></div>
</body>
</html>

下面是js代码:

function init(){
        var demoTop = document.getElementById('demo').offsetTop;
        var demoHeight = document.getElementById('demo').offsetHeight;
        var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
        if(scrollTop > (demoHeight + demoTop)){
            console.log('div 在当前页面的可视窗口外');
        }else{
            console.log('div 在当前页面的可视窗口内')
        }
    }

习惯了用jquery来解决问题,看到这题目时有点蒙,原生的计算各种高度的方法都记不清楚了,总结回顾一下吧

21、有一个div,里面有很多个按钮,每个按钮所实现的方法是不同的,代码如何实现

22、自适应布局、响应式设计

23、call、apply区别