前臺上傳檔案以及頁面的檔案顯示操作
1、UI佈局:
(1)新增圖片位的div:
<div class="add_remove_file"></div>
(2)檔案顯示的模板佈局(重點):
<!-- 模板放在add_remove_file外面 --> <div class="img_notfirst_div templatel div_display"> <div class="img_group" id=""> <div class="div_icon_left"> <img src="resources/images/teaching-icon-left.png" class="img_icon_left"> </div> <div class="div_file_icon"> <img alt="" class="img_pre_type" src= 'resources/images/pic-word.png'> <a class="icon-img-remove" title="刪除檔案"> <i class="hide_clip">移除</i> </a> </div> <div class="div_icon_right"> <img src="resources/images/teaching-icon-right.png" class="img_icon_right"> </div> </div> <div class="fileimg_txt" id="">飛啊飛啊飛飛到那裡去laallalal</div> </div>
由於畫面上需要移動圖片,在img_group層,id中儲存了檔案的大小,在img中儲存了需要顯示的圖片的路徑,在fileimg_txt層的id中儲存了圖片的src,加上這些資料在後期都需要傳遞給後臺介面或者加以顯示,所以有必要將他們儲存在頁面的相應佈局中,其實沒有這些要求,這種將需要獲取的資料放入頁面div中的做法也是很有必要的,非常穩定且不容易出錯(起碼不會因為某個原因而丟失或者未獲取到)。
另外這裡我將圖片(左移圖片、檔案顯示圖片、右移圖片)放在一層div中,檔案的名稱放在另一個div中,兩層div等寬,檔名稱居中。
2、支援的檔案型別:
專案中圖片和檔案上傳至檔案伺服器,走的是兩個不同的介面。所以檔案型別分為圖片和檔案,以檔案為例說明:
判斷檔案的型別:
判斷檔案的型別有兩個方面的目的:(1)不支援的檔案型別,在呼叫上傳檔案伺服器介面之前進行判斷;(2)支援的檔案型別根據型別採用不同的圖片進行顯示。
<input type="file" id="file_ns_upload" name="upload" onchange="nsUploadFile2(this);" style="display:none;">
function nsUploadFile2(obj) { var $this = $(obj); fileName = $this.val().substr($this.val().lastIndexOf("\\") + 1); var fileLength = $this.val().substring($this.val().lastIndexOf("\\") + 1, $this.val().lastIndexOf(".")); if (fileLength.length > maxLength) { openMsg("檔名不能大於" + maxLength); return; } // 檔案未選擇的場合 if (fileName == '') { return; } picPostfix = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase(); if(isPic(picPostfix)){ uploadPic(obj); }else if(isFileTypeSupport(picPostfix)){ uploadFile(obj); }else{ openMsg("不支援的檔案型別!"); return; } }
點選獲取檔案,因為用了自定義的按鈕,則需要將input隱藏,點選自定義的按鈕讓input的click事件觸發,然後用上述函式去處理選擇的檔案。其中用到了substr和substring兩個方法,注意區別。主要要說明的是(1)獲取到了檔案的字尾名並進行小寫轉換(2)在呼叫介面之前判斷了是否為支援的檔案型別。函式的具體內容如下:
/*判斷是否是支援的檔案型別*/
function isFileTypeSupport(filePostFix){
var allowExtention = ".txt,.pdf,.ppt,.pptx,.xls,.xlsx,.doc,.docx,.mp4,.ogg,.webm"; // 允許上傳檔案的字尾名
// 判斷上傳檔案格式是否符合要求
if (allowExtention.indexOf(filePostFix) <= -1) {
return false;
}else{
return true;
}
}
3、呼叫檔案上傳成功之後檔案在頁面中的顯示以及事件的繫結:
var $item = $('.img_notfirst_div.templatel').clone();
if(picPostfix=="txt"){
$('.img_pre_type', $item).attr('src', 'resources/images/pic-txt.png');
}else if(picPostfix=="pdf"){
$('.img_pre_type', $item).attr('src', 'resources/images/pic-pdf.png');
}else if(picPostfix=="ppt"||picPostfix=="pptx"){
$('.img_pre_type', $item).attr('src', 'resources/images/pic-ppt.png');
}else if(picPostfix=="xls"||picPostfix=="xlsx"){
$('.img_pre_type', $item).attr('src', 'resources/images/pic-excel.png');
}else if(picPostfix=="doc"||picPostfix=="docx"){
$('.img_pre_type', $item).attr('src', 'resources/images/pic-word.png');
}else if(picPostfix=="mp4"||picPostfix=="ogg"||picPostfix=="webm"){
$('.img_pre_type', $item).attr('src', 'resources/images/pic-video.png');
}
$('.fileimg_txt',$item).text(fileName);
$('.fileimg_txt',$item).attr("id",data.url);
$('.img_group',$item).attr("id",data.fileSize);
$('.icon-img-remove',$item).on('click',function(){
$item.remove();
})
$(".div_file_icon, .img_icon_left, .img_icon_right", $item).mouseover(function(){
$('.icon-img-remove',$item).show();
$(".img_icon_left, .img_icon_right", $item).show();
});
$(".div_file_icon, .img_icon_left, .img_icon_right", $item).mouseout(function(){
$('.icon-img-remove',$item).hide();
$(".img_icon_left, .img_icon_right", $item).hide();
});
$(" .img_icon_left", $item).on('click', function() {
tpFileAdjustPre($item);
});
$(" .img_icon_right", $item).on('click', function() {
tpFileAdjustNext($item);
});
$item.removeClass('templatel').appendTo('.add_remove_file').show();
根據不同的型別顯示不同的圖片,並將必要的資料塞進html中的div中儲存,以便之後隨時獲取使用。並且分別對必要的物件繫結mouseover和mouseout事件顯示隱藏刪除和左右移動圖示。
4、左右移動事件:
由於檔案上傳只是新建一條資訊的一部分,但是檔案上傳後又是可以刪除移動的,將檔案的各個資訊儲存在頁面中,到最後點選儲存按鈕時獲取存在的各個檔案的資訊是最簡單也是最不容易出錯的做法。左右移動則包含了相同兩個檔案div中檔案資訊的轉移。以左移為例,具體函式如下:
/*前移*/
function tpFileAdjustPre(selected){
$prev = selected.prev();
if($prev.length>0){
var curSrc = selected.find('.img_group .div_file_icon .img_pre_type').attr('src');
var curId = selected.find('.fileimg_txt').attr('id');
var curName = selected.find('.fileimg_txt').html();
var curFilesize = selected.find('.img_group').attr('id');
var preSrc = $prev.find('.img_group .div_file_icon .img_pre_type').attr('src');
var preId = $prev.find('.fileimg_txt').attr('id');
var preName = $prev.find('.fileimg_txt').html();
var preFilesize = $prev.find('.img_group').attr('id');
$prev.find('.img_group .div_file_icon .img_pre_type').attr('src',curSrc);
$prev.find('.fileimg_txt').attr('id',curId);
$prev.find('.fileimg_txt').text(curName);
$prev.find('.img_group').attr('id',curFilesize);
selected.find('.img_group .div_file_icon .img_pre_type').attr('src',preSrc);
selected.find('.fileimg_txt').attr('id',preId);
selected.find('.fileimg_txt').text(preName);
selected.find('.img_group').attr('id',preFilesize);
}else{
openMsg("你都第一了,不能再前進了!");
}
}
因為檔案佈局都是在一個大的div中,他們之間是兄弟關係,則找尋prev前一個或者next後一個即可找到前面或者後面的檔案佈局,根據父子層級關係和css類可以找到最外層div下的每層div,對相應的資料進行修改。5、效果如下:
但是,至此還有一個問題,就是上傳時因為沒有load,所以當大檔案未完全上傳時,仍然可以點選上傳其他檔案,而得到的結果就是之前的大檔案沒有上傳,出現了兩個相同的後來上傳的檔案。
6、新增遮罩在上傳大檔案時阻止使用者做其他操作。(先這樣保證功能的正確性吧)
在ajax請求之前,呼叫showloading,請求成功之後呼叫hideloading。
<!-- loading遮罩層 -->
<div class="loading loading_back">
</div>
<div class="loading loading_page">
<img alt="" src="resources/images/loading.gif">
</div>
css樣式如下:
.loading_back {
position: absolute;
opacity: 0.4;
width: 100%;
height: 100%;
background: #fff;
z-index: 999999998;
}
.loading_page{
position: absolute;
padding: 8px;
overflow: hidden;
top: 45%;
left: 45%;
z-index: 999999999;
}
.loading{
display: none;
}
//顯隱loading'條方法
function showLoading(){
$(".loading_back").css({ "width": $(document).width(), "height": $(document).height() });
$('.loading').show();
}
function hideLoading(){
$('.loading').hide();
}
效果如下:
雖然效果上不太好,但是功能上沒有大問題了。