在設計HTML頁面的過程中常會遇到表單元素覆蓋樣式元素所造成的問題,圖一就是一個典型的例子。不要小看這個貌似「低級」的問題,即使一些規模較大的網站上類似的問題也絕不鮮見。本文探討了造成這一問題的根本原因,並提出一種補救辦法――之所以說補救辦法而不是一勞永逸的解決辦法,是因為微軟和NetScape這兩個巨頭也還沒有對策。
一、HTML元素的顯示優先權
HTML中常用的表單元素包括:文字區域(TEXTAREA),列錶框(SELECT),文字輸入框(INPUT type=text),密碼輸入框(INPUT type=password),單選輸入框(INPUT type=radio) ,複選輸入框(INPUT type=checkbox),等等。常見的非表單元素包括:連結標記(A),DIV標記,SPAN標記,TABLE標記,等等。表單元素覆蓋樣式元素的根本原因在於HTML元素預設的顯示優先級規則,例如:幀元素總是比其他HTML元素優先,因此也總是顯示在最前面;表單元素總是比所有非表單元素優先。
所有這些HTML元素又可以依其顯示需求分成兩類,即有視窗的HTML元素(Windowed Element),無視窗的HTML元素(Windowless Element)。有視窗的元素包括:SELECT元素,OBJECT元素,插件,IE 5.01以及更早版本中的IFRAME元素。無視窗的元素包括:大多數的普通HTML元素,如連結和TABLE標記,除了SELECT元素之外的大多數表單元素,NS6+/IE 5.5以及更高版本中的IFRAME元素。本文討論的問題主要與有視窗的HTML元素有關,問題的癥結其實就在於作業系統預設總是把有視窗的元素顯示在無視窗的元素前面。
二、瀏覽器類型與顯示優先權
依照瀏覽器類型比較,HTML元素的顯示順序也有所不同,總結如下:
⑴ Netscape/Mozilla
在NS瀏覽器6.0以前的版本中,表單元素總是比其他HTML元素有更高的優先權。但在NS 6+瀏覽器中,IFRAME元素和所有表單元素的顯示順序或由CSS的z-index屬性值決定,或由它們在HTML頁面中出現的順序決定,但SELECT元素除外。
⑵ Internet Explorer
在最新的IE瀏覽器(6.0)中,IFRAME元素和所有表單元素根據z-index屬性值或它們在HTML頁面中出現的次序來決定顯示優先順序,但SELECT元素除外。
⑶ Opera
在最新的Opera(7.10*)瀏覽器中,包括SELECT在內的所有表單元素根據z-index屬性或它們在HTML頁面中的出現次序來決定顯示優先順序。但是,最新的Opera瀏覽器不將IFRAME作為無視窗元素顯示,IFRAME被看做有視窗元素,在顯示順序上要比所有無視窗元素優先。
三、CSS的z-index屬性
我們知道,CSS的z-index屬性可以用來控制任意HTML元素顯示時的覆蓋次序。當多個HTML元素重疊在同一空間中時,z-index值較大的元素會覆寫z-index值較小的元素。
但z-index屬性值不是萬能的。如前所述,有視窗的元素總是顯示在無視窗元素的前面,z-index屬性值只有在同一類別元素之間才起決定作用。形像地說,有視窗元素和無視窗元素就像畫在同一瀏覽器視窗的兩塊不同畫布上,兩類元素分別自成體系,它們的z-index屬性也只相對於同一畫布上的其他元素起作用。
四、補救之道
就目前的瀏覽器而言,比較有效的補救方法是:當無視窗元素需要覆寫有視窗元素時,運用腳本程式動態地隱藏有視窗元素。下面是一個完整的例子:
<html><head>
<style type=text/css>
.menuBlock{position:relative;top:14px;width:165px;border:2px solid black;}
#subMenus{position:relative;left:15px;top:15px;width:171px;
padding-left:2px;padding-right:2px;border:2px solid black;
z-index:100;visibility:hidden;}
#lb_1{position:absolute;left:10px;top:40px; }
</style>
<script type=text/javascript>
var isActive = false;
function showMenu(){
isActive = true;
//document.getElementById(lb_1).style.visibility=hidden;
document.getElementById(subMenus).style.visibility=visible;
}
function hideMenu(){
isActive = false;
setTimeout('hide()',100);
}
function hide(){
if(!isActive){
document.getElementById(subMenus).style.visibility = hidden;
document.getElementById(lb_1).style.visibility=visible;
}
}
function setStyle(menuItem){
isActive = true;
menuItem.style.backgroundColor = Gray;
menuItem.style.color = #FFFFFF
}
function setDefault(menuItem){
isActive = false;
menuItem.style.backgroundColor = ;
menuItem.style.color =
hideMenu();
}
</script></head><body>
<div id=main style=position:absolute;width:200px;>
<div id=menuBlock class=menuBlock onmouseover=showMenu();
onmouseout=hideMenu();>CSS選單</div>
<div id=subMenus >
<div id=0 onmouseover=setStyle(this)
onmouseout=setDefault(this) >選單項目一</div>
<!--共四個選單項目-->
</div><P>
<select id=lb_1 name=lb_1>
<option value=-1/>選擇列表
<!-- 三個選項-->
</select>
</div>
</body></html>
頁面的<STYLE>部分定義了三個樣式,分別用於選單條、選單項目、選擇列表,透過樣式定義保證選單、選擇列表的顯示區域重疊。 <BODY>部分包含選單和<SELECT>選擇清單的定義。當滑鼠經過選單列時,JavaScript函數showMenu執行,顯示出選單,同時隱藏SELECT選擇清單。滑鼠離開後,hideMnu函數隱藏選單,同時恢復選擇清單。其餘幾個JavaScript函數主要用於模擬選單動作,滑鼠經過選單項目時以高亮度顯示選單(setStyle函數),滑鼠離開選單項目時則將它恢復預設顯示形式(setDefault函數)。頁面的運作效果如圖二所示。將showMenu函數中的document.getElementById(lb_1).style.visibility=hidden語句註解掉就可以看到圖一的效果。
<descript>
<img src=http://www.chinahtml.com/cce/img/553/04601t02.jpg>
</descript>
總之,表單元素覆寫樣式元素的根源在於HTML元素預設的顯示優先權規則。本文介紹的補救辦法確實行之有效,不過如果你實在不想用這種辦法,那就只好考慮改變頁面佈局,避免表單元素和樣式元素的顯示區域重疊。