前端开发面试笔试题汇总

发表于2016-06-22 10:38:41

1.        请用div+css写出文字水平垂直居中,图片水平垂直居中的样式及布局。

2.        请用div+css写出左侧固定(width:200px),右侧自适应的页面布局。

3.        请写出至少五种css浏览器兼容性的写法。

4.        jquery的绑定事件有几种方式 ,请举例说明其优缺点。

5.        请写出至少三种js浏览器兼容性的写法。

6.        请写出js内存泄漏的问题。

7.        谈谈你对js闭包的理解。

8.        js面向对象的几种方式。


1.        请用div+css写出文字水平垂直距中,图片水平垂直距中的样式及布局。 

单文字垂直居中:

.align_cc{height:30px;line-height:30px;text-align:center; }

多行文字垂直居中:

.align_box {width: 220px;height: 200px;display: table-cell;vertical-align: middle;text-align: center;*position: relative;}                

.align_box span.align_word {display: inline-block;*position: absolute;*left: 0;*top: 50%;*width: 100%;}

.align_box span.align_word a {*display: inline-block;*position: relative;*top: -50%;}

<div class="align_box">

        <span class="align_word">

                <a href="">文字垂直居中对齐文字垂直居中对齐文字垂直居中对齐</a>

        </span>

</div>

图片垂直居中: 

.ver_pic {width: 200px; height: 200px;line-height:200px;text-align: center;background: #eee;} 

.ver_pic img { vertical-align:middle;width:100px;height:100px;}


2.        请用div+css写出左侧固定(width:200px),右侧自适应的页面布局。 

.c_left{float:left;display:inline-block;width:200px;} 

.c_right{margin-left:200px;} 


3.  css浏览器兼容性的写法

* :IE6、IE7可以识别;

_和- :IE6可以识别;

!important :表示高优先级,IE7及以上、Firefox都支持,IE6认识带!important的样式属性,但不认识!important的优先级

-webkit- :针对谷歌浏览器内核支持的CSS样式

-moz- :针对Firefox浏览器的内核CSS写法

-ms- :针对ie内核CSS写法

-o- :针对opera内核CSS写法


4.jQuery中提供了四种事件监听方式,分别是bind、live、delegate、on,对应的解除监听的函数分别是unbind、die、undelegate、off。

bind()可以向匹配的元素绑定一个或者多个事件处理器。但是它不会在没有存在dom树中的元素绑定该事件;而live()、delegate()则可以实现在不存在dom树中的元素继续绑定事件.

live方法其实是bind方法的变种,其基本功能同bind方法的功能一样都是为一个元素绑定某个事件,但是bind方法只能给当前存在的元素绑定事件,对于事后采用JS等方式新生成的元素无效,而live方法则正好弥补了bind方法的这个缺陷,它可以对后生成的元素也可以绑定相应的事件。

live()方法用到了事件委托的概念来处理事件的绑定,会绑定相应的事件到你所选择的元素的根元素上,即是document元素上,一旦事件冒泡到document上,jQuery将会查找selector/event metadata,然后决定那个handler应该被调用。

delegate()有点像.live(),不同于.live()的地方在于,它不会把所有的event全部绑定到document,而是由你决定把它放在哪儿。而和.live()相同的地方在于都是用event delegation.

其实.bind(), .live(), .delegate()都是通过.on()来实现的,.unbind(), .die(), .undelegate(),也是一样的都是通过.off()来实现的。

bind的缺点:

它会绑定事件到所有的选出来的元素上,当元素很多时,会出现效率问题;

当页面加载完的时候,你才可以进行bind();

它不会绑定到在它执行完后动态添加的那些元素上。

live的优点:

仅有一次的事件绑定,绑定到document上;

动态添加的elemtns依然可以触发那些早先绑定的事件,因为事件真正的绑定是在document上;

可以在document ready之前就可以绑定那些需要的事件。

live的缺点:

从jq1.7开始已经不被推荐了;

当一个元素采用live方法进行事件的绑定的时候,如果想阻止事件的传递或冒泡,就要在函数中return false,仅仅调用stopPropagation()是无法实现阻止事件的传递或者冒泡的,因为都要到达document,所以速度也会非常慢;

delegate的优点:

可以选择把这个事件放到哪个元素上了,可以有效的减小你所要查找的元素;

可以用在动态添加的元素上。

delegate的缺点:

需要查找哪个元素上发生了那个事件,尽管比document少很多了,不过,还是得浪费时间来查找。

on的优点:

提供了一种统一绑定事件的方法,可以用.on()来代替上述的3种方法。

one是在dom树加载后,对元素的绑定,和bind一样属于后期绑定,但是会在事件执行之后移除元素的绑定事件,事件只执行一次。


5.js浏览器兼容性的写法:

一、元素查找问题:

1. document.all[name]  (1)现有问题:Firefox不支持document.all[name]  (2)解决方法:使用getElementsByName(name),getElementById(id)等来替代。


2. 集合类对象问题

  (1)现有问题:IE中对许多集合类对象取用时可以用 (),但在Firefox只能用[]。

      如:IE中可以使用document.forms("formName")来返回名字为"formName"的Form,但在Firefox却行不通。

   (2)解决方法:使用[],上例中可以改为document.forms["formName"]

3. HTML元素的ID在JavaScript可见

  (1)现有问题:IE中HTML元素中的ID可以作为document的下属对象变量名直接使用。在Firefox中不能。

  (2)解决方法:使用getElementById("idName")代替idName作为对象变量使用。


4. eval(idName)取得对象

  (1)现有问题:在IE中,利用eval(idName)可以取得ID为idName的HTML对象,在Firefox中不能。

  (2)解决方法:用 getElementById(idName) 代替 eval(idName)。

  

5. 变量名与某HTML对象ID相同

  (1)现有问题:在Firefox中,因为对象ID不作为HTML对象的名称,所以可以使用与HTML对象id相同的变量名,IE中不能。

  (2)解决方法:在声明变量时,一律加上var,以避免歧义,这样在IE中亦可正常运行。此外,最好不要取与HTML对象id相同的变量名,以减少错误。


  注:3、4和5都属于同一类的问题。


6. Frame

  (1)现有问题:在IE中可以用window.top.frameId和window.top.frameName来得到该Frame所代表的Window,Firefox中只能用window.top.frameName。

  (2)解决方法:将Frame的Id和Name设置成相同,使用window.top.frameName来访问Frame。


二、DOM操作

1. 设置元素的文本内容。

  (1)现有问题:IE使用innerText,而Firefox使用textContent来设置元素文本内容。

  (2)解决方法:如果文本内容不包含"<"和">"等特殊字符,可以使用innerHTML。否则,可以使用:

        var child = elem.firstChild;

            if (child != null) elem.removeChild(child);

            elem.appendChild(document.createTextNode(content));


2. parentElement,parent.children

  (1)现有问题:IE可以使用parentElement获得父结点,parent.children得到结点的所有孩子结点。Firefox不支持。

  (2)解决方法:使用parentNode和parent.childNodes。


3. 对childNodes的解释。

  (1)现有问题:IE和Firefox中对childNodes的解释不同,IE不会包含空白文本结点,而Firefox会包含。

  (2)解决方法:使用childNodes过滤文本结点,如下:

      var children = elem.childNodes;

          for (i = 0; i < children.length; i++) {

            if (children[i].nodeType != 3) { // 过滤文本结点

              // ...

            }

          }


4. 对document.getElementsByName的解释。

  (1)现有问题:IE中getElementsByName只会检查<input>和<img>元素,而在Firefox下会检查所有元素。

  (2)解决方法:不要使用getElementsByName检查除<input>和<img>之外的元素,如果要获得单个元素,尽量使用getElementById。


5. 对document.getElementById的解释。

  (1)现有问题:IE中getElementById不仅检查Id属性,也会检查Name属性,当Name属性匹配参数时也会返回该元素。而在Firefox中只会检查Id属性。

  (2)解决方法:尽量保持Id和Name相同,不要让一个元素name属性和另一个元素的id属性相同。



三、事件

1. event.x与event.y问题

  (1)现有问题:在IE中,event对象有x,y 属性,Firefox中没有。

  (2)解决方法:在Firefox中,与event.x 等效的是 event.pageX。可以使用:

      mX = event.x ? event.x : event.pageX;

      

2. window.event

  (1)现有问题:使用window.event无法在Firefox上运行

  (2)解决方法:

         原代码(可在IE中运行):

            <input type="button" name="someButton" value="提交" onclick="javascript:gotoSubmit()"/>

            ...

            <script language="javascript">

                function gotoSubmit() {

                    ...

                    alert(window.event);    // use window.event

                    ...

                }

            </script>


        新代码(可在IE和Firefox中运行):

            <input type="button" name="someButton" value="提交" onclick="javascript:gotoSubmit(event)"/>

            ...

            <script language="javascript">

                function gotoSubmit(evt) {

                    evt = evt ? evt : (window.event ? window.event : null);

                    ...

                    alert(evt);             // use evt

                    ...

                }

            </script>


3. attachEvent和addEventListener

  (1)现有问题:IE中使用attachEvent来添加事件,Firefox中使用addEventListener。

  (2)解决方法:如下,注意事件参数的区别,一个是click,一个是onclick。

        if (document.attachEvent) document.attachEvent("click", clickHandler,false);

        else document.addEventListener("onclick",clickHandler);


四、语法

1. const

  (1)现有问题:在IE中不能使用const关键字。如const constVar = 32;在IE中这是语法错误。

  (2)解决方法:不使用const,以var代替。


2. 多余的逗号

  (1)现有问题:firefox中对象文字常量容许多余的逗号,在IE中不允许。下面语句在IE中非法。

      var obj = { 'key' : 'aaa', }

  (2)解决方法:去掉多余逗号。

  

五、XML

1. 创建XMLHttpRequest

  (1)现有问题:Firefox使用XMLHttpRequest,IE使用ActiveXObject。

  (2)解决方法:

      if (window.XMLHttpRequest) {

          req = new XMLHttpRequest();

      } else if (window.ActiveXObject) {

          req = new ActiveXObject("Microsoft.XMLHTTP");

      }


2. 创建DOM

  (1)现有问题:Firefox和IE创建DOM的方式不同。

  (2)解决方法:

        function createXmlDom() {

          var oXmlDom;

          if (Window.ActiveXObject) { // IE

            oXmlDom = new ActiveXObject("Microsoft.XmlDom");

          } else {  // Firefox

            oXmlDom = document.implementation.createDocument("", "", null);

          }

        }


3. 加载XML

  (1)现有问题:如果要加载外部文件IE和Firefox都可以用:

          oXmlDom.async=false;      // 这在Firefox中是必须的

          oXmlDom.load("test.xml");

     但是它们加载xml字符串的方式不一样,IE中直接可以使用oXmlDom.loadXML("<root><child/></root>"),而Firefox要使用DOMParser:

        var oParser = new DOMParser();

          var oXmlDom = oParser.parseFromString("<root/>", "text/xml");

  (2)解决方法:比较好的方法是给Firefox产生的XMLDom加上loadXML方法:

        if (isFirefox) { // 需要浏览器检测

          Document.prototype.loadXML = function(sXml) {

            var oParser = new DOMParser();

            var oXmlDom = oParser.parseFromString(sXml, "text/xml");

            

            while (this.firstChild) this.removeChild(this.firstChild);

            

            for (var i = 0; i < oXmlDom.childNodes.length; i++) {

              var oNewNode = this.importNode(oXmlDom.childNodes[i], true);

              this.appendChild(oNewNode);

            }

          }

        }

      这样在IE和Firefox就可以调用loadXML方法了。

      

4. XPath支持

  (1)现有问题:IE中可以直接用XmlDOM的selectNodes来根据XPath表示式来选择结点,Firefox则比较复杂,需要使用XPathEvaluator。

     IE: 

        var lstNodes = oXmlDom.documentElement.selectNodes("employee/name");

        for (var i = 0; i < lstNodes.length; i++) {

          alert(lstNodes[i].firstChild.nodeValue);

        }

     Firefox: 

          var oEvaluator = new XPathEvaluator();

          var oResult = oEvaluator.evaluate("employee/name", oXmlDom.documentElement, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);

          var oElement = oResult.iterateNext();

          while (oElement) {

            alert(oElement.firstChild.nodeValue);

            oElement = oResult.iterateNext();

          }

  (2)解决方法:比较好的方法给Firefox的Element添加selectNodes方法。

        if (isFirefox) { // 需要浏览器检测

            Element.prototype.selectNodes = function(sXPath) {

            var oEvaluator = new XPathEvaluator();

              var oResult = oEvaluator.evaluate(sXPath, this, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);

              

              var aNodes = new Array();

              

              if (oResult != null) {

                var oElement = oResult.iterateNext();

                while (oElement) {

                  aNodes.push(oElement);

                  oElement = oResult.iterateNext();

                }

              }

              return aNodes;

           }

      }

   这样在IE和Firefox中就都可以调用selectNodes方法了。

   

5. XSLT支持

  (1)现有问题:IE中可以使用XmlDOM的transferNode方法将其转换成html,而Firefox需要使用XSLTProcessor。

  IE:

        oXmlDom.load("employee.xml");

        oXslDom.load("employee.xslt");

        var sResult=oXmlDom.transformNode(oXslDom);

    Firefox:

        var oProcessor = new XSLTProcessor();

        oProcessor.importStylesheet(oXslDom);

        var oResultDom = oProcessor.transformToDocument(oXmlDom);        

        var oSerializer = new XMLSerializer();

        var sXml = oSerializer.serializeToString(oResultDom, "text/xml");

        alert(sXml);

  (2)解决方法:比较好的方法给Firefox的Node添加transferNode方法。

        if (isFirefox) { // 需要浏览器检测

          Node.prototype.transformNode = function(oXslDom) {

          var oProcessor = new XSLTProcessor();

            oProcessor.importStylesheet(oXslDom);

            var oResultDom = oProcessor.transformToDocument(oXmlDom);

            

            var oSerializer = new XMLSerializer();

            var sXml = oSerializer.serializeToString(oResultDom, "text/xml");

            

            return sXml;

          }

        }

   这样在IE和Firefox中就都可以调用transferNode方法了。


6.        请写出js内存泄漏的问题。

循环引用:一个DOM对象被多个Javascript对象引用就可能会引发内存泄露

js闭包的应用:

DOM插入顺序:


7.        谈谈你对js闭包的理解。 

考的是变量的作用域。闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。 

1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,

在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。 

2)闭包会在父函数外部,改变父函数内部变量的值。

所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。


8.js面向对象的几种方式。

第一种模式:工厂方式 

var lev=function(){ return "脚本之家"; }; 

function Parent(){ var Child = new Object(); Child.name="脚本"; Child.age="4"; Child.lev=lev; return Child; }; 

var x = Parent(); 

alert(x.name); 

alert(x.lev()); 

第二种模式:构造函数方式 

var lev=function(){ return "脚本之家"; }; 

function Parent(){ this.name="脚本"; this.age="30"; this.lev=lev; }; 

var x =new Parent(); 

alert(x.name); 

alert(x.lev()); 

第三种模式:原型模式 

var lev=function(){ return "脚本之家"; }; 

function Parent(){ }; 

Parent.prototype.name="李小龙"; 

Parent.prototype.age="30"; 

Parent.prototype.lev=lev; 

var x =new Parent(); 

alert(x.name); 

alert(x.lev()); 

第四种模式:混合的构造函数,原型方式(推荐) 

function Parent(){ this.name="脚本"; this.age=4; }; 

Parent.prototype.lev=function(){ return this.name; };

var x =new Parent(); 

alert(x.lev()); 

第五种模式:动态原型方式 

function Parent(){ this.name="脚本"; this.age=4; if(typeof Parent._lev=="undefined"){ 

        Parent.prototype.lev=function(){ return this.name; } Parent._lev=true; } 

}; 

var x =new Parent(); 

alert(x.lev());


评论(0)

请先登录后再评论,如果没有账号请先注册

发表评论