无标题文档
網頁設計Web頁中頁腳(Footer)貼底實現(兼容IE6/7/8, FF3)
最近有個需求,要求讓頁腳貼底,一開始採用了絕對位置的footer方案(設置footer的top),雖然可以應付大部分情況,但有的時候由於頁面不規範,會導致計算出來的高度值太小,導致底部上浮;有的時候甚至會疊在頁面內容之上。我們原本在onmouseup,
onresize,
onload中進行計算,但由於系統的龐大,往往會有一些層的onmouseup事件無法傳上來(可能是調用了stoppropagation或cancelBubble的關係),有很多未知的情況發生。
回過頭來說說這個需求的具體要求:
a.
當可見內容的總高度(不包括頁腳)不超過瀏覽器客戶區域實際高度時,頁腳要貼在瀏覽器底部,但不能有滾動條
(圖中紅色為屏幕顯示區域)
b.
當可見內容的總高度超過瀏覽器客戶區域實際高度時,Web
Design頁腳隨內容向下
(圖中紅色為屏幕顯示區域)
其實是個人第一點想到的就是想辦法計算除去footer高度的內容總高度,問題是總高度怎麼算?什麼時候算?這確實是一個值得思考的問題。
總高度的計算看上去是個很簡單的問題,但實際情況真的是如此嗎?如果我們自己用遍歷DOM的方法來計算高度,恐怕很難得出一個準確的高度,因為並不是所有的元素都要納入高度計算的(例如加了float的元素、position為absolute的元素)。於是想到了請瀏覽器幫忙,盡量用html
DOM原生屬性來解決,這時想到了document或者window的屬性。在IE中,我們找到了document.documentElement.clientHeight(由於我們使用的DOCTYPE是XHTML
1.0的,document.body.clientHeight不能正常工作);而在firefox中,我們找到了window.innerHeight。到目前為止,我們已經可以獲得網站設計
整個頁面的高度了,那去除footer高度的內容總高度自然而然就可以用下面的公式來獲得:
去除footer高度的內容總高度=頁面總高度-footer的高度
接下來要做的就是把這個高度賦給Content的容器(假設是一個ID為contentContainer的DIV),請注意這裡的Content包括任何除footer以外的東西(包括header)。由於有需求b,我們就得考慮如何讓footer在content超過顯示高度後不會繼續被看見(浮在頁面底部),所以肯定不能用top或margin-top,查閱css手冊後,發現有一個屬性最合適——min-height,這個屬性在實際內容不夠時,仍然會保持設置的高度,超過設置高度,會自然增加高度,但有一點,IE6不支持min-height,經實驗表明,在IE6中可以用height代替。
所以我們得到了以下的方案:
var isIE6=navigator.userAgent.indexOf('MSIE 6')>0;
var
isIE=navigator.userAgent.indexOf('MSIE')>0;
ion setFooterPosition()
var objBodycontainer = document.getElementById("ContentContainer");
var
footerHeight=document.getElementById('FooterContainer').offsetHeight;
f(!isIE)
if(window.innerHeight >
footerHeight)
document.getElementById('ContentContainer').style.minHeight =
(window.innerHeight-footerHeight)+'px';
lse
if(isIE6)
{
if(document.documentElement.clientHeight >
footerHeight)
document.getElementById('ContentContainer').style.height =
(document.documentElement.clientHeight-footerHeight)+'px';
}
else
{
if(document.documentElement.clientHeight >
footerHeight)
document.getElementById('ContentContainer').style.minHeight =
(document.documentElement.clientHeight-footerHeight)+'px';
}
}
最後就是選擇重新進行高度計算的時機,由於我們設置的是min-height(除了IE6),所以從根本上保證了不需要在內容高度改變時重新計算高度,但有一種情況必須考慮,那就是瀏覽器的客戶區域大小的改變,所以最後選擇了onresize事件和onload事件。
完整代碼如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<script
language="JavaScript">
var isIE6=navigator.userAgent.indexOf('MSIE
6')>0;
var isIE=navigator.userAgent.indexOf('MSIE')>0;
function setFooterPosition()
{
var objBodycontainer =
document.getElementById("ContentContainer");
var
footerHeight=document.getElementById('FooterContainer').offsetHeight;
if(!isIE)
{
if(window.innerHeight
>
footerHeight)
document.getElementById('ContentContainer').style.minHeight =
(window.innerHeight-footerHeight)+'px';
}
else
{
if(isIE6)
{
if(document.documentElement.clientHeight
> footerHeight)
document.getElementById('ContentContainer').style.height =
(document.documentElement.clientHeight-footerHeight)+'px';
}
else
{
if(document.documentElement.clientHeight >
footerHeight)
document.getElementById('ContentContainer').style.minHeight =
(document.documentElement.clientHeight-footerHeight)+'px';
}
}
}
if(isIE)
{
window.attachEvent("onload",setFooterPosition);
window.attachEvent("onresize",setFooterPosition);
}else
{
window.addEventListener("load",setFooterPosition,false);
window.addEventListener("resize",setFooterPosition,false);
}
</script>
<style
type="text/css">
body
{
margin:0;
}
#content
{
height:300px;
background-color:green;
}
#FooterContainer
{
height:30px;
background-color:red;
}
</style>
<body>
<div
id="ContentContainer">
<div
id="content">aa
</div>
</div>
<div
id="FooterContainer">
</div>
</body>
</html>
另外, 網頁寄存
這種方法有個小漏洞,如果有些層使用了float,可能導致瀏覽器返回的高度值不準確,所以必須使用clear大法來解決這個問題,告訴瀏覽器這些float的高度是需要計算的。
心得:
a.
瀏覽器的很多自帶屬性有時比上層代碼計算出來的值更加準確,畢竟是瀏覽器負責調用渲染引擎的,它比誰都瞭解自己呈現出來的東西
b.
適當調整頁面結構(添加容器),能夠使問題更容易解決。(原本我們的頁面中沒有ContentContainer這樣的同時包含header和content的容器)
留言列表