以下為本站文章分類清單

  1. AJAXspacer
  2. ASPspacer
  3. CSSspacer
  4. Javascriptspacer
  5. Windows 應用程式spacer
  6. 網頁設計
  7. 評論、短文、雜文spacer
  8. 版主spacer
  9. 最新回應spacer

以下為本頁本文內容

自訂 input type="file" 格式

網頁製作中,有不少難題急壞了所有設計師,例如曾經提過有關於 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 事件,指定模擬檔案欄位被按下。

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

卜維丰 12/7 07'

以下為文章回應區

同意轉載,不過麻煩看一下轉載需知

劍木拓也   2011/12/27 下午 04:54:00

To樓下:
IE8 測試是正常,稍稍頓了點而已。
我是直接拿這裡的 code 測試。

MichaelYang   2011/10/10 下午 12:28:00

按你所說的測試過,但在IE8中無法使用, 報出的錯誤信息是js 存取被拒,貌似是<input type="text" name="upfile" size="20" readonly>
存放圖片時 超出了它所能支持的數據範圍.

卜維丰   2011/8/9 下午 04:14:00

mrk,
IE7 以下我原本就沒打算花心思去搞相容
IE8 很 OK,還是我們的 IE8 不同?

mrk   2011/7/26 下午 02:59:00

這個方法在ie8、ie9(ie7以下未測)根本行不通

adifly   2009/5/5 下午 05:31:00

請問在firefox 瀏覽器下是否有辦法取得完整的檔案路徑呢?
ps:版主寫得書真的不錯!已入手!不過是當手邊的參考書用

卜維丰   2009/3/12 下午 05:58:00

YangChen, 不管什麼瀏覽器, 都不能改變欄位欄位的值
但送出鈕的控制, IE 和 FF 略不同

YangChen   2009/3/11 下午 03:43:00

請問這個方式為何我在 ie7.0 中無法實現,在最後 submit 都出現 存取拒絕。是否安全性有被修改過不允許透過script 變更 file.value 謝謝?

給個回應
姓名:
佈落格網址:
  如果您是要發問問題, 最好有個問題測試的網址, 這樣比較容易找到您問題所在, 謝謝
內容: