国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

JavaScript 圖片預覽效果 推薦

2019-11-21 00:53:09
字體:
來源:轉載
供稿:網友
上次寫的簡便無刷新文件上傳系統最初的目的就是用來實現這個圖片預覽效果。
兼容:ie6/7/8, firefox 3.5.5
后臺支持下還兼容:opera 10.10, safari 4.0.4, chrome 3.0

ps:兼容opera, safari和chrome需要后臺支持,請下載實例測試。


程序說明

【基本原理】

圖片預覽主要包括兩個部分:從file表單控件獲取圖像數據,根據數據顯示預覽圖像。
程序的file和img屬性就是用來保存file控件和顯示預覽圖像的容器的,而img還必須是img元素。

程序有以下幾種預覽方式:
simple模式:直接從file的value獲取圖片路徑來顯示預覽,適用于ie6;
filter模式:通過selection獲取file的圖片路徑,再用濾鏡來顯示預覽,適用于ie7/8;
domfile模式:調用file的getAsDataURL方法獲取Data URI數據來顯示預覽,適用于ff3;
remote模式:最后的辦法,把file提交后臺處理后返回圖片數據來顯示預覽,全適用。

程序定義時就自動根據瀏覽器設置MODE屬性:

ImagePreview.MODE = $$B.ie7 || $$B.ie8 ? "filter" :
    $$B.firefox 
? "domfile" :
    $$B.opera 
|| $$B.chrome || $$B.safari ? "remote" : "simple";


如果用能力檢測會比較麻煩,所以只用了瀏覽器檢測。
由于瀏覽器對應的默認模式是不會變的,這個值直接會保存到函數屬性中作為公用屬性。
ps:ie6也可以用filter模式,不過它有更好的simple模式。


【獲取數據】

調用preview方法,就會執行預覽程序:

if ( this.file && false !== this.onCheck() ) {
    
this._preview( this._getData() );
}


在通過檢測后,再調用_getData獲取數據,并作為_preview的參數進入預覽下一步。

程序初始化時就會根據mode來設置_getData數據獲取程序:
this._getData = this._getDataFun(opt.mode);

mode的默認值是ImagePreview.MODE,也可以在可選參數中自定義。
由于兼容性問題,一般應保留默認值,除非是使用全兼容的remote模式。

在_getDataFun里面,根據mode返回數據獲取程序:

代碼
switch (mode) {
    
case "filter" :
        
return this._filterData;
    
case "domfile" :
        
return this._domfileData;
    
case "remote" :
        
return this._remoteData;
    
case "simple" :
    
default :
        
return this._simpleData;
}


不同的模式有不同的數據獲取程序:
濾鏡數據獲取程序:

this.file.select();
try{
    
return document.selection.createRange().text;
finally { document.selection.empty(); }

一般用在ie7/8,在file控件select后再用selection對象獲得文件本地路徑。
此時file控件不能隱藏,否則不能被select,不過一般能選擇文件就肯定能被select了。
確實要隱藏也可以在獲取數據之后再隱藏。

domfile數據獲取程序:

return this.file.files[0].getAsDataURL();

用getAsDataURL從file控件獲取數據,這個方法暫時只有ff3支持。

遠程數據獲取程序:

this._setUpload();
this._upload && this._upload.upload();

用_upload上傳文件對象把數據提交后臺,根據返回的數據再顯示。
這個方法不屬于本地預覽,是沒有辦法中的辦法。

一般數據獲取程序:

return this.file.value;

最原始的方法,現在只有ie6還支持從file的value直接獲取本地路徑。

獲取的數據作為參數,在_preview預覽程序中進行預覽:

if ( !!data && data !== this._data ) {
    
this._data = data; this._show();
}


首先排除空值或相同值的情況,再執行_show預覽顯示程序,其中_data屬性用來保存當前的圖片數據。
圖片使用Data URI數據時可能會設置一個很大的src值,在ie8獲取很大的src值會出現“無效指針”的錯誤。
使用_data屬性保存這個值可以避免從src獲取值而觸發這個錯誤。

遠程數據獲取程序沒有返回值,因為它需要等待返回數據,在_preview中會自動排除。


【顯示預覽】

程序初始化時就會根據mode來設置_show預覽顯示程序:

this._show = opt.mode !== "filter" ? this._simpleShow : this._filterShow;


除了filter模式,都是使用_simpleShow顯示程序來顯示預覽圖片的。
里面會先調用_simplePreload方法設置一般預載圖片對象:

var preload = this._preload = new Image(), oThis = this;
preload.onload 
= function(){ oThis._imgShow( oThis._data, this.width, this.height ); };
preload.onerror 
= function(){ oThis._error(); };


預載圖片對象保存在_preload屬性中,主要用來判斷圖像能否加載成功并獲取圖片原始尺寸。
要實現這些功能只要用Image對象就足夠了。
在onload中執行_imgShow顯示預覽,在onerror中進行出錯處理。
ps:ff、chrome和safari的圖片對象還有naturalHeight和naturalWidth屬性可以獲取圖片的原始尺寸。

然后設置_preload的src預載圖片,如果成功預載就會執行_imgShow顯示預覽。
要注意src的設置要在onload/onerror的設置之后,否則設置之前就加載完成的話就觸發不了事件了。

_imgShow需要三個參數,包括要預覽圖片的src值,圖片原始寬度和圖片原始高度。
在_imgShow里面首先設置預覽圖片的尺寸:

代碼
var img = this.img, style = img.style,
    ratio 
= Math.max( 0this.ratio ) || Math.min( 1,
            Math.max( 
0this.maxWidth ) / width  || 1,
            Math.max( 
0this.maxHeight ) / height || 1
        );

style.width 
= Math.round( width * ratio ) + "px";
style.height 
= Math.round( height * ratio ) + "px";


這里的關鍵是獲取ratio比例值,如果自定義的ratio大于0就直接使用自定義的比例,否則就根據參數自動計算。
自動計算首先要確保maxWidth最大寬度和maxHeight最大高度大于等于0。
然后分別跟原始寬高做“/”運算得到比例,如果比例為0表示不限制,那么比例就自動改為1。
最后取比較小的比例來計算,程序設定了比例最大值為1,這樣就不會自動放大圖片了。
當然比例的計算可以根據需要自行修改。
ps:style的優先級比屬性(width/height)高,所以要用style設置。

最后設置img的src就實現預覽了。


【remote模式】

remote模式會先提交file控件到后臺,通過返回圖片數據來顯示圖片。
它跟其他模式最大的區別就是獲取數據的部分。

在_remoteData遠程數據獲取程序中,會調用_setUpload來設置上傳文件對象。
如果設置了action,并存在QuickUpload函數,就會進行實例化一個上傳文件對象保存到_upload中:

代碼
var oThis = this;
this._upload = new QuickUpload(this.file, {
    onReady: 
function(){
        
this.action = oThis.action; this.timeout = oThis.timeout;
        
var parameter = this.parameter;
        parameter.ratio 
= oThis.ratio;
        parameter.width 
= oThis.maxWidth;
        parameter.height 
= oThis.maxHeight;
    },
    onFinish: 
function(iframe){
        
try{
            oThis._preview( iframe.contentWindow.document.body.innerHTML );
        }
catch(e){ oThis._error("remote error"); }
    },
    onTimeout: 
function(){ oThis._error("timeout error"); }
});


這里使用的QuickUpload就是簡便無刷新文件上傳程序
在onReady中設置參數,在onFinish中處理返回數據,onTimeout進行出錯處理。
返回的數據可以是圖片的地址或對應Data URI數據,然后給_preview處理。
當然針對不同的后臺輸出,數據處理的方式也不同,可以按照需要修改。

后臺最好先根據傳遞的參數縮小圖片,盡量減少返回數據來提高預覽速度。


【filter模式】

filter模式在_filterData程序中得到文件本地路徑,但ie7/8都不允許直接使用本地路徑顯示圖片。
不過還是可以通過濾鏡,用本地路徑來做預覽圖片效果。

filter模式使用_filterShow方法來顯示預覽圖片。
里面先調用_filterPreload方法來設置濾鏡預載圖片對象。
跟一般預載圖片對象不同,濾鏡預載對象是用濾鏡來顯示圖片,所以并不一定要圖像元素。
程序就使用了div元素作為濾鏡預載對象:

代碼
var preload = this._preload = document.createElement("div");

$$D.setStyle( preload, {
    width: 
"1px", height: "1px",
    visibility: 
"hidden", position: "absolute", left: "-9999px", top: "-9999px",
    filter: 
"progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='image')"
});

var body = document.body; body.insertBefore( preload, body.childNodes[0] );


在樣式設置中隱藏元素并添加濾鏡,要使濾鏡生效width和height必須設置一個值。
由于要獲取尺寸,只能用visibility來隱藏并插入body,關于AlphaImageLoader濾鏡后面再介紹。

然后在_filterShow中預載圖片: 

try{
    preload.filters.item(
"DXImageTransform.Microsoft.AlphaImageLoader").src = data;
}
catch(e){ this._error("filter error"); return; }


成功的話,再給img載入圖片:

this.img.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='scale',src='" + data + "')";


最后調用_imgShow設置尺寸:

this._imgShow( ImagePreview.TRANSPARENT, preload.offsetWidth, preload.offsetHeight );


由于img是一個圖片對象,默認會顯示一個小圖標,為了去掉這個小圖標,可以讓它顯示一個透明圖片。
程序傳遞了ImagePreview.TRANSPARENT來設置透明圖片,具體數據在Data URI 和 MHTML再說明。
ps:當然也可以在filter模式用div做預覽圖片對象就沒有小圖標了,但這樣兼容起來會麻煩很多。


【AlphaImageLoader濾鏡】

filter模式使用的是AlphaImageLoader濾鏡。
它的作用是在對象容器邊界內,在對象的背景和內容之間顯示一張圖片。
如果載入的是png圖片,其透明度會被支持,可以用來解決png的兼容問題。
詳細參考msdn的AlphaImageLoader Filter和“Microsoft.AlphaImageLoader濾鏡講解”。
它包括三個屬性:enabled(濾鏡是否激活),sizingMethod(圖像顯示方式)和src(圖像路徑)。
程序主要使用后面兩個屬性。

sizingMethod有三種方式:
crop:剪切圖片以適應對象尺寸;
image:默認值。增大或減小對象的尺寸邊界以適應圖片的尺寸;
scale:縮放圖片以適應對象的尺寸邊界。

對于預載圖片對象_preload,要獲取圖片的原始尺寸,所以要用image方式。
而預覽圖片對象img,則要根據設定尺寸顯示圖片,所以要用scale方式。

而src屬性的路徑還支持本地路徑,是實現filter模式的關鍵所在。
幸運的是濾鏡并沒有像file控件那樣提高安全性,否則就沒辦法實現圖片本地預覽了。


【nsIDOMFile接口】

ff從3.0(或更早)開始,就不能通過value獲取file的完整路徑,也不支持直接用本地路徑顯示圖片。
不過欣喜的是,它同時也提供了nsIDOMFile接口,能更好地獲取文件數據。
在ff的file控件有一個FileList對象,包含了帶nsIDOMFile接口的File對象。
ps:FileList對象貌似是一個NodeList對象,但目前只能用第一個,可能是為了將來實現一個file控件選擇多個文件的功能預留的。

這個File對象有三個獲取文件數據的方法:
getAsText:獲取文件的文本數據,可以通過參數設置編碼;
getAsDataURL:獲取文件的Data URI數據;
getAsBinary:獲取文件的二進制數據。
其中getAsDataURL獲得的Data URI數據可以用于顯示圖片,_domfileData中就是用它來獲取數據的。

File對象還有支持兩個屬性:fileName(文件名,不包括路徑)和fileSize(文件大小)。
相關具體說明參考mozilla的FilensIDOMFile


【Data URI 和 MHTML】

上面已經多次提到Data URI,詳細介紹請看秦歌的“Data URI 和 MHTML”。
Data URI的主要作用是以字符代替數據,從而把文件“嵌”在代碼里。
除了ie,其他瀏覽器基本都很好的支持了Data URI。
ie8也有限度地支持,詳細參考msdn的data Protocol

由于opera,safari和chrome需要remote模式的瀏覽器都支持Data URI,所以程序返回的是Data URI形式的數據。
相比返回路徑的方法,返回Data URI不需要創建文件,還少一次HTTP請求。
ps:ie8只支持32k的Data URI數據,在ie8使用時要注意數據大小。

在filter模式需要一個透明圖片來去掉img默認顯示的小圖標,一般的方法需要一個圖片文件。
為了“省下”這個文件,可以使用Data URI來做一個1*1的透明圖片:

data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==

支持Data URI的情況下,只要把img的src設置為這個值就可以顯示一個透明圖片了。

雖然ie6/7不支持Data URI,還可以用mhtml來代替。
在ImagePreviewd.js開頭有一段注釋了的代碼:

代碼
Content-Type: multipart/related; boundary="_CLOUDGAMER"

--_CLOUDGAMER
Content
-Location:blankImage
Content
-Transfer-Encoding:base64

R0lGODlhAQABAJEAAAAAAP
///////wAAACH5BAEAAAIALAAAAAABAAEAAAICVAEAOw==


這是mhtml記錄數據的形式,調用時要按以下格式設置img的src:
mhtml:文件完整路徑!blankImage

其中blankImage表示要獲取的數據在文件對應的Content-Location。
問題在于如何獲得script(js文件)的完整路徑(包含http開頭的路徑)。
首先要在腳本運行時獲取,當前運行的script肯定是document.scripts的最后一個:
document.scripts[document.scripts.length - 1]
ps:document.scripts詳細參考msdn的scripts Collection,ff不支持,可以用getElementsByTagName("script")兼容。
接著可以利用getAttribute從src獲取script的完整路徑:

document.scripts[document.scripts.length - 1].getAttribute("src"4)


ie6/7的getAttribute支持第二個參數,設為4表示返回完整路徑的url地址,詳細參考msdn的getAttribute Method

結合Data URI 和 MHTML可以這樣得到透明圖片數據: 

ImagePreview.TRANSPARENT = $$B.ie7 || $$B.ie6 ?
    
"mhtml:" + document.scripts[document.scripts.length - 1].getAttribute("src"4+ "!blankImage" :
    
"data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";


使用時要注意:
腳本必須單獨另存為一個文件,作為mhtml需要的文件路徑。
要自動獲取完整路徑需要用script標簽鏈接文件。


【超空間】

程序還有一個dispose方法用于銷毀程序。
包括這幾個部分:
_upload上傳文件對象:它本身已經有一個dispose方法來銷毀程序;
_preload預載圖片對象:先清除它的onload/onerror事件再移除元素;
file和img屬性:直接設為null,由于不是程序創建的元素,留給使用者來移除。

說到移除元素,順便說一下超空間(DOM hyperspace),這是從“ppk談javascript”中看到的。
大概指的是當元素不在dom里面,而js又有關聯時,元素并不會消失,而是保存在一個稱為“超空間”的地方。
詳細參考書的DOM 超空間部分。
書中還說可以根據是否有parentNode來判斷元素是否在超空間,但測試以下代碼:

<body></body>
<script>
var elm = document.createElement("div");
alert(elm.parentNode);
document.body.removeChild(document.body.appendChild(elm));
alert(elm.parentNode);
</script>


第一次parentNode都是null,沒有問題,按理第二次也應該是null,但ie卻是一個object。
經測試,這個object的nodeType是11,也就是一個碎片對象(FRAGMENT)。
而且各個被removeChild移除的元素的parentNode都不相同,即會生成不同的碎片對象。
這種情況算不算在“超空間”呢,不過書中也只是說“一般來說”,也不用太考究。

那么用innerHTML清除呢?再測試以下代碼:

<body><div id="test"></div></body>
<script>
var elm = document.getElementById("test");
document.body.innerHTML 
= "";
alert(elm.parentNode);
</script>


結果在ie也是null了,看來removeChild和innerHTML在清除元素時產生了不同的結果。

那個碎片對象貌似沒什么用(難道為了保證有parentNode?),那是不是innerHTML就一定比removeChild好呢?
再測試以下代碼:

代碼
<body>
<style>div{border:1px solid #000; height:20px;}</style>
<span><div id="test1">test1</div></span>
<span><div id="test2">test2</div></span>
</body>
<script>
var div1 = document.getElementById("test1"), parent1 = div1.parentNode;
parent1.removeChild(div1);
alert(div1.tagName 
+ ":" + div1.innerHTML);
parent1.appendChild(div1);

var div2 = document.getElementById("test2"), parent2 = div2.parentNode;
parent2.innerHTML 
= "";
alert(div2.tagName 
+ ":" + div2.innerHTML);
parent2.appendChild(div2);
</script>


當使用removeChild時,移除元素的結構并沒有發生變化,各個瀏覽器的效果都一樣。
而使用innerHTML清除時,其他瀏覽器的效果跟removeChild一樣,但在ie被移除的元素就只剩下一個“外殼”了。

個人推測,ie在使用innerHTML時,被移除的元素會變成一個個單獨的元素,失去了彼此的聯系。
形象點說就是removeChild是直接掰斷樹枝,還能繼續嫁接使用,而innerHTML是把需要的樹葉節點取下來,再把樹枝燒掉。
ps:僅僅是推測,誰有官方資料請告訴我。

那么removeChild的好處是移除的元素能再次使用,兼容性好,不好的地方是ie會產生一個沒用的碎片對象。
而innerHTML的好處是不會產生多余的碎片對象,方便高效,但在ie被移除的元素基本不能再用,有兼容性問題。
那就可以根據需要使用不同的方法了,至于防止內存泄漏用那個好,感覺是innerHTML,但沒有更深入研究的話還說不清楚。


使用技巧

一般來preview方法都是在onchange中調用,即選擇文件后立即顯示預覽。

在不需要程序時最好執行一次dispose方法來銷毀程序,防止內存泄漏等。

利用ImagePreview.TRANSPARENT可以顯示透明圖片,而不需另外隱藏或增加文件。

第二個實例中的ResetFile是用來重置file控件的,詳細參考這里file的reset
而file控件樣式設置詳細參考這里的file樣式

asp版本使用Persits.Jpeg組件縮放圖片,測試請先安裝該組件。


使用說明

實例化時,有兩個必要參數,分別是file控件對象和img元素的預覽顯示對象:

new ImagePreview( file, img );


可選參數用來設置系統的默認屬性,包括:
屬性:    默認值//說明
mode:  ImagePreview.MODE,//預覽模式
ratio:  0,//自定義比例
maxWidth: 0,//縮略圖寬度
maxHeight: 0,//縮略圖高度
onCheck: function(){},//預覽檢測時執行
onShow:  function(){},//預覽圖片時執行
onErr:  function(){},//預覽錯誤時執行
以下在remote模式時有效
action:  undefined,//設置action
timeout: 0//設置超時(0為不設置)
如果要使用remote模式必須設置一個action。

還提供了以下方法:
preview:執行預覽操作;
dispose:銷毀程序。


程序源碼

代碼
var ImagePreview = function(file, img, options) {

    
this.file = $$(file);//文件對象
    this.img = $$(img);//預覽圖片對象
    
    
this._preload = null;//預載圖片對象
    this._data = "";//圖像數據
    this._upload = null;//remote模式使用的上傳文件對象
    
    
var opt = this._setOptions(options);

    
this.action = opt.action;
    
= opt.action;
    
this.timeout = opt.timeout;
    
this.ratio = opt.ratio;
    
this.maxWidth = opt.maxWidth;
    
this.maxHeight = opt.maxHeight;

    
this.onCheck = opt.onCheck;
    
this.onShow = opt.onShow;
    
this.onErr = opt.onErr;

    
//設置數據獲取程序
    this._getData = this._getDataFun(opt.mode);
    
//設置預覽顯示程序
    this._show = opt.mode !== "filter" ? this._simpleShow : this._filterShow;
};
//根據瀏覽器獲取模式
ImagePreview.MODE = $$B.ie7 || $$B.ie8 ? "filter" :
    $$B.firefox 
? "domfile" :
    $$B.opera 
|| $$B.chrome || $$B.safari ? "remote" : "simple";
//透明圖片
ImagePreview.TRANSPARENT = $$B.ie7 || $$B.ie6 ?
    
"mhtml:" + document.scripts[document.scripts.length - 1].getAttribute("src"4+ "!blankImage" :
    
"data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";

ImagePreview.prototype 
= {
  
//設置默認屬性
  _setOptions: function(options) {
    
this.options = {//默認值
        mode:        ImagePreview.MODE,//預覽模式
        ratio:        0,//自定義比例
        maxWidth:    0,//縮略圖寬度
        maxHeight:    0,//縮略圖高度
        onCheck:    function(){},//預覽檢測時執行
        onShow:        function(){},//預覽圖片時執行
        onErr:        function(){},//預覽錯誤時執行
        //以下在remote模式時有效
        action:        undefined,//設置action
        timeout:    0//設置超時(0為不設置)
    };
    
return $$.extend(this.options, options || {});
  },
  
//開始預覽
  preview: function() {
    
if ( this.file && false !== this.onCheck() ) {
        
this._preview( this._getData() );
    }
  },

  
//根據mode返回數據獲取程序
  _getDataFun: function(mode) {
    
switch (mode) {
        
case "filter" :
            
return this._filterData;
        
case "domfile" :
            
return this._domfileData;
        
case "remote" :
            
return this._remoteData;
        
case "simple" :
        
default :
            
return this._simpleData;
    }
  },
  
//濾鏡數據獲取程序
  _filterData: function() {
    
this.file.select();
    
try{
        
return document.selection.createRange().text;
    } 
finally { document.selection.empty(); }
  },
  
//domfile數據獲取程序
  _domfileData: function() {
    
return this.file.files[0].getAsDataURL();
  },
  
//遠程數據獲取程序
  _remoteData: function() {
    
this._setUpload();
    
this._upload && this._upload.upload();
  },
  
//一般數據獲取程序
  _simpleData: function() {
    
return this.file.value;
  },

  
//設置remote模式的上傳文件對象
  _setUpload: function() {
    
if ( !this._upload && this.action !== undefined && typeof QuickUpload === "function" ) {
        
var oThis = this;
        
this._upload = new QuickUpload(this.file, {
            onReady: 
function(){
                
this.action = oThis.action; this.timeout = oThis.timeout;
                
var parameter = this.parameter;
                parameter.ratio 
= oThis.ratio;
                parameter.width 
= oThis.maxWidth;
                parameter.height 
= oThis.maxHeight;
            },
            onFinish: 
function(iframe){
                
try{
                    oThis._preview( iframe.contentWindow.document.body.innerHTML );
                }
catch(e){ oThis._error("remote error"); }
            },
            onTimeout: 
function(){ oThis._error("timeout error"); }
        });
    }
  },

  
//預覽程序
  _preview: function(data) {
    
//空值或相同的值不執行顯示
    if ( !!data && data !== this._data ) {
        
this._data = data; this._show();
    }
  },

  
//設置一般預載圖片對象
  _simplePreload: function() {
    
if ( !this._preload ) {
        
var preload = this._preload = new Image(), oThis = this;
        preload.onload 
= function(){ oThis._imgShow( oThis._data, this.width, this.height ); };
        preload.onerror 
= function(){ oThis._error(); };
    }
  },
  
//一般顯示
  _simpleShow: function() {
    
this._simplePreload();
    
this._preload.src = this._data;
  },

  
//設置濾鏡預載圖片對象
  _filterPreload: function() {
    
if ( !this._preload ) {
        
var preload = this._preload = document.createElement("div");
        
//隱藏并設置濾鏡
        $$D.setStyle( preload, {
            width: 
"1px", height: "1px",
            visibility: 
"hidden", position: "absolute", left: "-9999px", top: "-9999px",
            filter: 
"progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='image')"
        });
        
//插入body
        var body = document.body; body.insertBefore( preload, body.childNodes[0] );
    }
  },
  
//濾鏡顯示
  _filterShow: function() {
    
this._filterPreload();
    
var preload = this._preload, data = this._data;
    
try{
        preload.filters.item(
"DXImageTransform.Microsoft.AlphaImageLoader").src = data;
    }
catch(e){ this._error("filter error"); return; }
    
//設置濾鏡并顯示
    this.img.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='scale',src='" + data + "')";
    
this._imgShow( ImagePreview.TRANSPARENT, preload.offsetWidth, preload.offsetHeight );
  },

  
//顯示預覽
  _imgShow: function(src, width, height) {
    
var img = this.img, style = img.style,
        ratio 
= Math.max( 0this.ratio ) || Math.min( 1,
                Math.max( 
0this.maxWidth ) / width  || 1,
                Math.max( 
0this.maxHeight ) / height || 1
            );
    
//設置預覽尺寸
    style.width = Math.round( width * ratio ) + "px";
    style.height 
= Math.round( height * ratio ) + "px";
    
//設置src
    img.src = src;
    
this.onShow();
  },

  
//銷毀程序
  dispose: function() {
    
//銷毀上傳文件對象
    if ( this._upload ) {
        
this._upload.dispose(); this._upload = null;
    }
    
//銷毀預載圖片對象
    if ( this._preload ) {
        
var preload = this._preload, parent = preload.parentNode;
        
this._preload = preload.onload = preload.onerror = null;
        parent 
&& parent.removeChild(preload);
    }
    
//銷毀相關對象
    this.file = this.img = null;
  },
  
//出錯
  _error: function(err) {
    
this.onErr(err);
  }
}
完整實例下載(asp與asp.net)
SPAN style="COLOR: rgb(0,0,255)">this
.timeout = opt.timeout;
    
this.ratio = opt.ratio;
    
this.maxWidth = opt.maxWidth;
    
this.maxHeight = opt.maxHeight;

    
this.onCheck = opt.onCheck;
    
this.onShow = opt.onShow;
    
this.onErr = opt.onErr;

    
//設置數據獲取程序
    this._getData = this._getDataFun(opt.mode);
    
//設置預覽顯示程序
    this._show = opt.mode !== "filter" ? this._simpleShow : this._filterShow;
};
//根據瀏覽器獲取模式
ImagePreview.MODE = $$B.ie7 || $$B.ie8 ? "filter" :
    $$B.firefox 
? "domfile" :
    $$B.opera 
|| $$B.chrome || $$B.safari ? "remote" : "simple";
//透明圖片
ImagePreview.TRANSPARENT = $$B.ie7 || $$B.ie6 ?
    
"mhtml:" + document.scripts[document.scripts.length - 1].getAttribute("src"4+ "!blankImage" :
    
"data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";

ImagePreview.prototype 
= {
  
//設置默認屬性
  _setOptions: function(options) {
    
this.options = {//默認值
        mode:        ImagePreview.MODE,//預覽模式
        ratio:        0,//自定義比例
        maxWidth:    0,//縮略圖寬度
        maxHeight:    0,//縮略圖高度
        onCheck:    function(){},//預覽檢測時執行
        onShow:        function(){},//預覽圖片時執行
        onErr:        function(){},//預覽錯誤時執行
        //以下在remote模式時有效
        action:        undefined,//設置action
        timeout:    0//設置超時(0為不設置)
    };
    
return $$.extend(this.options, options || {});
  },
  
//開始預覽
  preview: function() {
    
if ( this.file && false !== this.onCheck() ) {
        
this._preview( this._getData() );
    }
  },

  
//根據mode返回數據獲取程序
  _getDataFun: function(mode) {
    
switch (mode) {
        
case "filter" :
            
return this._filterData;
        
case "domfile" :
            
return this._domfileData;
        
case "remote" :
            
return this._remoteData;
        
case "simple" :
        
default :
            
return this._simpleData;
    }
  },
  
//濾鏡數據獲取程序
  _filterData: function() {
    
this.file.select();
    
try{
        
return document.selection.createRange().text;
    } 
finally { document.selection.empty(); }
  },
  
//domfile數據獲取程序
  _domfileData: function() {
    
return this.file.files[0].getAsDataURL();
  },
  
//遠程數據獲取程序
  _remoteData: function() {
    
this._setUpload();
    
this._upload && this._upload.upload();
  },
  
//一般數據獲取程序
  _simpleData: function() {
    
return this.file.value;
  },

  
//設置remote模式的上傳文件對象
  _setUpload: function() {
    
if ( !this._upload && this.action !== undefined && typeof QuickUpload === "function" ) {
        
var oThis = this;
        
this._upload = new QuickUpload(this.file, {
            onReady: 
function(){
                
this.action = oThis.action; this.timeout = oThis.timeout;
                
var parameter = this.parameter;
                parameter.ratio 
= oThis.ratio;
                parameter.width 
= oThis.maxWidth;
                parameter.height 
= oThis.maxHeight;
            },
            onFinish: 
function(iframe){
                
try{
                    oThis._preview( iframe.contentWindow.document.body.innerHTML );
                }
catch(e){ oThis._error("remote error"); }
            },
            onTimeout: 
function(){ oThis._error("timeout error"); }
        });
    }
  },

  
//預覽程序
  _preview: function(data) {
    
//空值或相同的值不執行顯示
    if ( !!data && data !== this._data ) {
        
this._data = data; this._show();
    }
  },

  
//設置一般預載圖片對象
  _simplePreload: function() {
    
if ( !this._preload ) {
        
var preload = this._preload = new Image(), oThis = this;
        preload.onload 
= function(){ oThis._imgShow( oThis._data, this.width, this.height ); };
        preload.onerror 
= function(){ oThis._error(); };
    }
  },
  
//一般顯示
  _simpleShow: function() {
    
this._simplePreload();
    
this._preload.src = this._data;
  },

  
//設置濾鏡預載圖片對象
  _filterPreload: function() {
    
if ( !this._preload ) {
        
var preload = this._preload = document.createElement("div");
        
//隱藏并設置濾鏡
        $$D.setStyle( preload, {
            width: 
"1px", height: "1px",
            visibility: 
"hidden", position: "absolute", left: "-9999px", top: "-9999px",
            filter: 
"progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='image')"
        });
        
//插入body
        var body = document.body; body.insertBefore( preload, body.childNodes[0] );
    }
  },
  
//濾鏡顯示
  _filterShow: function() {
    
this._filterPreload();
    
var preload = this._preload, data = this._data;
    
try{
        preload.filters.item(
"DXImageTransform.Microsoft.AlphaImageLoader").src = data;
    }
catch(e){ this._error("filter error"); return; }
    
//設置濾鏡并顯示
    this.img.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='scale',src='" + data + "')";
    
this._imgShow( ImagePreview.TRANSPARENT, preload.offsetWidth, preload.offsetHeight );
  },

  
//顯示預覽
  _imgShow: function(src, width, height) {
    
var img = this.img, style = img.style,
        ratio 
= Math.max( 0this.ratio ) || Math.min( 1,
                Math.max( 
0this.maxWidth ) / width  || 1,
                Math.max( 
0this.maxHeight ) / height || 1
            );
    
//設置預覽尺寸
    style.width = Math.round( width * ratio ) + "px";
    style.height 
= Math.round( height * ratio ) + "px";
    
//設置src
    img.src = src;
    
this.onShow();
  },

  
//銷毀程序
  dispose: function() {
    
//銷毀上傳文件對象
    if ( this._upload ) {
        
this._upload.dispose(); this._upload = null;
    }
    
//銷毀預載圖片對象
    if ( this._preload ) {
        
var preload = this._preload, parent = preload.parentNode;
        
this._preload = preload.onload = preload.onerror = null;
        parent 
&& parent.removeChild(preload);
    }
    
//銷毀相關對象
    this.file = this.img = null;
  },
  
//出錯
  _error: function(err) {
    
this.onErr(err);
  }
}
完整實例下載(asp與asp.net)
上一篇:JavaScript是否可實現多線程 深入理解JavaScript定時機制

下一篇:javascript 年月日聯動實現核心代碼

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片
猜你喜歡的新聞
猜你喜歡的關注

新聞熱點

疑難解答

圖片精選

網友關注

主站蜘蛛池模板: 绥滨县| 邛崃市| 黑河市| 巨野县| 祁阳县| 阜宁县| 余姚市| 阳信县| 嘉禾县| 都昌县| 视频| 花垣县| 青海省| 青龙| 建德市| 靖边县| 福州市| 桦甸市| 望江县| 逊克县| 金秀| 同德县| 蚌埠市| 邳州市| 凤城市| 顺平县| 山阴县| 故城县| 山东| 宁波市| 绩溪县| 全南县| 集贤县| 商都县| 屏东县| 定陶县| 台安县| 穆棱市| 古交市| 阿克苏市| 阳曲县|