JS圖片上傳預覽插件製作(相容到IE6)

来源:http://www.cnblogs.com/LuckyWinty/archive/2016/08/06/5745100.html
-Advertisement-
Play Games

其實,圖片預覽功能非常地常見。很意外,之前遇到上傳圖片的時候都不需要預覽,也一直沒有去實現過。現在手上的項目又需要有圖片預覽功能,所以就動手做了一個小插件。在此分享一下思路。 一、實現圖片預覽的一些方法。 瞭解了一下,其實方法都是大同小異的。大概有以下幾種方式: ①訂閱input[type=file ...


其實,圖片預覽功能非常地常見。很意外,之前遇到上傳圖片的時候都不需要預覽,也一直沒有去實現過。現在手上的項目又需要有圖片預覽功能,所以就動手做了一個小插件。在此分享一下思路。

一、實現圖片預覽的一些方法。

瞭解了一下,其實方法都是大同小異的。大概有以下幾種方式:

①訂閱input[type=file]元素的onchange事件.

一旦選擇的路徑被改變就把圖片上傳至伺服器,然後就返回圖片在伺服器端的地址,並且賦值到img元素上。

缺點:工作量大,有些上傳並不是用戶最終需要上傳的圖片,但是這種方式會把上傳過程中選擇過的圖片都保存至伺服器端,會造成資源浪費,而且伺服器端清理臨時的那些預覽圖片也需要一定的工作量。

 

②利用HTML5的新特性FileReader

這個對象提供了很多相關的方法,其中最主要用到readAsDataURL這個方法。點我瞭解更多

缺點:通過FileReader的readAsDataURL方法獲取的Data URI Scheme會生成一串很長的base64字元串,若圖片較大那麼字元串則更長,若頁面出現reflow時則會導致性能下降。且瀏覽器支持情況不一致,支持的瀏覽器:FF3.6+,Chrome7+,IE10+。

 

③使用window.URL.createObjectURL代替FileReader,再用DXImageTransform.Microsoft.AlphaImageLoader濾鏡相容IE。

缺點:由於IE11作了安全方面的考慮,使得在input[type=file]元素上通過value、outerHTML和getAttribute的方式都無法獲取用戶所選文件的真實地址,只能獲取到

D:\frontEnd\文件名稱。因此需使用document.selection.createRangeCollection方法來獲取真實地址。

 

二、我的插件製作

我選擇了比較保守的方法,就是第三種使用window.URL.createObjectURL代替FileReader,再用DXImageTransform.Microsoft.AlphaImageLoader濾鏡相容IE的方法啦。

①第一步,HTML的佈局

	<div id="pic">
		<img id="preview" src="../imgs/default.jpeg">
	</div>
	<input type="file" id="uploadBtn" accept="image/*" onchange="setPreviewPic()">

是不是想說so easy?

 

②第二步,插件js封裝。

1、建立對象

我主要採用了組合繼承的方式,封裝了兩個方法,分別是單張圖片上傳和多張圖片上傳。因為無論是單張圖片上傳還是單張圖片上傳,都需要傳入、上傳圖片的input按鈕、img標簽、包裹著img的div、最大的單張照片的值,單位為KB。所以這四個參數在創建上傳圖片對象的時候就要傳入。創建該對象的方法如下:

var SetPreviewPic=function(fileObj,preview,picWrap,maxImgSize){
 	this.fileObj=fileObj;
 	this.preview=preview;
 	this.picWrap=picWrap;
 	this.maxImgSize=maxImgSize;
}

2、定義匹配模式

因為是上傳圖片,除了在input裡面加了accept="image/*",做了初步限制之外,還需要一個js的正則來通過路徑的檢測來判定是否為圖片。所以在prototype上面定義該模式以供兩個方法使用:

SetPreviewPic.prototype.pattern=new RegExp('\.(jpg|png|jpeg)+$','i');

3、定義方法

主要就是判斷是否低於IE11的環境,編寫兩類方案。第一種就是直接通過改變img的src來預覽圖片,第二種就是在低版本的IE下,通過濾鏡來達到預覽效果。

FF、Chrome、IE11以上:(這裡貼出多張圖片預覽的代碼)

	 if(maxPics){	
if(this.fileObj.files && this.fileObj.files[0]){ var imgs=this.picWrap.querySelectorAll('img'); //查找DOM裡面已經有多少張圖片了 var num=imgs.length; var html=this.picWrap.innerHTML; if(Number(num)<Number(maxPics)){ //判斷是否超過最大上傳限度 if(num==1&&(!imgs[0].classList.contains('newLoad'))){ //覆蓋第一張預設圖片 html=''; } if(this.pattern.test(fileObj.files[0].name)){ if(judgeSize(fileObj.files[0].size/1024,this.maxImgSize)){//判斷圖片的大小是否超限 html='<img class="newLoad" style="margin:5px;width:'+width+'px;height:'+height+'px;" src='+window.URL.createObjectURL(this.fileObj.files[0])+' />'+html; this.picWrap.innerHTML=html; }else{ alert('你上傳的圖片太大!'); } }else{ alert('你上傳的好像不是圖片哦,請檢查!'); } }else{ alert('每次最多上傳'+maxPics+'張圖片!'); } }

IE11下利用濾鏡達到效果:

        var nums=this.picWrap.childNodes.length;//因為IE6以下不支持querySelectorAll等方法,就通過childNodes的長度判斷

        if(nums<maxPics+2){//這裡加2是因為本來有一張預設的圖片,而且childNodes讀出來的長度會多1
        	this.fileObj.select();
        	if(document.selection){
        		var imgSrc=document.selection.createRange().text;

        		var image=new Image();        
        		image.src=imgSrc;        
        		filesize=image.fileSize;  
        		if(judgeSize(image.fileSize/1024,this.maxImgSize)){

        //IE下必須設置div的大小
        var ele=document.createElement('div');
        ele.style.width=width+'px';
        ele.style.height=height+'px';
        ele.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale,src='"+imgSrc+"')";

        try{
        	this.picWrap.appendChild(ele);
        }catch(e){
        	alert('你上傳的圖片格式有誤,請重新選擇!');
        	return false;
        }
        this.preview.style.display='none';
        document.selection.empty();
    }else{
    	alert('你上傳的圖片太大!');
    }
}

至此,就完成啦!

 

用法:

<script type="text/javascript" src="../js/singlePic.js"></script>
<script>
    var fileObj=document.getElementById('uploadBtn');
    var preview=document.getElementById('preview');
    var picWrap=document.getElementById('pic');
    fileObj.onchange=function(){
        var obj=new SetPreviewPic(fileObj,preview,picWrap,100);
        //定義上傳圖片對象,參數分別為上傳圖片的input按鈕、img標簽包、裹著img的div、最大的單張照片的值,單位為KB
        obj.uploadSinglePic(200,250);//單張圖片上傳,參數分別為每張的寬度、高度
        // obj.uploadPics(200,250,2);  //多張圖片上傳,參數分別為每張的寬度、高度、最多上傳張數
    }
</script>

 

完成!完整項目請點擊我的github!歡迎關註,給我一個點個start哦!^_^

 

不過,這裡有一個就是其實沒辦法判斷客戶端是否將不是圖片的文件通過修改尾碼名來上傳,只能通過伺服器端來判斷!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.安裝 Erlang,官網:https://www.erlang.org/ 2.安裝RabbitMQ伺服器,rabbitMQ server,官網http://www.rabbitmq.com/ 註:可以根據不同的需要到官網進行相關下載!!! 3.安裝完成之後需要對其進行配置變數: 創建新的系統變數 ...
  • 最近想用C++在windows下實現一個基本的圖像查看器功能,目前只想到了使用GDI或OpenGL兩種方式。由於實在不想用GDI的API了,就用OpenGL的方式實現了一下基本的顯示功能。用GDAL讀取圖像,這樣就能與圖像格式無關。OpenGL的glDrawPixels()函數也能實現圖像顯示,但是... ...
  • 數組的定義: JavaScript 中的數組是一種特殊的對象,用來表示偏移量的索引是該對象的屬性,索引可能是整數。然而,這些數字索引在內部被轉換為字元串類型,這是因為 JavaScript 對象中的屬性名必須是字元串。在內部被歸類為數組。由於 Array 在 JavaScript 中被當作對象,因此 ...
  • 快速排序,又稱劃分交換排序。以分治法為策略實現的快速排序演算法。 本文主要要談的是利用javascript實現in-place思想的快速排序 分治法: 在電腦科學中,分治法是建基於多項分支遞歸的一種很重要的演算法範式。字面上的解釋是“分而治之”,就是把一個複雜的問題分成兩個或更多的相同或相似的子問題, ...
  • 看懂此文,不再困惑於 JS 中的事件設計 今天剛在關註的微信公眾號看到的文章,關於JS事件的,寫的很詳細也很容易理解,相關的知識點都有總結到,看完就有種很舒暢的感覺,該串起來的知識點都串起來了。反正一位元組:爽。 作者:aitangyong 鏈接:blog.csdn.net/aitangyong/ar ...
  • 在學習javascript中,如果在事件的使用上出現一些反差效果,不良效果,如滑鼠的移入移出時,顯示你所需要的內容, 但就是沒有出現,然而你不斷的檢查代碼,逐個代碼查錯,還在瀏覽器的調試工具中調試都沒有發現錯誤,沒有看到你所 想要的錯誤,那麼這個時候你要判斷一下是不是冒泡事件帶來的不良效果了,不過在 ...
  • HTML5 History API提供了一種功能,能讓開發人員在不刷新整個頁面的情況下修改站點的URL。這個功能很有用,例如通過一段JavaScript代碼局部載入頁面的內容,你希望通過改變當前頁面的URL來反應出頁面內容的變化,這時該功能可以派上用場。 舉個例子,當用戶從首頁進入幫助頁面時,我們通 ...
  • 非行間樣式案例 IE獲取非行間樣式 Chrome/FF獲取非行間樣式 我的相容性寫法 我的擴展性寫法 ==註意== 以上只能獲取非行間樣式,不能設置非房間樣式的值。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...