• 【转】前端面试


    一、HTML

    1. 针对移动浏览器端开发页面,不期望用户放大屏幕,且要求“视口(viewport)”宽度等于屏幕宽度,视口高度等于设备高度,如何设置?

    移动web前端viewport详解
    <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, maximum-scale=1, user-scalable=no">

    meta使用详细总结

    2.data-xxx 属性的作用是什么?

    HTML5 data-* 属性:

    定义和用法
    data- 属性用于存储页面或应用程序的私有自定义数据。
    data-
    属性赋予我们在所有 HTML 元素上嵌入自定义 data 属性的能力。
    存储的(自定义)数据能够被页面的 JavaScript 中利用,以创建更好的用户体验(不进行 Ajax 调用或服务器端数据库查询)。
    data-* 属性包括两部分:
    属性名不应该包含任何大写字母,并且在前缀 "data-" 之后必须有至少一个字符
    属性值可以是任意字符串

    注释:用户代理会完全忽略前缀为 "data-" 的自定义属性。
    这里的data-前缀就被称为data属性,其可以通过脚本进行定义,也可以应用CSS属性选择器进行样式设置。数量不受限制,在控制和渲染数据的时候提供了非常强大的控制。

    html:

    <div class="mm" data-name="张含韵"></div>
    <div class="mm" data-name="undefined"></div>

    css:

    .mm{256px; height:200px;}
    .mm[data-name='张含韵']{background:url(http://image.zhangxinxu.com/image/study/s/s256/mm1.jpg) no-repeat;}
    .mm[data-name='undefined']{background:url(http://image.zhangxinxu.com/image/study/s/s256/mm3.jpg) no-repeat;}

    js:

    expense = document.getElementById('day2-meal-expense').dataset;

    3.请描述一下cookies,sessionStorage和localStorage的区别?

    之前总结过:http://www.jianshu.com/p/da227e50df43
    HTTP cookies 详解
    微软的 IE6 SP1 在 cookie 中引入了一个新的选项:HTTP-only,HTTP-Only背后的意思是告之浏览器该 cookie 绝不能通过 JavaScript 的 document.cookie属性访问。设计该特征意在提供一个安全措施来帮助阻止通过 JavaScript 发起的跨站脚本攻击 (XSS) 窃取 cookie 的行为

    4.什么是浏览器的标准模式(standards mode)和怪异模式(quirks mode)

    目前浏览器的排版引擎有三种模式:怪异模式(Quirks mode)、接近标准模式(Almost standards mode)、以及标准模式(Standards mode)。在怪异模式下,排版会模拟 Navigator 4 与 Internet Explorer 5 的非标准行为。为了支持在网络标准被广泛采用前,就已经建好的网站,这么做是必要的。在标准模式下,行为即(但愿如此)由 HTML 与 CSS 的规范描述的行为。在接近标准模式下,只有少数的怪异行为被实现。

    那么所谓标准模式,就一定都“标准”吗?答案当然是否定的,因为各个浏览器厂商实现标准的阶段不同,所以各个浏览器的“标准模式”之间也会有很大的不同。
    Firefox、Safari、Chrome、Opera (自 7.5 以后)、 IE8 和 IE9 都有一个准标准模式。那么既然标准模式都不那么标准,准标准的模式肯定就更不标准了。

    • 浏览器如何决定用哪个模式?
      HTML文件来说,浏览器使用文件开头的 DOCTYPE 来决定用怪异模式处理或标准模式处理。为了确保你的页面使用标准模式,请确认你的页面如同本范例一样拥有 DOCTYPE:

      <!DOCTYPE html>
      <html>
      <head>
        <meta charset=UTF-8>
      <title>Hello World!</title>
      </head> 
      <body>
      </body>
      </html>

      范例中的DOCTYPE,<!DOCTYPE html>,是所有可用的DOCTYPE之中最简单的,而且是HTML5 所推荐的。HTML的早期变种也属于推荐标准,不过今日的浏览器都会对这个 DOCTYPE 使用标准模式,就算是已过时的 Internet Explorer 6 也一样。目前并没有正当的理由,去使用其他更复杂的 DOCTYPE。如果你使用其他的 DOCTYPE,你可能会冒着触发接近标准模式或者怪异模式的风险。

    • 使用
      请确定你把 DOCTYPE 正确地放在 HTML 文件的顶端。任何放在 DOCTYPE 前面的东西,比如批注或 XML 声明,会令 Internet Explorer 9 或更早期的浏览器触发怪异模式。

      在 HTML5中,DOCTYPE 唯一的作用是启用标准模式。更早期的 HTML 标准会附加其他意义,但没有任何浏览器会将 DOCTYPE 用于怪异模式和标准模式之间互换以外的用途。

    • 浏览器的标准模式与怪异模式的设置与区分方法

    由于历史的原因,各个浏览器在对页面的渲染上存在差异,甚至同一浏览器在不同版本中,对页面的渲染也不同。在W3C标准出台以前,浏览器在对页面的渲染上没有统一规范,产生了差异(Quirks mode或者称为Compatibility Mode);由于W3C标准的推出,浏览器渲染页面有了统一的标准(CSScompat或称为Strict mode也有叫做Standars mode),这就是二者最简单的区别。W3C标准推出以后,浏览器都开始采纳新标准,但存在一个问题就是如何保证旧的网页还能继续浏览,在标准出来以前,很多页面都是根据旧的渲染方法编写的,如果用的标准来渲染,将导致页面显示异常。为保持浏览器渲染的兼容性,使以前的页面能够正常浏览,浏览器都保留了旧的渲染方法(如:微软的IE)。这样浏览器渲染上就产生了Quircks mode和Standars mode,两种渲染方法共存在一个浏览器上。
    火狐一直工作在标准模式下,但IE(6,7,8)标准模式与怪异模式差别很大,主要体现在对盒子模型的解释上,这个很重要,下面就重点说这个。那么浏览器究竟该采用哪种模式渲染呢?这就引出的DTD,既是网页的头部声明,浏览器会通过识别DTD而采用相对应的渲染模式:

    1. 浏览器要使老旧的网页正常工作,但这部分网页是没有doctype声明的,所以浏览器对没有doctype声明的网页采用quirks mode解析。
    2. 对于拥有doctype声明的网页,什么浏览器采用何种模式解析,这里有一张详细列表可参考:http://hsivonen.iki.fi/doctype。
    3. 对于拥有doctype声明的网页,这里有几条简单的规则可用于判断:对于那些浏览器不能识别的doctype声明,浏览器采用strict mode解析。
    4. 在doctype声明中,没有使用DTD声明或者使用HTML4以下(不包括HTML4)的DTD声明时,基本所有的浏览器都是使用quirks mode呈现,其他的则使用strict mode解析。
    5. 可以这么说,在现有有doctype声明的网页,绝大多数是采用strict mode进行解析的。
    6. 在ie6中,如果在doctype声明前有一个xml声明(比如:<?xml version=”1.0″ encoding=”iso-8859-1″?>),则采用quirks mode解析。这条规则在ie7中已经移除了。
      如何判定现在是标准模式还是怪异模式:
      方法一:执行以下代码
      alert(window.top.document.compatMode) ;
      //BackCompat  表示怪异模式
      //CSS1Compat  表示标准模式
      方法二:jquery为我们提供的方法,如下:
      alert($.boxModel)
      alert($.support.boxModel)

    CSS

    1. 解释一下盒模型宽高值的计算方式,边界塌陷,负值作用,box-sizing概念。

    1.1 盒模型

    a. ie678怪异模式(不添加 doctype)使用 ie 盒模型,宽度=边框+padding+内容宽度
    b. chrome, ie9+, ie678(添加 doctype) 使用标准盒模型,宽度= 内容宽度

    1.2 box-sizing

    content-box(默认)
    布局所占宽度Width:
    Width = width + padding-left + padding-right + border-left + border-right
    布局所占高度Height:
    Height = height + padding-top + padding-bottom + border-top + border-bottom
    border-box
    布局所占宽度Width:
    Width = width(包含padding-left + padding-right + border-left + border-right)
    布局所占高度Height:
    Height = height(包含padding-top + padding-bottom + border-top + border-bottom)

    1.3 边界塌陷
    之前总结的

    1.4 负值作用

    display:inline-block是什么呢?相信大家对这个属性并不陌生,根据名字inline-block我们就可以大概猜出它是结合了inline和block两者的特性于一身,简单的说:设置了inline-block属性的元素既拥有了block元素可以设置width和height的特性,又保持了inline元素不换行的特性。

    在margin属性中一共有两类参考线,top和left的参考线属于一类,right和bottom的参考线属于另一类。top和left是以外元素为参考,right和bottom是以元素本身为参考。
    厉害了我的margin_由浅入深漫谈margin属性

    margin:-10px 20px -30px 40px;

    这时候 margin 的解析逻辑是怎样的呢?首先我们要搞清 div 的和周边元素的关系,div 没有相连元素,而此时 div 的 containing block 是 body 产生的 block box。则根据上面介绍的参考线原理,div 的左外边距以 containing block 的 content 左边为参考线,及此时以 body 的 content 左边为参考线进行水平向右位移,位移的大小为 40px,同理,上边距以 body 的 content 上边为参考线进行垂直向上位移 10px(负值和正值的方向相反),下边距依照现在 div 的 borer 下边(此时的 div 已经经过上边距位移过了)垂直向上位移 30px(此时,margin 不会改变 box 的 border 内的物理大小,但会改变 box 的逻辑大小,即:以此 box 的 margin 的下边为参考的元素,不是从 box 的物理位置开始的,而是从逻辑位置开始),右边距依照现在 div 的 borer 右边(此时的 div 已经经过左边距位移过了)水平向右位移 20px。或许有朋友问你分析的顺序怎么和 margin 表达式中出现的顺序不一样?如果按照 margin 表达式中出现的顺序来分析,结果是一样的,只是为了更好的方便大家的理解而没有按照表达式的顺序来分析。

    margin为负值产生的影响和常见布局应用

    应用

    <div class="main"> 
      <div class="main-content">main content</div>
    </div>
    <div class="left">left</div>
    <div class="right">right</div>
    *{ margin:0; padding: 0 }
    .main{ float: left;  100%; } 
    .main .main-content{ 
      margin: 0 210px; 
      background-color: rgba(33, 114, 214, 0.8);
      height: 500px
     } 
    .left{
       200px;
      float: left; 
      background-color:
      rgba(255, 82, 0, 0.8); 
      margin-left: -100%; 
      height: 200px
     } 
    .right{ 
       200px;
      height: 200px; 
      margin-left: -200px;
      float: left;
      background-color: rgba(90, 243, 151, 0.8);
     }
    • 负边距+定位:水平垂直居中
      还有其他。。

    [margin,padding]任一方向的百分数都是相对于包含块的宽度(width)的。
    一般left和right(用于absolute/fixed)在一个样式是只能使用其一,不能left和right都设置,要么使用left就不使用right,要么使用right就不使用left,如果left和right均使用将会出现兼容问题,一个对象设置了靠左left多少距离,自然右边距离自然就有了所以无需设置左边。
    相同道理,top和bottom对一个对象只能使用其一,不然会出现逻辑兼容问题。譬如一个人让你往左走,一个人让你往右走,同时发出往左往右走这个时候你也不好判断往那边走。

    2. BFC(Block Formatting Context)是什么?有哪些应用?

    CSS之BFC详解
    [CSS]深入理解BFC原理及应用

    Block Formatting Context,中文直译为块级格式上下文。BFC就是一种布局方式,在这种布局方式下,盒子们自所在的containing block顶部一个接一个垂直排列,水平方向上撑满整个宽度(除非内部盒子自己建立了新的BFC)。两个相邻的BFC之间的距离由margin决定。在同一个BFC内部,两个垂直方向相邻的块级元素的margin会发生“塌陷”。

    文档这里也间接指出了垂直相邻盒子margin合并的解决办法:就是给这两个盒子也创建BFC。

    通俗一点,可以把BFC理解为一个封闭的大箱子,箱子内部的元素无论如何翻江倒海,都不会影响到外部。

    • 如何创建BFC
      总结一下就是:

      float属性不为none
      overflow不为visible(可以是hidden、scroll、auto)
      position为absolute或fixed
      display为inline-block、table-cell、table-caption

    • BFC的作用
      1. 清除内部浮动我们在布局时经常会遇到这个问题:对子元素设置浮动后,父元素会发生高度塌陷,也就是父元素的高度变为0。解决这个问题,只需要把把父元素变成一个BFC就行了。常用的办法是给父元素设置overflow:hidden。
      2. 垂直margin合并在CSS当中,相邻的两个盒子的外边距可以结合成一个单独的外边距。这种合并外边距的方式被称为折叠,并且因而所结合成的外边距称为折叠外边距。折叠的结果:
      两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值。
      两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值。
      两个外边距一正一负时,折叠结果是两者的相加的和。这个同样可以利用BFC解决。关于原理在前文已经讲过了。
      3. 创建自适应两栏布局在很多网站中,我们常看到这样的一种结构,左图片+右文字的两栏结构。
      显然,这是文字受到了图片浮动的影响。当然,如果你想做文本绕排的效果,浮动是不二之选。不过在这里,这显然不是我们想要的。此时我们可以为P元素的内容建立一个BFC,让其内容消除对外界浮动元素的影响。给文字加上overflow:hidden

    3.如何要求容器在宽度自由很缩的情况下,A/B/C的宽度始终是1:1:1,如何实现,写出两种方法。


     

    flex布局:

    .div1 {
       100%;
      height: 400px;
      border: 1px solid #888;
      flex-direction: row;
      /**主要代码*/
      display: flex;
      /*     align-items: center; */
      /*     justify-content: center; */
    }
    
    .div {
      /*   position:absolute; */
      /*     500px; */
      flex-grow: 1;
      border: 1px solid #888;
    }

    百分数布局:inline-block元素间间隙产生及去除详解:

    <div class="div1">
      <div class="div2 div">
        div2
      </div><div class="div3 div">
        div3
      </div><div class="div4 div">
        div4
      </div>
    </div>
    
    
    .div1 {
       100%;
      height: 400px;
      background-color: red;
    }
    .div2{
      margin-left: 5%;
    }
    .div {
      30%;
      display:inline-block;
      background-color:#888;
    }

    4.

    如图,A若宽高已知,如何实现水平、垂直均相对于父元素居中?若A高度未知呢?


     


    之前总结的

    JavaScript

    1. 函数中的arguments是什么?是数组吗?若不是,如何将它转化为真正的数组?

    arguments不是真正的数组。没有数组的方法

    function a(){
      console.log(arguments);
      var args = Array.prototype.slice.call(arguments);
      console.log(args);
      /* arguments.forEach(function(){   
      }) */
    }
    a(1,2,3)

    2. 列举JavaScript中typeof操作符的可能结果,如何区分:{}和[]类型?

    3. Function中的call、apply、bind的区别是什么?请针对每一个写出一个代码示例。

    4. 使用jQuery,找到id位selector的select标签中有用data-target属性为isme的option的值?

    var se = $("#selector option[data-target=isme]");
    console.log(se.val());

    5. 优化代码

     for(var i = 0; i < document.getElementsByTagName('a').length; i++) {
        document.getElementsByTagName('a')[i].onmouseover = function(){
            this.style.color = 'red';
        };
        document.getElementsByTagName('a')[i].onmouseout = function(){
            this.style.color = '';
        };

    5.1 CSS

    回流与重绘:CSS性能让JavaScript变慢?
    翻译计划-重绘重排重渲染
    通过类修改样式
    有时候我们需要通过JavaScript给元素增加样式,比如如下代码:

    element.style.fontWeight = 'bold';
    element.style.backgroundImage = 'url(back.gif)';
    element.style.backgroundColor = 'white';element.style.color = 'white';//...

    这样效率很低,每次修改style属性后都会触发元素的重绘,如果修改了的属性涉及大小和位置,将会导致回流。所以我们应当尽量避免多次为一个元素设置style属性,应当通过给其添加新的CSS类,来修改其CSS

    当一个元素的外观的可见性visibility发生改变的时候,重绘(repaint)也随之发生,但是不影响布局。类似的例子包括:outline, visibility, or background color。根据Opera浏览器,重绘的代价是高昂的,因为浏览器必须验证DOM树上其他节点元素的可见性。而回流更是性能的关键因为其变化涉及到部分页面(或是整个页面)的布局。一个元素的回流导致了其所有子元素以及DOM中紧随其后的祖先元素的随后的回流。


    render.png

    如何避免回流或将它们对性能的影响降到最低?

    • 如果想设定元素的样式,通过改变元素的 class 名 (尽可能在 DOM 树的最末端)(Change classes on the element you wish to style (as low in the dom tree as possible))
    • 避免设置多项内联样式(Avoid setting multiple inline styles)
    • 应用元素的动画,使用 position 属性的 fixed 值或 absolute 值(Apply animations to elements that are position fixed or absolute)
    • 权衡平滑和速度(Trade smoothness for speed)
    • 避免使用table布局(Avoid tables for layout)
    • 避免使用CSS的JavaScript表达式 (仅 IE 浏览器)(Avoid JavaScript expressions in the CSS (IE only))

    结合着看

    • “离线”的批量改变和表现DOM。“离线”意味着不在当前的DOM树中做修改。你可以:通过documentFragment来保留临时变动。
    • 复制你即将更新的节点,在副本上工作,然后将之前的节点和新节点交换。
    • 通过display:none属性隐藏元素(只有一次重排重绘),添加足够多的变更后,通过display属性显示(另一次重排重绘)。通过这种方式即使大量变更也只触发两次重排。
    • 不要频繁计算样式。如果你有一个样式需要计算,只取一次,将它缓存在一个变量中并且在这个变量上工作。
    • 通常情况下,考虑一下渲染树和变更后需要重新验证的消耗。举个例子,使用绝对定位会使得该元素单独成为渲染树中body的一个子元素,所以当你对其添加动画时,它不会对其它节点造成太多影响。当你在这些节点上放置这个元素时,一些其它在这个区域内的节点可能需要重绘,但是不需要重排。

    5.2 事件绑定

    当使用 addEventListener()为一个元素注册事件的时候,句柄里的 this 值是该元素的引用。其与传递给句柄的 event 参数的 currentTarget 属性的值一样

    document.addEventListener("mouseover", function(e){
      var target = e.target;
      if(target.nodeName.toLowerCase() === 'a'){
            target.style.color = 'red';
      }
    }, false)
    document.addEventListener("mouseout", function(e){
      var target = e.target;
      if(target.nodeName.toLowerCase() === 'a'){
            target.style.color = '';
      }
    }, false)

    6. 请设计一个算法。将两个有序数组合并为一个数组。请不要使用concat以及sort方法。

    Javascript排序算法之合并排序(归并排序)的2个例子

    function merge(left, right) {
      var result = [],
        il = 0,
        ir = 0;
    
      while (il < left.length && ir < right.length) {
        if (left[il] < right[ir]) {
          result.push(left[il++]);
        } else {
          result.push(right[ir++]);
        }
      }
      result.push(left[il] ? left[il] : right[ir]);
      return result;
    }
    var left = [1, 4, 7];
    var right = [2, 5];
    console.log(merge(left, right))

    这个方法有个缺陷,left更大的时候,后面的元素没了
    改下:

    function merge(left, right) {
      var result = [],
        il = 0,
        ir = 0;
    
      while (il < left.length && ir < right.length) {
        if (left[il] < right[ir]) {
          result.push(left[il++]);
        } else {
          result.push(right[ir++]);
        }
      }
     //这里注意
      result = result.concat(left[il] ? left.slice(il) : right.slice(ir));
      return result;
    }
    var left = [1, 4, 7, 8, 9, 10];
    var right = [2, 5];
    console.log(merge(left, right))


    作者:darr250
    链接:http://www.jianshu.com/p/258a2f734a85
    來源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    How To Mine Bitcoins 比特币挖矿
    Fear No More歌词
    我曾七次鄙视自己的灵魂
    固态硬盘降价,如何选择
    618好物推荐,路由器,手机电脑
    人机验证
    $this->request->post 和input 区别
    APP_DEBUG改成false上线之后发现:“页面错误!请稍后再试~
    Hide()方法不生效
    会声会影x7 每次安装均会提示:已安装这个产品的另一个版本
  • 原文地址:https://www.cnblogs.com/sivkun/p/7586971.html
Copyright © 2020-2023  润新知