1. 程式人生 > >【前端】前端筆試題 [1]

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

func 循環引用 object meid 內核 hresult 分別是 存在 all

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());

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