DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> JavaScript基礎知識 >> 前端面試題及答案整理(二)
前端面試題及答案整理(二)
編輯:JavaScript基礎知識     

Part1 CSS相關

1 內聯元素(inline-element)和塊元素(block element)分別有哪些

常見內聯元素(行內元素)有a、b、span、i 、em、input、select 、img等
常見的塊元素有div、ul、li、h1~h6、talbe、ol、 ul、td、p等

2 浮動相關

浮動布局指將元素脫離普通流/文檔流,使其可以左右移動,直至它的外邊緣遇到包含框或者另一個浮動框的邊緣。浮動框不屬於文檔中的普通流,當一個元素浮動之後,不會影響到塊級元素的布局而只會影響內聯元素的排列。
正因為浮動元素脫離了文檔流,其父級元素並不知道它的存在,因此會表現為高度為0,無論浮動元素如何變化,其父級元素也不會隨它變化將其包裹,這種現象也叫作“高度塌陷”。
下面的例子中,不管#floatDom高度如何變化,#parent高度始終為0,這將導致父元素邊框不能被撐開,背景不能顯示等問題

<div id="parent">
 <div id="floatDOM" style="float:left;width:300px;height:300px;">
 <div style="clear:both">
</div>

因為高度塌陷的存在(這往往不是我們所期望的),必須要清除浮動,下面介紹清除浮動的幾種方式:
•在浮動元素後添加樣式含有“clear:both”的元素

<div id="parent">
 <div id="floatDOM" style="float:left;width:300px;height:300px;">
 <div style="clear:both">
</div>

也可以添加br標簽,其自帶clear:both屬性

<div id="parent">
 <div id="floatDOM" style="float:left;width:300px;height:300px;">
 <br/>
</div>

利用這種方式清除浮動的優點在於通俗易懂,容易掌握,缺點也很明顯,增加了很多無意義的標簽,這個在後期維護中是很痛苦的。
•為父元素添加樣式“overflow:hidden"

<div id="parent" style="overflow:hidden">
 <div id="floatDOM" style="float:left;width:300px;height:300px;">
</div>

利用這種方式不存在結構和語義化問題而且代碼量極少,然而在內容增多的時候容易造成不會自動換行導致內容被隱藏掉,無法顯示需要溢出的元素。
•利用:after偽元素

<style type="text/css">
 .clearfix:after {content:"."; display:block; height:0; visibility:hidden; clear:both; }
 .clearfix { *zoom:1; }
</style>

<div id="parent" class="clearfix">
 <div id="floatDOM" style="float:left;width:300px;height:300px;">
</div>

利用這種方式,僅需在目標元素上添加一個類,也是目前使用最多的一種方式。

Reference
iyunlu.com/view/css-xht

3 相對布局(relative)和絕對布局的區別(absolute)

相對布局和絕對布局最本質的區別在於是否脫離文檔流。
相對布局未脫離文檔流,即設置元素相對布局後,文檔流仍然保持其原始的位置,通過設置top、left等屬性可設置其相對於原始位置的偏移量。
絕對布局是脫離文檔流的,即文檔流中的要素並不知道該絕對布局要素的存在,絕對布局的定位是相對於父元素中具有相對布局或絕對布局的要素,若都不存在則相對於body布局。

4 盒模型(Box Model)

盒模型定義了一個元素的顯示形式,包括content(內容)、padding(內邊距)、border(邊界)以及margin(外邊距)幾部分組成,目前有兩種盒模型標准,一種是W3C標准盒子模型,還有一種是IE盒子模型,采用的是Microsoft自己的標准。

這兩種盒模型的區別主要在於元素寬度的計算。標准模式下css中定義的width即為content(內容)的寬度,整個元素在頁面中占有的寬度,計算公式為:
復制代碼 代碼如下:
  DOM_Width =  width + padding + border + margin

而在IE盒子模型中,css中定義的width為content + padding + border,因此在IE盒子模型中,整個元素在頁面中占有的寬度為(高度同理)

 復制代碼 代碼如下:
 DOM_Width =  width + margin

在CSS3中利用box-sizing保留了兩種盒子模型,當我們設置box-sizing: content-box(默認),采用的是W3C標准盒模型,當設置box-sizing:border-box時,采用的是IE盒模型。

5 CSS reset(重置)

每個浏覽器都有一些自帶的樣式,而且各個浏覽器這些自帶的樣式往往又存在不同,這給我們布局上帶來了一些不便。因此在實踐中往往需要對浏覽器的css樣式進行“清零”,即CSS reset。最簡單的一種reset代碼如下:

*{
 margin:0;
 padding:0;
}

這種方式雖然簡單但太過“暴力”,因為很多要素像div、li等本身默認就沒有margin、padding樣式,這無異於造成大量冗余,更推薦的方式根據自己需要編寫reset代碼。

Reference:
www.zhangxinxu.com/wordpress/2010/08/html5-css-reset

6 CSS hack

由於不同的浏覽器對CSS的解析和支持是不同的,這會導致相同的CSS代碼在不同浏覽器中的顯示方式並不是完全一致的,這就需要通過CSS Hack來解決不同浏覽器的兼容性問題。針對不同浏覽器寫不同的樣式的這個過程就稱為CSS hack。

CSS Hack常見的形式有如下幾種:
•屬性Hack

比如IE6能識別_width以及*width,而在IE7中能識別*width,但是不能識別_width,在FireFox中兩個都不識別。
•選擇符Hack

比如IE6能識別*html .class{},IE7能識別*+html .class{}或者*:first-child+html .class{}
•條件Hack

IE條件注釋是微軟從IE5開始就提供的一種非標准邏輯語句。比如針對所有IE:

<!–[if IE]>
 <!–Your Code–>
 <![endif]–>

針對IE6及以下版本:

<!–[if lt IE 7]>
<!–Your Code–>
<![endif]–>

這類Hack不僅對CSS生效,對寫在判斷語句裡面的所有代碼都會生效。

Reference

http://www.jb51.net/css/226888.html

7 優雅降級(graceful degradation)與漸進增強(progressive enhancement)

漸進增強指針對低版本浏覽器進行構建頁面,保證最基本的功能,然後再針對高級浏覽器進行效果、交互等改進和追加功能達到更好的用戶體驗。

優雅降級指一開始就構建完整的功能,然後再針對低版本浏覽器進行兼容。

兩者的區別在於優雅降級是從復雜的現狀開始,並試圖減少用戶體驗的供給,而漸進增強則是從一個非常基礎的,能夠起作用的版本開始,並不斷擴充,以適應未來環境的需要。降級(功能衰減)意味著往回看;而漸進增強則意味著朝前看,同時保證其根基處於安全地帶。

8 說出遇到的浏覽器兼容問題
•不同浏覽器中顯示的內邊距、外邊距不同,如ul標簽在FireFox中默認是有padding值的,而在IE中只有margin有值

利用CSS Reset(參見第5條)
•IE6的雙倍邊距BUG,在塊級元素浮動後本來外邊距10px,但IE解釋為20px

將其該塊級元素display設置為inline
•IE6中不支持min-height

min-height的作用是作用是當容器的內容較少時,能保持一個最小的高度,以免破壞了布局或UI設計效果。而當容器內的內容增加的時候,容器能夠自動的伸展以適應內容的變化。

通過這種下面的方式可以解決:

#targetDom{
  background:#ccc;
  min-height:100px;
  height:auto!important;
  height:100px;
  overflow:visible;
 }

•在標准的事件綁定中綁定事件的方法函數為addEventListener,而IE使用的是attachEvent

通過條件判斷分別寫兩條綁定語句或者使用jquery這類web框架庫綁定。
•標准浏覽器采用事件捕獲的方式,而IE采用的是事件冒泡機制

後來標准認為冒泡更合理,利用設置addEventListener第三個參數兼容兩種機制,事件冒泡為默認值。
•事件處理中的event屬性IE中獲取方式和標准浏覽器不同

標准浏覽器是作為參數帶入,而ie是window.event方式獲得,獲得目標元素ie為e.srcElement 標准浏覽器為e.target

Part2 其它

1 了解常用http狀態碼

200 OK 一切正常,對GET和POST請求的應答文檔跟在後面。

201 Created服務器已經創建了文檔,Location頭給出了它的URL。

202 Accepted 已經接受請求,但處理尚未完成。

304 Not Modified 客戶端有緩沖的文檔並發出了一個條件性的請求(一般是提供If-Modified-Since頭表示客戶只想比指定日期更新的文檔)。服務器告 訴客戶,原來緩沖的文檔還可以繼續使用。

400 Bad Request 請求出現語法錯誤。

404 Not Found 無法找到指定位置的資源。這也是一個常用的應答。

405 Method Not Allowed 請求方法(GET、POST、HEAD、DELETE、PUT、TRACE等)對指定的資源不適用。(HTTP 1.1新)

500 Internal Server Error 服務器遇到了意料不到的情況,不能完成客戶的請求。

502 Bad Gateway 服務器作為網關或者代理時,為了完成請求訪問下一個服務器,但該服務器返回了非法的應答。

2 手寫ajax請求

//在IE5和IE6中模擬XMLHttpRequest方法
if(window.XMLHttpRequest === undefined){
 window.XMLHttpRequest = function(){
  try{
   return new ActiveXObject("Msxml2.XMLHttp.6.0"); //可用,使用最新ActiveX對象
  }
  catch(e1){
   try{
    return new ActiveXObject("Msxml2.XMLHttp.3.0");//不可用,退後更早的版本
   }
   catch(e2){
    throw new Error("XMLHttpRequest is not supported");
   }
  }
 }
}

//get請求
function xhrGet(url,callback){
 var request = new XMLHttpRequest();
 request.open('GET',url,true);
 request.onreadystatechange = function(){
  if(request.readyState === 4 && request.status == 200){
   callback&&callback(request.responseText);
  }
 };
 request.send(null);
}

//post請求
function xhrPost(url,data,callback){
 var request = new XMLHttpRequest();
 request.open('POST',url,true);
 request.setRequestHeader('Content-Type','application/json');
 request.onreadystatechange = function(){
  if(request.readyState === 4 && request.status == 200){
   callback&&callback(request);
  }
 };
 request.send(JSON.stringfy(data));
}

這是XMLHttpRequest傳統的用法,XMLHttpRequest Level 2提出了很多新的方法,我們常提到的CORS也是源自該方法。


要了解詳細XHR2推薦 XMLHttpRequest Level 2 使用指南

3 跨域問題

當我們在頁面中通過ajax請求其它服務器的數據時,由於浏覽器對於JavaScript的同源策略,客戶端就會發生跨域問題。所謂同源策略,指的是一段腳本只能請求來自相同來源(相同域名、端口號、協議)的資源。

如果上面XMLHttpRequest請求的服務地址與當前文件不同源的話,浏覽器中會出現如下錯誤:

那麼該如何解決這類跨域問題?

(1)利用CORS跨域

"跨域資源共享"(Cross-origin resource sharing,簡稱CORS)。CORS是是在XHR2中拓展的能力,使用方法很簡單,在服務端設置:
Header set Access-Control-Allow-Origin * 

這種設置將接受所有域名的跨域請求,也可以指定具體網址,也可以對域名進行限定:
Header set Access-Control-Allow-Origin http://www.test.com 

然而,這種方式的局限性在於要求客戶端支持,並且服務端進行相關設置。在這兩者滿足的情況下,通過CORS進行跨域不僅支持所有類型的HTTP請求,而且開發者可以使用普通的XMLHttpRequest發起請求和獲得數據,比起JSONP有更好的錯誤處理。

(2)利用JSONP實現跨越

對於較老的浏覽器,它們往往不支持CORS,因此使用JSONP進行跨域也是很常見的一種方式。
我們知道在網頁中通過<script>元素的src指定加載目標腳本時是不受同源策略的影響的,因此可以使用它們從其他服務器請求數據,這種利用<script>元素作為Ajax傳輸的技術就稱為JSONP。

JSONP實現的原理如下:

function getJSONP(url, callback){
  var funcName = getUniqueName();//利用時間戳或指自增計數器獲得唯一函數名
  
  url += "?callback=" + funcName; //將函數名作為參數添加至url中
  
  var script = document.createElement('script');//動態構建script標簽
  
  //回調函數
  getJSONP[funcName] = function(response){
   try{
    callback(response); //處理響應數據
   }
   finally{
    //即使回調函數或響應拋出錯誤,清除動態增加內容
    delete getJSONP[funcName];
    script.parentNode.removeChild(scirpt);
   }
  }
  
  //觸發HTTP請求
  script.src = url;
  document.body.appendChild(script);
 }

JSONP也存在一些弊端,首先JSONP支持GET不支持POST方法,另外使用<script>元素進行Ajax請求,這意味著允許Web頁面可以執行遠程服務器發送過來的任何JavaScript代碼,因此對於不信任的服務器,不應該采用該技術。

(3)利用window.name進行跨域

window對象有個name屬性,該屬性有個特征:即在一個窗口(window)的生命周期內,窗口載入的所有的頁面都是共享一個window.name的,每個頁面對window.name都有讀寫的權限,window.name是持久存在一個窗口載入過的所有頁面中的,並不會因新頁面的載入而進行重置,因此可以借助window.name在不同源的頁面中傳遞數據。

如www.a.com/a.html想要獲得www.b.com/b.html中的數據,原理如下:

a) 在b.html中將數據存儲在window.name中

b) 在a.html中構建一個隱藏(display:none)的iframe標簽,假設id設為proxy,src設置為和a.html同源即可。

c) 通過如下代碼在a.html中獲取到data

 var proxy = document.getElementById('proxy');
 proxy.onload = function(){
  var data = proxy.contentWindow.name;//獲取到數據
 }

d) 移除相關元素

(4) 使用window.postMessage進行跨域

這種方式比較簡單,在a頁面中利用windowObj.postMessage(message, targetOrigin)向目標頁面發送信息,而在b頁面中通過監聽message事件獲取信息。這種方式是在HTML5中新增的方法,對於IE6、IE7等老版本浏覽器無法使用。

4 如何提高網站性能

請參看博主的另外兩篇文章:

關於提高網站性能的幾點建議

關於提高網站性能的幾點建議2

發現新內容會持續更新...

博文作者:vicfeel

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved