在項目安開發中,有一個需求是用戶需上傳特定的text文件,根據此文件判斷設備的狀態。javascript
以上是需求,此時須要在頁面上用到文件上傳的功能,原始的文件上傳樣式很差看,本身此段時間一直都在用layui前端框架寫頁面,本想用layui官網上給的文件上傳功能的,可是經理說上傳的文件不能只顯示文件名,css
還要配上一張圖片。layui上傳文件的模式都是:html
顯然這個版本的文件上傳尚未符合項目的須要。前端
在接下來的對比中,看到了百度富文本編輯器的文件上傳和圖片上傳樣式:
java
由於這個功能是在百度富文本編輯器工具欄中的,想要用這個功能,第一就是須要中上傳文件是在編輯內容的狀況下,配置百度富文本自定義上傳。 第二就是看它的源碼,本身分析把這個功能剝離出來。jquery
無奈裏面的配置信息有點多,只好在網上查看相關的類百度富文本編輯器上傳單獨使用的功能,看到了一篇文章正是講單獨使用百度富文本編輯器文件上傳和圖片上傳的。具體是看誰的博客的我也給忘了,反正是按照Ta說的本身動手試了試還能夠,web
在這裏先簡單說下實現過程:chrome
首先下載百度富文本,下載完解壓後放在本身web項目webapps下面。前端框架
接下來是寫一個簡單的demo.jsp頁面:app
必定要引入相應的ueditor.config.js和ueditor.all.js。
原文上是寫的附件上傳和圖片上傳兩個的,可是用於須要,我只測試了附件上傳,因此這裏的代碼也都是針對附件上傳的。
處理相應的js配置:
js代碼爲:
1 <script type="text/javascript"> 2 3 // 實例化編輯器,這裏注意配置項隱藏編輯器並禁用默認的基礎功能。 4 var uploadEditor = UE.getEditor("uploadEditor", { 5 isShow: false, 6 focus: false, 7 enableAutoSave: false, 8 autoSyncData: false, 9 autoFloatEnabled:false, 10 wordCount: false, 11 sourceEditor: null, 12 scaleEnabled:true, 13 toolbars: [["attachment"]] 14 }); 15 16 // todo::some code 17 18 </script> 19 <script type="text/javascript"> 20 uploadEditor.ready(function () { 21 // 監聽插入附件 22 uploadEditor.addListener("afterUpfile",_afterUpfile); 23 }); 24 25 document.getElementById('j_upload_file_btn').onclick = function () { 26 var dialog = uploadEditor.getDialog("attachment"); 27 dialog.title = '附件上傳'; 28 dialog.render(); 29 dialog.open(); 30 }; 31 32 function _afterUpfile(t, result) { 33 var fileHtml = ''; 34 for(var i in result){ 35 fileHtml = '<li><a href="'+result[i].url+'" target="_blank">'+result[i].url+'</a></li>'; 36 } 37 document.getElementById('upload_file_wrap').innerHTML = fileHtml; 38 } 39 </script>
除了以上操做,還要在ueditor.all.js裏面ctrl + f搜索:me.execCommand('insertHtml', html);
而後在其下面加入一行代碼:me.fireEvent('afterUpfile', filelist);基本上算是完成了。我本身測過了可使用的:
不會上傳動態圖片,只能上傳操做過程:
本身能夠測試一下。
固然了,Ta這個寫的都是多文件上傳的,可是個人須要是上傳一個固定的txt文件,而本身又不想翻來覆去去尋找源碼代碼去改,最後決定本身用layui寫一個類百度富文本上傳附件功能:
百度富文本是點擊一個錨點或者按鈕彈出上傳頁面的,這點對於layui來講不要過輕鬆。
首先頁面要先引入layui.js和layui.css,
而後定義一個打開上傳附件的按鈕,點擊此按鈕彈出上傳的框:
1 <form class="layui-form"> 2 <div class="layui-inline"> 3 <a class="layui-btn layui-btn-primary" id="file_btn">上傳校準文件</a> 4 </div> 5 </form>
在js裏面寫點擊按鈕打開彈窗事件:
$('#file_btn').click(function(){ layer.open({ type: 2, title: '上傳校準文件', maxmin: false, shadeClose: false, //點擊遮罩關閉層 area : ['650px' , '450px'], content: '/log/upload' }); });
content裏面的地址是通過後臺控制層跳轉的頁面,由於我用的是MVC模式,簡單的頁面代碼:
1 <%@ page language="java" contentType="text/html; charset=utf-8" 2 pageEncoding="utf-8"%> 3 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 4 <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> 5 <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> 6 <%@ page trimDirectiveWhitespaces="true"%> 7 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 8 <html> 9 <head> 10 <meta charset="utf-8"> 11 <title>文件上傳</title> 12 <meta name="renderer" content="webkit"> 13 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 14 <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> 15 <meta name="apple-mobile-web-app-status-bar-style" content="black"> 16 <meta name="apple-mobile-web-app-capable" content="yes"> 17 <meta name="format-detection" content="telephone=no"> 18 <link rel="stylesheet" href="${pageContext.request.contextPath}/layui/css/layui.css" media="all" /> 19 <link rel="stylesheet" href="${pageContext.request.contextPath}/css/public.css" media="all" /> 20 <script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-3.2.1.min.js"></script> 21 </head> 22 <body class="childrenBody"> 23 <form class="layui-form"> 24 25 </form> 26 </body> 27 <script type="text/javascript" src="${pageContext.request.contextPath}/layui/layui.js"></script>
點擊上傳校準文件按鈕彈出頁面爲:
而後在這個頁面上添加一個選擇文件的按鈕或者圖片,我用的就是layui官網上給的樣式,看起來仍是能夠的:
1 <form class="layui-form"> 2 <div class="user_left"> 3 <div class="file_upload" style="margin-top:10%;text-align:center;"> 4 <div class="layui-upload-drag" id="test1"> 5 <i class="layui-icon"></i> 6 <p>點擊上傳,或將文件拖拽到此處</p> 7 </div> 8 </div> 9 </div> 10 <div class="layui-form-item" style="text-align:center;margin-top:15%;"> 11 <button type="button" class="layui-btn" id="btn1">肯定</button> 12 <button type="button" class="layui-btn layui-btn-primary" id="btn2">取消</button> 13 </div> 14 </form>
頁面顯示爲:
根據百度富文本附件上傳操做流程,我這邊應該是點擊或者拖拽完文件後這部分隱藏掉,而後天換成相應的文件列表頁面:
1 <form class="layui-form"> 2 <div class="user_left"> 3 <div class="ups" style="display:none;"> 4 <div class="layui-upload" style="margin-left:54%;"> 5 <button type="button" class="layui-btn layui-btn-primary layui-btn-sm" id="test3" style="margin-left:43%;"> 6 <i class="layui-icon"></i>從新選擇 7 </button> 8 <button type="button" class="layui-btn layui-btn-sm layui-btn-normal" id="test2"> 9 <i class="layui-icon"></i>開始上傳 10 </button> 11 </div> 12 <div class="layui-form-item"> 13 <div class="layui-upload"> 14 <div class="imgg"> 15 <p class="titll"></p> 16 </div> 17 </div> 18 </div> 19 </div> 20 <div class="file_upload" style="margin-top:10%;text-align:center;"> 21 <div class="layui-upload-drag" id="test1"> 22 <i class="layui-icon"></i> 23 <p>點擊上傳,或將文件拖拽到此處</p> 24 </div> 25 </div> 26 </div> 27 <div class="layui-form-item" style="text-align:center;margin-top:15%;"> 28 <button type="button" class="layui-btn" id="btn1">肯定</button> 29 <button type="button" class="layui-btn layui-btn-primary" id="btn2">取消</button> 30 </div> 31 </form>
圖片和文件名的樣式爲:
1 /* 上傳文件*/ 2 .imgg{width: 110px;height: 130px;background: url(../images/txt.png) no-repeat center;text-align: center;margin: 9px 0 0 9px; position: relative; 3 display: block;float: left;overflow: hidden;font-size: 12px;} 4 .titll{position: absolute;top: 0;left: 0;width: 100%;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;top: 5px;text-align: center;}
其中的圖片本身去查找選擇。
頁面顯示爲:
可是這樣太難看了,再對比一下百度富文本附件上傳樣式,emm,加個顯示文件個數的,而後加個分割線:
1 <div class="ups" style="display:none;"> 2 <div class="layui-upload" style="margin-left:3%;"> 3 <span>選中<a style="color:red;">1</a>個文件,上傳成功<a id="succ" style="color:green;">0</a>個</span><!-- 顯示上傳文件成功的個數 --> 4 <button type="button" class="layui-btn layui-btn-primary layui-btn-sm" id="test3" style="margin-left:43%;"> 5 <i class="layui-icon"></i>從新選擇 6 </button> 7 <button type="button" class="layui-btn layui-btn-sm layui-btn-normal" id="test2"> 8 <i class="layui-icon"></i>開始上傳 9 </button> 10 </div> 11 <hr class="layui-bg-gray"><!-- 分割線 --> 12 <div class="layui-progress" lay-showPercent="yes" lay-filter="demo" style="display:none;margin-top:3%;"> 13 <div class="layui-progress-bar layui-bg-green" lay-percent="0%"></div> 14 </div> 15 <div class="layui-form-item"> 16 <div class="layui-upload"> 17 <div class="imgg"> 18 <p class="titll"></p> 19 </div> 20 </div> 21 </div> 22 </div>
再看頁面:
注意:這部分代碼應該是隱藏着的,當用戶點擊選擇文件後纔會把點擊選擇文件隱藏這個頁面代碼打開,因此在頭部我設置了css屬性:display:none;
固然,這些操做是用戶選擇文件不上傳,當點擊特定的上傳按鈕時才上傳文件的,因此js代碼爲:
1 layui.use(['upload','form','element'], function(){ 2 var $ = layui.jquery 3 ,upload = layui.upload; 4 var form = layui.form; 5 var element = layui.element; 6 upload.render({ 7 elem: '#test1' 8 ,exts : 'txt|TXT' 9 ,url: '/log/upload' 10 ,accept : 'file' 11 ,multiple: false 12 ,auto: false//不自動上傳 13 ,bindAction: '#test2' 14 ,choose: function(obj){ 15 $('.file_upload').hide(); 16 $('.ups').show(); 17 //讀取本地文件 18 obj.preview(function(index, file, result){ 19 $('.titll').text(file.name); 20 }); 21 } 22 ,done: function(res){//上傳完畢後的回調 23 //console.log(res); 24 25 } 26 }); 27 });
具體使用配置請先看layui官網上給的基礎參數一覽表:http://www.layui.com/doc/modules/upload.html#options
choose:就是選擇文件後的回調函數,選擇完文件以後先不上傳,把選擇文件這部分隱藏掉:$('.file_upload).hide();而後把選擇完文件以後的頁面顯示出來:$('.ups').show();
而後在obj.preview方法中獲取到文件名賦值到titll類中用於顯示文件名。
而後在done中寫上傳完畢以後的事情:簡單說就是把上傳按鈕給禁用了,防止重複上傳,而後顯示上傳成功個數給改變一下:
1 $('#succ').text(1); 2 $('#test2').addClass('layui-btn-disabled');
由於我這這邊只是上傳一個文件的,因此添加的1.
而後想刷新父頁面的刷新就行,根據須要寫。
接下來講下從新上傳事件:
從新上傳就等於剛打開這個彈出層第一次點擊同樣,因此我是這樣寫的:
1 //從新選擇 2 $('#test3').click(function(){ 3 $('#test1').trigger("click"); 4 });
test1就是剛彈出這個頁面點擊選擇文件的模板選擇器。重傳等於說是這個按鈕從新點擊了一次,因此給它加個點擊事件,雖然隱藏了,可是並不影響。
而後再以前操做中上傳成功以後把開始上傳這個按鈕給禁用了防止重複上傳。若是點擊從新上傳的話這個開始上傳按鈕應該也是能夠點擊的。
原本是想加再點擊從新上傳事件裏面,可是考慮到用戶點擊從新上傳但因爲一些緣由並無選擇文件,這樣的話仍是會形成一些沒必要要的bug。
因此把開始上傳按鈕的禁用狀態改掉應該是寫再用戶選擇完文件以後發生的:
1 obj.preview(function(index, file, result){ 2 $('.titll').text(file.name); 3 $('#test2').removeClass('layui-btn-disabled');//移除禁用狀態 4 });
頁面依次爲:上傳完畢後頁面;點擊從新上傳按鈕頁面;點擊從新上傳按鈕選擇完文件後頁面:
至此,大體的基本都算是寫完了,接下來增長個功能進度條!
進度條我用的也是layui官網上給的進度條demo,樣式仍是能夠的,近一段時間對於layui很癡迷。接下來講下實現過程:
首先進度條顯示是在用戶點擊開始上傳以後纔出現的,因此頁面上加上一個進度條(element模板):
1 <div class="layui-progress" lay-showPercent="yes" lay-filter="demo" style="margin-top:3%;"> 2 <div class="layui-progress-bar layui-bg-green" lay-percent="0%"></div> 3 </div>
在分割線下面,看頁面上:
固然,這裏給它設置爲隱藏,在用戶點擊開始上傳時候再顯示出來,讓它從0%一直到100%顯示上傳成功後再次隱藏掉。設置爲隱藏再style裏面加個屬性:display:none;
前面說了,這個進度條顯示是在用戶點擊開始上傳時候纔有的,直到上傳成功結束,因此我把這個事件寫在用戶點擊上傳以後的方法before中:
1 ,before: function(obj){ //obj參數包含的信息,跟 choose回調徹底一致。 2 $('.layui-progress').show();//進度條顯示 3 }
這個方法寫在choose與done中間。這樣的話當用戶點擊開始上傳以後進度條就會顯示出來了。
接下來是實現進度條的loading!
因爲時間緣由我直接用的是layui官網上給的demo,本身改改直接拿過來用,就是使用週期性定時器setInterval:
先貼上代碼:
1 ,before: function(obj){ //obj參數包含的信息,跟 choose回調徹底一致。 2 $('.layui-progress').show();//進度條顯示 3 var n = 0, 4 timer = setInterval(function(){ 5 n = n + Math.random()*1000|0; 6 if(n>80){ 7 n = 80; 8 clearInterval(timer); 9 } 10 element.progress('demo', n+'%'); 11 }, 2000); 12 }
n就是定義的百分百,從0開始的。而後用n = n + Math.random()*1000|0; 獲取進度百分比。一直到n=80也就是進度條到80%的時候清除定時器,用element.progress('demo', n+'%')給進度條賦值。
爲何到80%?由於這短期是上傳的時間,在文件上傳成功以後才返回100%;
在done裏面獲取到返回的狀態,當返回成功時用element.progress('demo', 100+'%');使進度條到100%。
頁面演示爲:開始上傳;上傳過程;上傳成功;上傳成功後:
上面就是全部的實現過程了,若是想實現多文件上傳或者圖片上傳只須要改改其中的一些代碼就能夠了。
特此記一下,之後能夠直接拿來用。