表單多文件上傳樣式美化 && 支持選中文件後刪除相關項

来源:http://www.cnblogs.com/imwtr/archive/2016/09/30/5924042.html
-Advertisement-
Play Games

開發中會經常涉及到文件上傳的需求,根據業務不同的需求,有不同的文件上傳情況。 有簡單的單文件上傳,有多文件上傳,因瀏覽器原生的文件上傳樣式及功能的支持度不算太高,很多時候我們會對樣式進行美化,對功能進行完善。 本文根據一個例子,對多文件的上傳樣式做了一些簡單的美化(其實也沒怎麼美化。。),同時支持選 ...


 

開發中會經常涉及到文件上傳的需求,根據業務不同的需求,有不同的文件上傳情況。

有簡單的單文件上傳,有多文件上傳,因瀏覽器原生的文件上傳樣式及功能的支持度不算太高,很多時候我們會對樣式進行美化,對功能進行完善。

 

本文根據一個例子,對多文件的上傳樣式做了一些簡單的美化(其實也沒怎麼美化。。),同時支持選擇文件後自定義刪除相關的文件,最後再上傳

文章篇幅較長,先簡單看看圖示:

目錄

 

一、文件上傳基礎

1. 單文件上傳

最簡單的文件上傳,是單文件上傳,form標簽中加入enctype="multipart/form-data",form表單中有一個input[type="file"]項

<form name="form1" method="post" action="/abc.php" enctype="multipart/form-data">
    <input type="text" name="user" id="user" placeholder="請輸入昵稱">
    <input type="file" name="userImage" id="userImage">
    <input type="submit" name="sub" value="提交">
</form>

2. 多文件上傳

  1)類似單文件上傳,簡單的多文件上傳其實就是多幾個input[type="file"]項

<form name="form1" method="post" action="/abc.php" enctype="multipart/form-data">
    <input type="text" name="user" id="user" placeholder="請輸入昵稱">
    <input type="file" name="userImage1" id="userImage1">
    <input type="file" name="userImage2" id="userImage2">
    <input type="file" name="userImage3" id="userImage3">
    <input type="submit" name="sub" value="提交">
</form>

 

  2) HTML5為表單文件項新增了一個multiple屬性,可以設置實現選擇多個文件,如

<form name="form1" method="post" action="/abc.php" enctype="multipart/form-data">
    <input type="text" name="user" id="user" placeholder="請輸入昵稱">
    <input type="file" name="userImage" id="userImage" multiple>
    <input type="submit" name="sub" value="提交">
</form>

要註意的是,對於multiple這個新屬性,在IE9及以下版本中不被支持,在移動端安卓平臺下會忽略,也就是只能選擇一個文件

 

二、表單文件上傳的美化

看了上面幾個圖片,可以知道原生的文件選擇項樣式是最基本的,主要體現在三個點:

  1. 無邊框,與其他有邊框的元素不合拍
  2. 選擇文件的按鈕樣式太基礎
  3. 選擇多個文件後只顯示總數,未顯示詳細選擇的文件名

基於幾個問題,可以按需對其進行美化

第一點可以直接添加邊框的樣式

第二點需要增添其他元素,可以新增一個按鈕(自行按需美化),將原始文件框隱藏,用JS事件綁定,點擊按鈕後模擬文件框的點擊

<input type="file" name="userImage" id="userImage" style="display: none;">
<input type="button" id="" value="選擇文件" onclick="document.getElementById('userImage').click()">

第三點與第二點類似,也得添加新的元素,選擇文件後,通過JS獲取選擇的文件信息,併在新的元素中顯示出來

想著很簡單,但隨之而來的問題就是,如果選中的文件數量很多,新元素占空間的多少就是個問題,可以預設顯示幾個文件,再通過“查看更多文件”查看到更多的信息

隨之另外的想法是,一次性選中的文件很多,想取消某個文件時,又得重新選擇。這未免太繁瑣,所以需要提供即時刪除某個選中文件的操作

 

三、選中文件後的刪除

要提供選中文件後可刪除的操作,就必然需要提供相關入口及腳本操作,下麵圍繞這點來做些解析

1. 界面的處理

選擇文件後,我們可以通過刪除按鈕刪除選中的文件,因為會出現多文件的情況,所以需要一個信息模版

  <!-- 當前選擇的文件列表 文件信息模版 -->
    <script type="text/template" id="file-temp-item-tpl">
        <span class="file-temp-item" style="{{style}}">
            <span class="file-temp-name">{{name}}</span>
            <span class="file-temp-btn">&times;</span>
        </span>
    </script>

選中的文件一多,就得再增添一個下拉框做輔助,最多顯示5個文件信息,然後通過下拉按鈕展開下拉框(按鈕樣式自行設定)

這裡5個文件間的位置計算的不是很到位,主要是這段代碼,可以自行設定

// 計算每一項坐標left、占寬width
left = i === 0 ? 2 : 2 + i * (100 / fileTempLen);
width = 100 / fileTempLen - 2;

下拉列表裡面的每一項也是一個模版

  <!-- 查看更多文件 文件信息模版 -->
    <script type="text/template" id="file-more-item-tpl">
        <li>
            <span class="file-item-more-name">{{name}}</span>
            <span class="file-item-more-btn">&times;</span>
        </li>
    </script>

以下為初始的HTML結構

  <form name="form" id="form" method="post" action="fileTest.php" enctype="multipart/form-data">
        <!-- <input type="number" name="numberTest" value="100"> -->
        <input type="file" name="fileTest[]" id="fileTest" multiple>
        <!-- 當前選擇的文件列表(最多顯示5條) -->
        <span class="file-temp">
        </span>
        <!-- 查看更多文件 -->
        <ul class="item-more">
        </ul>
        <input type="button" class="btn btn-success" id="uploadBtn" value="上傳">
        <p class="upload-tip">文件上傳成功</p>
    </form>

以下為全部CSS樣式

  1         <link rel="stylesheet" type="text/css" href="bootstrap.min.css">
  2     <style type="text/css">
  3         html {
  4             font-family: Arial;
  5         }
  6 
  7         form {
  8             margin: 50px auto;
  9             width: 400px;
 10         }
 11 
 12         input {
 13             width: 300px;
 14             padding: 4px;
 15         }
 16 
 17         #uploadBtn {
 18             margin-top: -3px;
 19             margin-left: 5px;
 20             width: 60px;
 21             height: 30px;
 22             font-weight: bold;
 23             font-size: 12px;
 24         }
 25 
 26         #fileTest {
 27             display: inline-block;
 28             border: 1px solid #ccc;
 29             border-radius: 3px;
 30         }
 31 
 32         .file-temp {
 33             position: relative;
 34             display: none;
 35             width: 300px;
 36             height: 31px;
 37         }
 38 
 39         .file-temp-item {
 40             position: absolute;
 41             top: 4px;
 42             height: 24px;
 43         }
 44 
 45         .item-more-btn {
 46             display: inline-block;
 47             position: absolute;
 48             top: 18px;
 49             right: 0.5%;
 50             width: 10px;
 51             height: 10px;
 52             color: #777;
 53             cursor: pointer;
 54         }
 55 
 56         .item-more-btn:hover {
 57             border-top-color: #aaa;
 58         }
 59 
 60         .file-temp-name {
 61             display: inline-block;
 62             overflow: hidden;
 63             width: 90%;
 64             height: 26px;
 65             padding: 2px 15px 2px 5px;
 66             border-radius: 2px;
 67             background-color: #eaeaf3;
 68             text-overflow: ellipsis;
 69             white-space: nowrap;
 70         }
 71         .file-temp-btn {
 72             position: absolute;
 73             display: inline-block;
 74             top: 4px;
 75             right: 11%;
 76             width: 18px;
 77             height: 18px;
 78             line-height: 18px;
 79             text-align: center;
 80             border: 1px solid #ddd;
 81             background-color: #ccc;
 82             border-radius: 50%;
 83             color: #fff;
 84             font-size: 18px;
 85             cursor: pointer;
 86         }
 87 
 88         .item-more {
 89             position: absolute;
 90             overflow-y: auto;
 91             display: none;
 92             padding-left: 0;
 93             width: 300px;
 94             max-height: 150px;
 95             list-style: none;
 96         }
 97 
 98         .item-more li {
 99             position: relative;
100             padding: 5px;
101             border: 1px solid #ccc;
102             border-top: none;
103         }
104         .item-more li:hover {
105             background-color: #f5f5f9;
106         }
107 
108         .file-item-more-name {
109             display: inline-block;
110             width: 90%;
111             overflow: hidden;
112             text-overflow: ellipsis;
113             white-space: nowrap;
114         }
115         .file-item-more-btn {
116             position: absolute;
117             display: inline-block;
118             top: 8px;
119             right: 2%;
120             width: 18px;
121             height: 18px;
122             line-height: 18px;
123             text-align: center;
124             border: 1px solid #ddd;
125             background-color: #ddd;
126             border-radius: 50%;
127             color: #fff;
128             font-size: 18px;
129             cursor: pointer;
130         }
131         .file-item-more-btn:hover {
132             background-color: #ccc;
133         }
134 
135         .upload-tip {
136             display: none;
137             margin: 50px auto;
138             text-align: center;
139             font-size: 12px;
140         }
141     </style>    
View Code

 

2. 腳本的處理

下麵,著重介紹JS腳本的處理

要獲取到選中文件的信息,自然想到用value屬性,但通過文件項的value只能獲取到一個文件路徑(第一個),無論有沒有multiple

無multiple

<input type="file" onchange="console.log(this.value);">

有multiple

<input type="file" multiple onchange="console.log(this.value);">

 

既然直接通過value獲取不到所有選中的文件信息,只能尋求其他途徑。

 

  1)FileList

獲取選中的文件信息,還可以用FileList對象,這是在HTML5中新增的,每個表單文件項都有個files屬性,裡邊存儲這選中的文件的一些信息

<input type="file" multiple onchange="console.log(this.files);">

選中兩個文件後,查看文件信息

FileList對象看起來是個類數組,有length屬性。所以我們應該可以通過修改或刪除相關的項來自定義我們選擇的文件(註意其實這是不能修改的,且繼續看下去)

假如我選擇了兩個文件,想刪除第二項目,使用splice刪除,則

<input type="file" multiple onchange="console.log(Array.prototype.splice.call(this.files, 1, 1));">

報錯,由此可知FileList的length屬性是只讀的,那直接修改為可寫可配置呢

Object.defineProperty(FileList.prototype, 'length', {
    writable: true,
    configurable: true
});

配置之後length能修改了,乍一看還以為splice生效了,然而輸出一看,FileList對象內容不變,仍為兩項

查閱了一些資料後,瞭解到瀏覽器為了安全性的考慮,把FileList對象的內容設為了不可更改,只可以手動置空,但不能修改內容

所以,解決辦法是,新增一個數組,初始複製FileList對象的文件內容,之後的修改操作則通過這個可更改的數組進行


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 回到目錄 知識點 本文是一個很另類的文章,在項目中用的比較少,但如果項目中真的出現了這種情況,我們也需要知道如何去解決,對於知識點StringContent和FormUrlEncodedContent我們應該瞭解的多一點,FormUrlEncodedContent是以鍵/值對的形式進行POST數據的 ...
  • A.優化站點資源 速度很重要。用戶很關心。我們的站點必須載入夠快,否則用戶就會走人。SEO 也很重要。我們的站點必須載入夠快,否者搜索排名就會下降。 明白了這樣,我們就來清點一下 【Bootstrap】2.作品展示站點 中的資源。特別的,來看一看我們能控制的、影響頁面速度的重要因素 —— 文件大小, ...
  • 標準文檔流 將窗體自上而下分成一行行, 併在每行中按從左至右的順序排放元素,即為文檔流.每個非浮動塊級元素都獨占一行, 浮動元素則按規定浮在行的一端. 若當前行容不下, 則另起新行再浮動. 標準流的微觀現象 空白摺疊現象 圖片也是一樣,圖片和表單元素可以看成是文字 高矮不齊,底邊對齊 自動換行,一行 ...
  • 用到過PDF的媛媛and猿猿們,總會發現這大千世界之萬能播放器插件,總能少了對媒體控制的介面。 你總會發現PDF無法像img圖片一樣正常載入展現出來,那麼我們在通用語法的基礎上拓展出了適用於預覽及打開的PDF插件便於開發應用。 最主要的是使用到了一個jquery的插件jquery.media.js, ...
  • 一. DOM 分為DOM核心,HTML-DOM和CSS-DOM 1.DOM核心 不專屬與javascript。 獲取對象:document.getElementsByTagName('div') 獲取屬性:elem.getAtrribute('title') 2.html-DOM document. ...
  • 選擇器是jQuery的根基 一. 認識 1.CSS常用的選擇器 標簽選擇器,後代選擇器,Id選擇器,通配符選擇器,類選擇器,群組選擇器——主流瀏覽器全部支持 偽類選擇器,子選擇器,臨近選擇器等等——不是全部被支持 2.jQuery選擇器 比如有個 <p class="demo">demo</p> C ...
  • 一.常用的JavaScript庫對比 Prototype、Dojo、YUI、Mootools jQuery是一個輕量級的JavaScript庫,大型開發必備——由John Resig於2006年創建。 jQuery的理念是:寫得少做得多。 優勢:簡化了Js的複雜操作,不再關心相容性,大量的實用方法。 ...
  • 前言 和其他編程語言一樣,Javascript同樣擁有著很多種設計模式,比如單例模式、代理模式、觀察者模式等,熟練運用Javascript的設計模式可以使我們的代碼邏輯更加清晰,並且更加易於維護和重構。 本文將介紹Javascript模式中較為常見和實用的模式——單例模式,主要分為概念和實例部分。在 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...