【前端】前端筆試題 [1]

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瀏覽器兼容性的寫法
* :IE六、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、元素查找問題:
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相同的變量名,以減小錯誤。

  注:三、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。

2、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屬性相同。


3、事件
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);

4、語法
1. const
  (1)現有問題:在IE中不能使用const關鍵字。如const constVar = 32;在IE中這是語法錯誤。
  (2)解決方法:不使用const,以var代替。

2. 多餘的逗號
  (1)現有問題:firefox中對象文字常量允許多餘的逗號,在IE中不容許。下面語句在IE中非法。
      var obj = { 'key' : 'aaa', }
  (2)解決方法:去掉多餘逗號。
  
5、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());javascript

相關文章
相關標籤/搜索