返回 登录
0

前端笔试题

阅读4421

图片垂直居中:
.ver_pic {width: 200px; height: 200px;line-height:200px;text-align: center;background: #eee;}
.ver_pic img { vertical-align:middle;width:100px;height:100px;}

  1. 请用div+css写出左侧固定(width:200px),右侧自适应的页面布局。
    .c_left{float:left;display:inline-block;width:200px;}
    .c_right{margin-left:200px;}

  2. 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)等来替代。

  1. 集合类对象问题
    (1)现有问题:IE中对许多集合类对象取用时可以用 (),但在Firefox只能用[]。
    如:IE中可以使用document.forms(“formName”)来返回名字为”formName”的Form,但在Firefox却行不通。
    (2)解决方法:使用[],上例中可以改为document.forms[“formName”]
  2. HTML元素的ID在JavaScript可见
    (1)现有问题:IE中HTML元素中的ID可以作为document的下属对象变量名直接使用。在Firefox中不能。
    (2)解决方法:使用getElementById(“idName”)代替idName作为对象变量使用。

  3. eval(idName)取得对象
    (1)现有问题:在IE中,利用eval(idName)可以取得ID为idName的HTML对象,在Firefox中不能。
    (2)解决方法:用 getElementById(idName) 代替 eval(idName)。

  4. 变量名与某HTML对象ID相同
    (1)现有问题:在Firefox中,因为对象ID不作为HTML对象的名称,所以可以使用与HTML对象id相同的变量名,IE中不能。
    (2)解决方法:在声明变量时,一律加上var,以避免歧义,这样在IE中亦可正常运行。此外,最好不要取与HTML对象id相同的变量名,以减少错误。

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

  5. 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));

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

  2. 对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) { // 过滤文本结点
    // …
    }
    }

  3. 对document.getElementsByName的解释。
    (1)现有问题:IE中getElementsByName只会检查和元素,而在Firefox下会检查所有元素。
    (2)解决方法:不要使用getElementsByName检查除和之外的元素,如果要获得单个元素,尽量使用getElementById。

  4. 对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;

  1. window.event
    (1)现有问题:使用window.event无法在Firefox上运行
    (2)解决方法:
    原代码(可在IE中运行):



    function gotoSubmit() {
    ...
    alert(window.event); // use window.event
    ...
    }

    新代码(可在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>
    
  2. 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代替。

  1. 多余的逗号
    (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”);
}

  1. 创建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);
    }
    }

  2. 加载XML
    (1)现有问题:如果要加载外部文件IE和Firefox都可以用:
    oXmlDom.async=false; // 这在Firefox中是必须的
    oXmlDom.load(“test.xml”);
    但是它们加载xml字符串的方式不一样,IE中直接可以使用oXmlDom.loadXML(““),而Firefox要使用DOMParser:
    var oParser = new DOMParser();
    var oXmlDom = oParser.parseFromString(“”, “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方法了。

  3. 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方法了。

  4. 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方法了。

  5. 请写出js内存泄漏的问题。
    循环引用:一个DOM对象被多个Javascript对象引用就可能会引发内存泄露
    js闭包的应用:
    DOM插入顺序:

  6. 谈谈你对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());

领悟推荐一些常用的前端开发干货资料,关注之后就能接到最近更新了

前端学习网站
前端e路
前端大牛

评论