開啟瀏覽自訂 - 自訂 input type="file" 格式

開啟瀏覽自訂 - 自訂 input type="file" 格式

出處:http://audi.tw/blog/css/input.type=file.asp

網頁製作中,有不少難題急壞了所有設計師,例如曾經提過有關於 Flash 遮住下拉選單問題,而其中一個令人頭大的問題,則是表單中的檔案欄位,再怎麼加上 CSS 樣式來修飾,仍然控制不了按鈕中的文字,在 QuirksMode中提過解決方案。不過我個人仍對這個解決方案不太滿意。

問題的成因仍為瀏覽器本身對元件的解釋不同所導致,如:

input type=file
[圖1] 不同瀏覽器對檔案欄位的顯示效果

如[圖1],由上至下,分別是 Netscape 9、Safari 3、FireFox 2以及 Opera 9 對檔案欄位(<input type="file">) 的顯示方式。一般來說,中文瀏覽器中,檔案欄位的按鈕多半為「瀏覽...」,英文版瀏覽器則為「Browse...」,這個字樣沒辦法被改變(以目前而言),因此,我設計了一個代替方案,相容於可顯示 CSS2 效果的瀏覽器中,看起來效果是:

   

事實上,這個問題在 Mozilla 系瀏覽器以安全性考量,封鎖 Javascript 控制檔案欄位按鈕而變得棘手,否則,簡單處理如下:

<form enctype="multipart/form-data" method="post";>
   <input type="file" name="file" size="20" style="display:none;">
   <input type="text" name="upfile" size="20" readonly>
   <input type="button" value="開啟檔案" onclick="this.form.file.click();"> 
  <input type="Submit" name="Submit" value="上傳"> 
</form>

就是紅字部份,Mozilla 系發出 Security error code:1000 的警告,並且不允許執行,於是讓工作變得困難起來。

整個工作的想法是自己設計一個文字欄位和按鈕,來取代檔案欄位,同時,按下按鈕時,又能模擬檔案欄位的按鈕被按下,於是有了這麼一個設計:

<form enctype="multipart/form-data" method="post">
  <input type="file" name="file" id="file" size="20" class="ifile">
  <input type="text" name="upfile" size="20" readonly>
  <input type="button" value="開啟檔案" onclick="this.form.file.click();">
  <input type="Submit" name="Submit" value="上傳">
</form>

<style type="text/css">
.ifile {position:absolute;opacity:0;filter:alpha(opacity=0);}
</style>

   

先講藍字部份,這裡不使用 CSS 指定寬度,直接以 size 指定檔案欄位和文字欄位寬度,以確保在輸入部份的寬度是一致,如下:

 <-- (1) 
  <--(2)

當這部份問題確認後,檔案欄位加上樣式,首以 position:absolute 使檔案欄位變「浮動」區塊,這時,事實上,上例中的(1)直接疊在(2)之上,如下:

  

加點透明度,會看得更清楚:

  

加上透明度是很重要的步驟,整個設計的想法,就是使檔案欄位變成透明,覆蓋在文字欄位和按鈕之上,當按下按鈕時,事實上仍是按到檔案欄位的「瀏覽」鈕。所以為什麼,在稍早要使用 size="20" 來確保兩者寬度一致,就是這個原因。

到目前為止,外觀上的問題就解決了,剩下的,要真正能作用,事實上,仍保留了檔案欄位,不過要把使用者選取的檔案顯示在文字欄位中,使用 onChange 事件,如下(以下為完整可用範例):

<form enctype="multipart/form-data" method="post">
  <input type="file" name="file" id="file" size="20" class="ifile"
     onchange="
        this.form.upfile.value=this.value.substr(this.value.lastIndexOf('\\')+1);
      " >
  <input type="text" name="upfile" size="20" readonly>
  <input type="button" value="開啟檔案" onclick="this.form.file.click();">
  <input type="Submit" name="Submit" value="上傳">
</form>

<style type="text/css">
.ifile {position:absolute;opacity:0;filter:alpha(opacity=0);}
</style>

一般選取的檔案結果看起來像:

C:\Documents and Settings\Administrator\桌面\photo.jpg

簡單使用 Javascript 在檔案欄位內容有變動時,把 photo.jpg 檔名放到 upfile 欄位中。而為了確保其他瀏覽器的運作,尤其你也知道,IE 對檔案欄位的顯示說有多醜就有多噁心,於是,自訂按鈕仍加上 onclick 事件,指定模擬檔案欄位被按下。

好了,你想用「瀏覽」就用吧!想自己訂按鈕文字,也隨你所願,不喜歡用按鈕?那用圖片吧!不過要提醒你,本身檔案欄位的按鈕上就有「瀏覽...」字樣,有一定寬度,用圖片的話,別太小張。