在編寫前臺頁面的時候,有時需要將選中的圖片夾雜着其它信息一塊兒上傳到服務端,在選着本地圖片的時候,爲了得到更好的效果,需要將該圖片顯示在頁面上。javascript
最初思路有兩個。詳細例如如下:java
一、獲取選中文件的二進制數據再傳遞給畫板,畫出圖片來。安全
二、獲取選中文件的傳遞給Img標籤。函數
通過測試,獲得例如如下結果:post
一、Img標籤的src沒法指向本地路徑的文件,這應該是基於安全考慮的結果吧。ui
二、經過File API 讀取的文件二進制數據沒法直接傳遞給Cancav畫板畫出選中圖片,這也許也是基於安全考慮的結果。this
三、通過不懈努力。最終發現了一個解決方法,那就是經過File API的FileReader對象的readAsDataURL將本地圖片建立出一個虛擬URL傳遞給Img標籤的src。orm
具體代碼例如如下:對象
當前項目是基於EasyUi的。如下是頁面的對話框代碼,請關注id="announcePicture"的文件控件,系統要求在該文件控件選擇一個圖片文件時,將其顯示在id="img"的Img標籤中。事件
<div id="announceDlg" class="easyui-dialog" style="width:400px;height:550px;padding:10px 20px" closed="true" buttons="#announceDlg-buttons"> <div class="ftitle">公告信息</div> <form id="fm" method="post" enctype="multipart/form-data"> <div class="fitem"> <label>公告Id:</label> <input id="announceId" name="announceId" class="easyui-textbox" type="text" value=""> </div> <div class="fitem"> <label>標題:</label> <input type="text" id="announceTitle" name="announceTitle" class="easyui-textbox" value="" data-options="required:true"> </div> <div class="fitem"> <label>文件:</label> <input class="easyui-filebox" id="announcePicture" name="announcePicture" value="" style=""> </div> <div class="fitem"> <label>內容:</label> <input type="text" id="announceContent" name="announceContent" class="easyui-textbox" value="" data-options="iconCls:'icon-search',multiline:true,required:true" style="height:120px"> </div> <div class="fitem"> <label></label> <img id="img" style="width:160px;height:160px" /> </div> </form> </div> <div id="announceDlg-buttons"> <a href="javascript:void(0)" class="easyui-linkbutton c6" iconcls="icon-ok" onclick="save()" style="width:90px">Save</a> <a href="javascript:void(0)" class="easyui-linkbutton" iconcls="icon-cancel" onclick="javascript:$('#announceDlg').dialog('close')" style="width:90px">Cancel</a> </div>
如下是對EasyUI進行的拓展,添加了getFile方法。該方法可以獲取當前FileBox對象選中的文件的File對象。
$.extend($.fn.filebox.methods, { getFile: function (myself) { var temp = $(myself).next().children("[type='file']"); var file = document.getElementById(temp.attr("id")); if (file.files.length > 0) { // 若選中一個文件,則返回該文件的File對象 return file.files[0]; } // 若未選中不論什麼文件,則返回null return null; } });
如下是設置FileBox對象的OnChange事件,當選擇一個圖片後。執行當中定義的事件處理函數:
$("#announcePicture").filebox({ onChange: function (event) { // 獲取所選文件的File對象 var file = $(this).filebox("getFile"); if (file != null) { // 建立FileReader對象 var reader = new window.FileReader(); // 定義reader的onload事件 // 當讀完文件信息後觸發onload事件 reader.onload = function (e) { // reader.result保存着產生的虛擬URL $("#img").attr("src", this.result); } // 讀取指定文件並造成URL reader.readAsDataURL(file); } } });
細心的各位必定會發現,在FileBox對象的OnChange事件處理函數內調用getFile時並未傳遞不論什麼闡述。但是在getFile函數中卻有一個myself參數被運用了。要了解這點需要看一下EasyUI中處理FileBox的源碼:
$.fn.filebox = function (_4ed, _4ee) { if (typeof _4ed == "string") { var _4ef = $.fn.filebox.methods[_4ed]; if (_4ef) { return _4ef(this, _4ee); } else { return this.textbox(_4ed, _4ee); } } _4ed = _4ed || {}; return this.each(function () { var _4f0 = $.data(this, "filebox"); if (_4f0) { $.extend(_4f0.options, _4ed); } else { $.data(this, "filebox", { options: $.extend({}, $.fn.filebox.defaults, $.fn.filebox.parseOptions(this), _4ed) }); } _4ea(this); }); };
看到 return _4ef(this, _4ee); 這句語句了嗎?EasyUI在調用指定方法時,默認第一個參數爲當前對象,而實際傳入的參數,則做爲第二個參數來使用。