最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS實現(xiàn)表單多文件上傳樣式美化支持選中文件后刪除相關(guān)項

 更新時間:2016年09月30日 16:21:58   作者:imwtr  
在項目開發(fā)中我們經(jīng)常遇到文件上傳的功能,根據(jù)需求有多文件上傳和單文件上傳,今天小編給大家實例講解下表單多文件上傳樣式美化支持選中文件后刪除相關(guān)項,非常不錯,感興趣的朋友一起看看吧

開發(fā)中會經(jīng)常涉及到文件上傳的需求,根據(jù)業(yè)務(wù)不同的需求,有不同的文件上傳情況。

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

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

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

一、文件上傳基礎(chǔ)

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屬性,可以設(shè)置實現(xiàn)選擇多個文件,如

<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>

二、表單文件上傳的美化

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

無邊框,與其他有邊框的元素不合拍
選擇文件的按鈕樣式太基礎(chǔ)
選擇多個文件后只顯示總數(shù),未顯示詳細選擇的文件名
基于幾個問題,可以按需對其進行美化

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

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

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

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

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

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

三、選中文件后的刪除

要提供選中文件后可刪除的操作,就必然需要提供相關(guān)入口及腳本操作,下面圍繞這點來做些解析

1. 界面的處理

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

<!-- 當前選擇的文件列表 文件信息模版 -->
<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個文件信息,然后通過下拉按鈕展開下拉框(按鈕樣式自行設(shè)定)

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

// 計算每一項坐標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結(jié)構(gòu)

 <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樣式

<link rel="stylesheet" type="text/css" href="bootstrap.min.css">
  <style type="text/css">
    html {
      font-family: Arial;
    }
    form {
      margin: 50px auto;
      width: 400px;
    }
    input {
      width: 300px;
      padding: 4px;
    }
    #uploadBtn {
      margin-top: -3px;
      margin-left: 5px;
      width: 60px;
      height: 30px;
      font-weight: bold;
      font-size: 12px;
    }
    #fileTest {
      display: inline-block;
      border: 1px solid #ccc;
      border-radius: 3px;
    }
    .file-temp {
      position: relative;
      display: none;
      width: 300px;
      height: 31px;
    }
    .file-temp-item {
      position: absolute;
      top: 4px;
      height: 24px;
    }
    .item-more-btn {
      display: inline-block;
      position: absolute;
      top: 18px;
      right: 0.5%;
      width: 10px;
      height: 10px;
      color: #777;
      cursor: pointer;
    }
    .item-more-btn:hover {
      border-top-color: #aaa;
    }
    .file-temp-name {
      display: inline-block;
      overflow: hidden;
      width: 90%;
      height: 26px;
      padding: 2px 15px 2px 5px;
      border-radius: 2px;
      background-color: #eaeaf3;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .file-temp-btn {
      position: absolute;
      display: inline-block;
      top: 4px;
      right: 11%;
      width: 18px;
      height: 18px;
      line-height: 18px;
      text-align: center;
      border: 1px solid #ddd;
      background-color: #ccc;
      border-radius: 50%;
      color: #fff;
      font-size: 18px;
      cursor: pointer;
    }
    .item-more {
      position: absolute;
      overflow-y: auto;
      display: none;
      padding-left: 0;
      width: 300px;
      max-height: 150px;
      list-style: none;
    }
    .item-more li {
      position: relative;
      padding: 5px;
      border: 1px solid #ccc;
      border-top: none;
    }
    .item-more li:hover {
      background-color: #f5f5f9;
    }
    .file-item-more-name {
      display: inline-block;
      width: 90%;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .file-item-more-btn {
      position: absolute;
      display: inline-block;
      top: 8px;
      right: 2%;
      width: 18px;
      height: 18px;
      line-height: 18px;
      text-align: center;
      border: 1px solid #ddd;
      background-color: #ddd;
      border-radius: 50%;
      color: #fff;
      font-size: 18px;
      cursor: pointer;
    }
    .file-item-more-btn:hover {
      background-color: #ccc;
    }
    .upload-tip {
      display: none;
      margin: 50px auto;
      text-align: center;
      font-size: 12px;
    }
  </style>

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對象看起來是個類數(shù)組,有l(wèi)ength屬性。所以我們應(yīng)該可以通過修改或刪除相關(guān)的項來自定義我們選擇的文件(注意其實這是不能修改的,且繼續(xù)看下去)

假如我選擇了兩個文件,想刪除第二項目,使用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生效了,然而輸出一看,F(xiàn)ileList對象內(nèi)容不變,仍為兩項

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

所以,解決辦法是,新增一個數(shù)組,初始復(fù)制FileList對象的文件內(nèi)容,之后的修改操作則通過這個可更改的數(shù)組進行

// 存儲更新所選文件
var curFiles = []; 
...
// 選中文件后
var files = this.files;
if (files && files.length) {
// 原始FileList對象不可更改,所以將其賦予curFiles提供接下來的修改
Array.prototype.push.apply(curFiles, files);
}

假如點擊了刪除叉叉,可以直接更新文件信息數(shù)組

var name = $(this).prev().text();
// 去除該文件
curFiles = curFiles.filter(function(file) {
return file.name !== name;
});

這樣一來,更新文件信息的問題得到解決,然后就可以進行文件的上傳了

點擊文件上傳,如果直接調(diào)用$form.submit(); 則上傳的文件信息依然是初始的FileList對象,達不到我們自定義的要求,所以需要用Ajax提交

那么,該怎么想后臺提供一個文件對象呢?

  2)FormData

HTML5引入了表單的新對象FormData, 它可以生成一個表單對象,我們可以向其中獲取/設(shè)置鍵值對信息,再一并提交給后臺

引用MDN的FormData使用方法,我們可以添加各種類型的數(shù)據(jù),使用ajax提交

var oMyForm = new FormData();
oMyForm.append("username", "Groucho");
oMyForm.append("accountnum", 123456); // 數(shù)字123456被立即轉(zhuǎn)換成字符串"123456"
// fileInputElement中已經(jīng)包含了用戶所選擇的文件
oMyForm.append("userfile", fileInputElement.files[0]);
var oFileBody = '<a id="a"><b id="b">hey!</b></a>'; // Blob對象包含的文件內(nèi)容
var oBlob = new Blob([oFileBody], { type: "text/xml"});
oMyForm.append("webmasterfile", oBlob);
var oReq = new XMLHttpRequest();
oReq.open("POST", "http://foo.com/submitform.php");
oReq.send(oMyForm);

也可使用JQ的封裝的ajax,不過要注意設(shè)置processData和contentType屬性為false,防止JQ胡亂解析文件格式

var fd = new FormData(document.getElementById("fileinfo")); // 使用某個表單作為初始項
fd.append("CustomField", "This is some extra data");
$.ajax({
url: "stash.php",
type: "POST",
data: fd,
processData: false, // 告訴jQuery不要去處理發(fā)送的數(shù)據(jù)
contentType: false // 告訴jQuery不要去設(shè)置Content-Type請求頭
});

這里有幾個要注意的點:

1)FormData中的屬性值接受的是單個文件信息,不能是復(fù)合性的對象??赡鼙硪獠幻鳎铱?/p>

var fd = new FormData($('#form')[0]);
fd.append('myFileTest', curFiles);
$files = $_REQUEST['myFileTest'];
var_dump($files);

用PHP接收傳過來的數(shù)據(jù),數(shù)據(jù)卻被直接轉(zhuǎn)換成字符串了,非文件對象

curFiles是文件對象,那PHP端是不是應(yīng)該用$_FILES來接收信息呢,試試換成$files = $_FILES['myFileTest'];

直接出問題了,說明不能這樣處理,需要將curFiles內(nèi)容一項一項拆開,即單個文件信息

var fd = new FormData($('#form')[0]);
for (var i = 0, j = curFiles.length; i < j; ++i) {
fd.append('myFileTest[]', curFiles[i]);
}
$files = $_FILES['myFileTest'];
var_dump($files);

文件接收成功,接下來就可以按需進行文件的操作了

2)后端獲取文件信息的時候,是直接通過原始$_FILES獲取的,其他一般的信息才用$_REQUEST獲取

換成$files = $_REQUEST['myFileTest'];試試,直接就是出現(xiàn)找不到myFileTest的問題

試試添加一般的文件再提交

var fd = new FormData($('#form')[0]);
for (var i = 0, j = curFiles.length; i < j; ++i) {
fd.append('myFileTest[]', curFiles[i]);
}
fd.append('myTest', [1, 2, 3]);
$files = $_FILES['myFileTest'];
$test = $_REQUEST['myTest'];
var_dump($test);
var_dump($files);

3)如果需要multiple的多文件上傳,則需要在文件項的文件后添加[]號,表示這是一個多文件的數(shù)組,以供后端處理解析

fd.append('myFileTest[]', curFiles[i]);

如果沒有后面的[],則連續(xù)的append會直接覆蓋原來的,最后后端獲取到的只是最后append進去的項

4)不要直接在JQ的ajax中實例化出一個FormData對象,會出問題

直接在data屬性中生成FormData對象,會被JQ忽略,所以后端什么信息也拿不到

混合表單項簡單的例子:

在表單處理中,很多時候我們會進行文件上傳和其他基礎(chǔ)項的提交,簡單地多加一個input項目,看看是否處理成功

<input type="number" name="numberTest" value="100">

<?php
$files = $_FILES['myFileTest'];
$test = $_REQUEST['numberTest'];
echo json_encode(array(
'len' => count($files['name']),
'num' => $test
));
?>

以下為全部的JS腳本:

<script type="text/javascript">
/**
* 向文件列表元素中添加相應(yīng)的文件項
* @param {Array} files 當前的文件列表數(shù)組對象
*/
function addItem(files) {
var fileTempItemTpl = $('#file-temp-item-tpl').html(),
fileMoreItemTpl = $('#file-more-item-tpl').html()
htmlTemp = [],
htmlMoreTemp = [],
// 文件列表中各文件坐標位置及所占空間
left = 2,
width = 100,
// 最多取前5個文件
fileTempLen = files.length > 5 ? 5 : files.length;
for (var i = 0, j = files.length; i < j; ++i) {
// 當i > 4,即第6個文件開始
if (i > 4) {
htmlMoreTemp.push(fileMoreItemTpl.replace('{{name}}', files[i].name));
continue;
}
// 計算每一項坐標left、占寬width
left = i === 0 ? 2 : 2 + i * (100 / fileTempLen);
width = 100 / fileTempLen - 2;
htmlTemp.push(fileTempItemTpl
.replace('{{style}}', 'left: ' + left + '%;width: ' + width + '%;')
.replace('{{name}}', files[i].name)
);
}
// 渲染相關(guān)元素內(nèi)容
$('.file-temp').html(''
+ '<input type="text" style="background-color:#fff;" class="form-control" id="fileTemp" readonly>'
+ htmlTemp.join('')
+ (files.length > 5
? '<span class="item-more-btn" title="查看更多">=</span>'
: ''
)
);
$('.item-more').html(htmlMoreTemp.join(''));
}
// 保存當前選擇的(更新后)文件列表
var curFiles = [];
// 初始選擇文件時觸發(fā)
$('#fileTest').change(function() {
var $this = $(this),
$temp = $('.file-temp'),
files = this.files;
if (files && files.length) {
// 原始FileList對象不可更改,所以將其賦予curFiles提供接下來的修改
Array.prototype.push.apply(curFiles, files);
addItem(curFiles);
$this.hide();
$temp.css('display', 'inline-block');
}
});
$(document)
// 取消選擇某個文件時,在文件列表數(shù)組對象中刪除這個值,并更新列表
.on('click', '.file-temp-btn, .file-item-more-btn', function() {
$('.upload-tip').hide();
var name = $(this).prev().text();
// 去除該文件
curFiles = curFiles.filter(function(file) {
return file.name !== name;
});
// 文件列表數(shù)組對象長度大于5才顯示“更多文件列表”下拉項
if (curFiles.length <= 5) {
$('.item-more').hide();
}
// 文件列表數(shù)組被清空則重置文件選擇表單項
if (!curFiles.length) {
$('#fileTest').val('').show();
$('.file-temp').css('display', 'none');
} else {
addItem(curFiles);
}
console.log(curFiles)
})
// 顯示“更多文件列表”下拉項
.on('click', '.item-more-btn', function() {
$('.upload-tip').hide();
$('.item-more').show('normal');
});
// 上傳操作
$('#uploadBtn').click(function() {
$('.upload-tip').hide();
// 構(gòu)建FormData對象
var fd = new FormData($('#form')[0]);
for (var i = 0, j = curFiles.length; i < j; ++i) {
fd.append('myFileTest[]', curFiles[i]);
}
$.ajax({
url: 'fileTest.php',
type: 'post',
data: fd,
processData: false,
contentType: false,
success: function(rs) {
rs = JSON.parse(rs);
$('.upload-tip')
.addClass('text-success')
.removeClass('text-error')
.text(rs.len + '個文件上傳成功, number項值為' + rs.num)
.show();
},
error: function(err) {
}
});
});
</script>

以上所述是小編給大家介紹的JS實現(xiàn)表單多文件上傳樣式美化支持選中文件后刪除相關(guān)項,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

  • JavaScript日期對象(Date)基本用法示例

    JavaScript日期對象(Date)基本用法示例

    這篇文章主要介紹了JavaScript日期對象(Date)基本用法,結(jié)合實例形式較為詳細的分析了JavaScript日期對象(Date)獲取日期、時間戳、年月日、星期及日期比對等操作技巧,需要的朋友可以參考下
    2017-01-01
  • ionic開發(fā)中點擊input時鍵盤自動彈出

    ionic開發(fā)中點擊input時鍵盤自動彈出

    ionic開發(fā)移動端界面時,在輸入用戶名和密碼的時候,輸入法不要擋住我的輸入框,并且輸入框往上滾動的時候,頂部標題不要上移,下面給大家分享實現(xiàn)代碼,一起看看吧
    2016-12-12
  • 微信小程序?qū)崿F(xiàn)星級評分

    微信小程序?qū)崿F(xiàn)星級評分

    這篇文章主要為大家詳細介紹了微信小程序?qū)崿F(xiàn)星級評分,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • npm qs模塊使用詳解

    npm qs模塊使用詳解

    這篇文章主要介紹了npm qs模塊使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧
    2020-02-02
  • javascript多種數(shù)據(jù)類型表格排序代碼分析

    javascript多種數(shù)據(jù)類型表格排序代碼分析

    這個表格排序代碼,性能比上一次那一個好了很多而且支持很多種類型的排序,這一次寫的能支持更多的排序。
    2010-09-09
  • 你知道該如何捕獲js報錯前的用戶行為嗎

    你知道該如何捕獲js報錯前的用戶行為嗎

    這篇文章主要給大家介紹了該如何捕獲js報錯前的用戶行為的相關(guān)資料,文中通過實例代碼介紹的非常詳細,對大家學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友可以參考下
    2023-06-06
  • ES11屢試不爽的新特性,你用上了幾個

    ES11屢試不爽的新特性,你用上了幾個

    這篇文章主要介紹了ES11屢試不爽的新特性,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧
    2020-10-10
  • JavaScript字符串插入、刪除、替換函數(shù)使用示例

    JavaScript字符串插入、刪除、替換函數(shù)使用示例

    本文為大家介紹下JavaScript字符串的插入、刪除、替換函數(shù)的在實際中的應(yīng)用,想要學(xué)習的朋友可以參考下哈,希望對初學(xué)者有所幫助
    2013-07-07
  • JS正則驗證郵箱的格式詳細介紹

    JS正則驗證郵箱的格式詳細介紹

    這篇文章主要介紹了JS正則驗證郵箱的格式。需要的朋友可以過來參考下,希望對大家有所幫助
    2013-11-11
  • 兼容Firefox的Javascript XSLT 處理XML文件

    兼容Firefox的Javascript XSLT 處理XML文件

    這篇文章主要介紹了兼容Firefox的Javascript XSLT 處理XML文件,需要的朋友可以參考下
    2014-12-12

最新評論

苍梧县| 峨边| 连江县| 武鸣县| 威宁| 玉山县| 三都| 龙海市| 永兴县| 灵宝市| 寿阳县| 桦甸市| 边坝县| 罗源县| 霍林郭勒市| 乌鲁木齐县| 天长市| 玉山县| 虎林市| 锦屏县| 濮阳市| 舒兰市| 梧州市| 洛南县| 湘潭市| 汨罗市| 蕉岭县| 肇东市| 临沂市| 开原市| 额尔古纳市| 沧源| 仪征市| 化州市| 潮州市| 饶平县| 封开县| 仪陇县| 临清市| 安西县| 石楼县|