js實(shí)現(xiàn)純前端的圖片預(yù)覽
圖片上傳是一個(gè)普通不過(guò)的功能,而圖片預(yù)覽就是就是上傳功能中必不可少的子功能了。在這之前,我曾經(jīng)通過(guò)訂閱input[type=file]元素的onchange事件,一旦更改路徑則將圖片上傳至服務(wù)器,接著就獲取圖片路徑并賦值到img元素上。先不管文件異步提交的解決方案,就是服務(wù)端清理那些臨時(shí)的預(yù)覽圖片已經(jīng)增加不少工作量了。
偶然從MDN上找到純前端圖片預(yù)覽的相關(guān)資料,經(jīng)過(guò)整理后記錄下來(lái)以便日后查閱。
一、準(zhǔn)備功夫1──FileReader
FileReader是HTML5的新特性,用于讀取Blob和File類型的數(shù)據(jù)。具體的用法如下:
(1). 構(gòu)造方式
var fr = new FileReader();
(2). 屬性
readyState:類型為unsigned short,F(xiàn)ileReader實(shí)例的當(dāng)前狀態(tài),(EMPTY——0,還沒(méi)有加載任何數(shù)據(jù);LOADING——1,數(shù)據(jù)正在加載;DONE——2,已完成全部的讀取請(qǐng)求),只讀。
result:讀取到的文件內(nèi)容,只讀。
error:類型為DOMError,表示在讀取文件時(shí)發(fā)生的錯(cuò)誤,只讀。
(3). 方法
abort():中止讀取操作,并將readyState設(shè)置為DONE。當(dāng)沒(méi)有執(zhí)行讀取操作時(shí),調(diào)用該方法會(huì)拋DOM_FILE_ABORT_ERR異常。
readAsArrayBuffer(Blob blob):讀取數(shù)據(jù),result屬性被設(shè)置為ArrayBuffer類型
readAsText(Blob blob [, encoding='utf-8']):讀取數(shù)據(jù),result屬性被設(shè)置為String類型
readAsBinaryString(Blob blob):讀取數(shù)據(jù),result屬性被設(shè)置為原始二進(jìn)制數(shù)據(jù)
readAsDataURL(Blob blob):讀取數(shù)據(jù),result屬性被設(shè)置為Data URI Scheme形式(具體請(qǐng)瀏覽《JS魔法堂:Data URI Scheme介紹》)
(4).事件
onload:讀取數(shù)據(jù)成功后觸發(fā)
onerror:讀取數(shù)據(jù)時(shí)拋異常時(shí)觸發(fā)
onloadstart:讀取數(shù)據(jù)前觸發(fā)
onloadend:讀取數(shù)據(jù)后觸發(fā),在onload或onerror后觸發(fā)
onabort:中止讀取后觸發(fā)
onprogress:讀取過(guò)程中周期性觸發(fā)
(5). 瀏覽器支持
FF3.6+,Chrome7+,IE10+
二、準(zhǔn)備功夫2──DXImageTransform.Microsoft.AlphaImageLoader濾鏡
(1). 作用:主要作用是對(duì)圖片進(jìn)行透明處理(IE5.5~6并不支持透明的png)
(2). 樣式中的使用方式
#preview{ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale,src="dummy.png"); }
(3). JS中的使用方式
var preview = document.getElementById('preview'); preview.style.filter = preview.currentStyle.filter + ";progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale,src='dummy.png')"; preview.filters.item("DXImageTransform.Microsoft.AlphaImageLoader").src="dummy1.png";
(4). 屬性
enabled:可選項(xiàng),設(shè)置濾鏡是否激活。值范圍true(默認(rèn)),false
sizingMethod:可選項(xiàng),設(shè)置濾鏡作用的圖片在容器邊界內(nèi)的顯示方式,值范圍crop(剪切圖片以適應(yīng)容器尺寸),image(默認(rèn)值,增大或縮小容器尺寸以適應(yīng)圖片的尺寸),scale(縮放圖片以適應(yīng)容器尺寸)
src:必填項(xiàng),使用絕對(duì)或相對(duì)URL指向背景圖片。當(dāng)URL為用戶計(jì)算機(jī)本地地址時(shí)有效, 而img元素的src為用戶計(jì)算機(jī)本地地址時(shí)會(huì)拋不允許訪問(wèn)本地文件系統(tǒng)的異常。
三、實(shí)現(xiàn)
接下來(lái)我們就利用FileReader的readAsDataURL來(lái)獲取Data URI Scheme來(lái)實(shí)現(xiàn)圖片預(yù)覽的功能,而IE5.5~9我們就使用濾鏡DXImageTransform.Microsoft.AlphaImageLoader來(lái)作降級(jí)處理。
html片斷:
<style type="text/css"> #preview{ width: 100px; height: 100px; } </style> <!--[if lte IE 9]> <style type="text/css"> #preview{ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale); } </style> <![endif]--> <input type="file" onchange="showPreview(this);"/> <div id="preview"> </div>
js片斷:
var preview = function(el){ var pv = document.getElementById("preview"); // IE5.5~9使用濾鏡 if (pv.filters && typeof(pv.filters.item) === 'function'){ pv.filters.item("DXImageTransform.Microsoft.AlphaImageLoader").src = el.value; } else{ // 其他瀏覽器和IE10+(不支持濾鏡)則使用FileReader var fr = new FileReader(); fr.onload = function(evt){ var pvImg = new Image(); pvImg.style.width = pv.offsetWidth + 'px'; pvImg.style.height = pv.offsetHeight + 'px'; pvImg.src = evt.target.result; pv.removeChild(0); pv.appendChild(pvImg); }; fr.readAsDataURL(el.files[0]); } };
四、坑
由于IE11作了安全方面的考慮,使得在input[type=file]元素上通過(guò)value、outerHTML和getAttribute的方式都無(wú)法獲取用戶所選文件的真實(shí)地址,只能獲取到 C:\fakepath\文件名稱 。因此假如使用IE11,但文本模式卻設(shè)置為10以下,那就沒(méi)木有辦法實(shí)現(xiàn)圖片預(yù)覽了。
解決辦法1──在head標(biāo)簽下加入這句: <meta http-equiv="X-UA-Compatible" content="IE=Edge"> 。這樣就可以告訴IE,默認(rèn)使用當(dāng)前IE的最高版本解析、渲染網(wǎng)頁(yè)了。
解決辦法2──采用 document.selection.createRangeColleciton() 獲取真實(shí)地址,具體操作如下:
// 假設(shè)fileEl就是[type=file]元素 fileEl.select(); var filePath = document.selection.createRangeCollection()[0].htmlText;
五、補(bǔ)充:使用window.URL.createObjectURL代替FileReader
通過(guò)FileReader的readAsDataURL方法獲取的Data URI Scheme會(huì)生成一串很長(zhǎng)的base64字符串,若圖片較大那么字符串則更長(zhǎng),若頁(yè)面出現(xiàn)reflow時(shí)則會(huì)導(dǎo)致性能下降。解決方案如下:
1. 預(yù)覽的img標(biāo)簽使用絕對(duì)定位,從而脫離正常文檔流,那么就與文檔的其他元素?zé)o關(guān)了,而reflow時(shí)則不會(huì)影響性能。
2. 采用 window.URL.createObjectURL(Blob blob) 生成數(shù)據(jù)鏈接。
var createObjectURL = function(blob){ return window[window.webkitURL ? 'webkitURL' : 'URL']['createObjectURL'](blob); };
注意: window.URL.createObjectURL 生成的數(shù)據(jù)鏈接是獨(dú)占內(nèi)存的,因此若不時(shí)用時(shí)需要調(diào)用 window.URL.revokeObjectURL(DOMString objUrl) 來(lái)釋放內(nèi)存。在刷新頁(yè)面時(shí),也會(huì)自動(dòng)釋放內(nèi)容。
var resolveObjectURL = function(blob){ window[window.webkitURL ? 'webkitURL' : 'URL']['revokeObjectURL'](blob); };
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助。
- JS使用H5實(shí)現(xiàn)圖片預(yù)覽功能
- 簡(jiǎn)單實(shí)現(xiàn)JS上傳圖片預(yù)覽功能
- javascript圖片預(yù)覽和上傳(兼容IE)
- angularjs點(diǎn)擊圖片放大實(shí)現(xiàn)上傳圖片預(yù)覽
- JS HTML5拖拽上傳圖片預(yù)覽
- 輕松實(shí)現(xiàn)js圖片預(yù)覽功能
- javascript實(shí)現(xiàn)input file上傳圖片預(yù)覽效果
- js實(shí)現(xiàn)上傳圖片預(yù)覽的方法
- 上傳圖片預(yù)覽JS腳本 Input file圖片預(yù)覽的實(shí)現(xiàn)示例
- viewer.js實(shí)現(xiàn)圖片預(yù)覽功能
相關(guān)文章
如何寫一個(gè)通用的JavaScript效果庫(kù)!(2/2)
如何寫一個(gè)通用的JavaScript效果庫(kù)!(2/2)...2007-04-04微信小程序使用scroll-view標(biāo)簽實(shí)現(xiàn)自動(dòng)滑動(dòng)到底部功能的實(shí)例代碼
本文通過(guò)實(shí)例代碼給大家介紹了微信小程序使用scroll-view標(biāo)簽實(shí)現(xiàn)自動(dòng)滑動(dòng)到底部功能,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2018-11-11JS為什么說(shuō)async/await是generator的語(yǔ)法糖詳解
這篇文章主要給大家介紹了關(guān)于JS為什么說(shuō)async/await是generator的語(yǔ)法糖的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用JS具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07js實(shí)現(xiàn)單行文本向上滾動(dòng)效果實(shí)例代碼
這篇文章主要介紹了js實(shí)現(xiàn)單行文本向上滾動(dòng)效果,大家參考使用吧2013-11-11