成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

JS基礎(chǔ)篇--搞清Image加載事件(onload)、加載狀態(tài)(complete)后,實(shí)現(xiàn)圖片的本地

callmewhy / 4030人閱讀

摘要:與介紹只是對(duì)象的一個(gè)屬性,可以判斷圖片加載完成,不管圖片是不是有緩存而則是這個(gè)對(duì)象的事件回調(diào),當(dāng)圖片加載完成后執(zhí)行綁定的函數(shù)。第三次點(diǎn)擊,谷歌瀏覽器結(jié)果為瀏覽器結(jié)果為。例打印結(jié)果第一次點(diǎn)擊,谷歌瀏覽器結(jié)果為瀏覽器結(jié)果為空。

onload與complete介紹

complete只是HTMLImageElement對(duì)象的一個(gè)屬性,可以判斷圖片加載完成,不管圖片是不是有緩存;而onload則是這個(gè)Image對(duì)象的load事件回調(diào),當(dāng)圖片加載完成后執(zhí)行onload綁定的函數(shù)。

給下面一個(gè)例子,解釋下:

document.getElementById("load").onclick = function() {  
    var img = new Image();  
    img.src="images/avatar.png";  
    if(img.complete) {  
        console.log("dd");  
    }  
    img.onload = function() {  
        console.log("ff");  
    }  
} 

打印結(jié)果:
第一次點(diǎn)擊,谷歌瀏覽器結(jié)果為:dd;IE瀏覽器結(jié)果為:ff。
第二次點(diǎn)擊,谷歌瀏覽器結(jié)果為:dd,ff;IE瀏覽器結(jié)果為:ff。
第三次點(diǎn)擊,谷歌瀏覽器結(jié)果為:dd,ff;IE瀏覽器結(jié)果為:dd,ff。
...

例2:

document.getElementById("load").onclick = function() {  
    var img = new Image();  
    if(img.complete) {  
        console.log("dd");  
    }  
    img.onload = function() {  
        console.log("ff")  
    }  
    img.src="images/avatar.png";  
} 

打印結(jié)果:
第一次點(diǎn)擊,谷歌瀏覽器結(jié)果為:dd,ff;IE瀏覽器結(jié)果為:ff。
第二次點(diǎn)擊,谷歌瀏覽器結(jié)果為:dd,ff;IE瀏覽器結(jié)果為:ff。
第二次點(diǎn)擊,谷歌瀏覽器結(jié)果為:dd,ff;IE瀏覽器結(jié)果為:ff。
...

例3:

document.getElementById("load").onclick = function() {  
    var img = new Image(); 
    
    if(img.complete) {  
        console.log("dd");  
    }  
    img.onload = function() {  
        console.log("ff")  
    }  
    img.src="";     
}  

打印結(jié)果:
第一次點(diǎn)擊,谷歌瀏覽器結(jié)果為:dd;IE瀏覽器結(jié)果為:空。
第二次點(diǎn)擊,谷歌瀏覽器結(jié)果為:dd;IE瀏覽器結(jié)果為:空。
第二次點(diǎn)擊,谷歌瀏覽器結(jié)果為:dd;IE瀏覽器結(jié)果為:空。
...

根據(jù)結(jié)果得出:對(duì)于 complete 屬性來(lái)講,IE是根據(jù)圖片是否顯示過(guò)來(lái)判斷,就是說(shuō)當(dāng)加載的圖片顯示出來(lái)后,complete 屬性的值才為 true ,否則一直是 false ,和以前是否加載過(guò)該張圖片沒(méi)有關(guān)系,即和緩存沒(méi)有關(guān)系!但是其它瀏覽器表現(xiàn)出來(lái)的確不一樣,只要以前加載過(guò)該圖,瀏覽器有緩存,也無(wú)論src是否有值,成功與否,只要獲取到image,就可以執(zhí)行,complete 就為 true。所以這個(gè)complete在不同瀏覽器中結(jié)果是不一樣的。

本地圖片預(yù)覽

首先先寫(xiě)下布局,html代碼:

css代碼:

.centerView{
    width:150px;
}
.localPreview{
    position:relative;
    width:150px;
    height:150px;
    line-height:150px;
    text-align:center;
    background:#ccc;
}
.localPreview img{
    position: relative;
    vertical-align: middle;
}
.inputParent{
    position:relative;
    display:block;
    margin:10px auto;
    cursor:pointer;
    width:80px;
    height:30px;
    line-height:30px;
    background:#27bb6e;
    text-align: center;
    font-size:12px;
    color:#fff;
}
.inputParent i{
    font-style: normal;
    color:#fff;
}
.inputParent #filePath{
    position:absolute;
    width:100%;
    height:100%;
    top:0;
    left:0;
    filter:alpha(opacity=0); 
    opacity: 0;
}

靜態(tài)頁(yè)面的效果如圖所示:

梳理一下思路,我們要實(shí)現(xiàn)圖片的本地預(yù)覽,需要如下幾點(diǎn):
1.點(diǎn)擊file上傳文件按鈕后,選中圖片后,獲得圖片的路徑。
2.根據(jù)圖片實(shí)例一個(gè)new Image()得到圖片的實(shí)際的大小。
3.得到圖片的實(shí)際大小,再根據(jù)顯示區(qū)域的寬高來(lái)處理圖片的寬高,讓其自適應(yīng)于父元素區(qū)域中。
4.在IE9以及低版本瀏覽器中需要使用濾鏡來(lái)實(shí)現(xiàn)圖片的預(yù)覽。

根據(jù)以上幾點(diǎn)我們就寫(xiě)如下代碼,首先我們先創(chuàng)建一個(gè)構(gòu)造函數(shù)。

function DealPic(width,height){
    this.oriWidth = width;
    this.oriHeight = height;
}

這個(gè)oriWidth與oriHeight指的是父區(qū)域的寬高,也就是圖片要跟該寬高進(jìn)行比較的值。

接下來(lái)實(shí)現(xiàn)一個(gè)getObjectURL,干嘛的呢,如果支持file對(duì)象支持files,就返回只包含url的一個(gè)對(duì)象,如果是IE9以及低版本瀏覽器返回的對(duì)象中還包括濾鏡圖片的原始大小。

DealPic.prototype.getObjectURL = function(fileObj){
    var result = {} ;
    var file;
    if(fileObj.files){
        file = fileObj.files[0];
        if (window.createObjectURL!=undefined) { // basic
            result.url = window.createObjectURL(file) ;
        }else if (window.URL!=undefined) { // mozilla(firefox)
            result.url = window.URL.createObjectURL(file) ;
        }else if (window.webkitURL!=undefined) { // webkit or chrome
            result.url = window.webkitURL.createObjectURL(file) ;
        }
    }else{
       var hiddenAlphaImageWidth,hiddenAlphaImageHeight;
        var hiddenAlphaImage = document.createElement("img");
        document.body.appendChild(hiddenAlphaImage);
        fileObj.select();
        fileObj.blur();
        result.url = document.selection.createRange().text;
        hiddenAlphaImage.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=image)";
        hiddenAlphaImage.filters.item("DXImageTransform.Microsoft.AlphaImageLoader").src = result.url;
        //但是當(dāng)濾鏡使用的圖片超過(guò)10M大小,使用上面的代碼頁(yè)面會(huì)報(bào)錯(cuò),說(shuō)hiddenAlphaImage出現(xiàn)未指明的錯(cuò)誤;
        //解決辦法就是使用下面的注釋的方式,注釋上面的兩行代碼
        //使用下面代碼濾鏡圖片超過(guò)10M后本地預(yù)覽不了,通過(guò)這個(gè)濾鏡得到的圖片的寬高始終是28*30
        //hiddenAlphaImage.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod="image",src="" + result.url + "")"; 
        
        result.width = hiddenAlphaImage.offsetWidth;
        result.height = hiddenAlphaImage.offsetHeight;
        if(hiddenAlphaImage.parentNode){
            hiddenAlphaImage.parentNode.removeChild(hiddenAlphaImage);
        }
    }
    return result;
}

在IE低版本瀏覽器為什么要這樣處理呢,如果我們要得到濾鏡圖片的元素大小,首先得創(chuàng)建一個(gè)img元素,然后通過(guò)IE瀏覽器的document.selection.createRange().text得到圖片路徑,然后給這個(gè)img元素進(jìn)行設(shè)置,這兒關(guān)鍵得用到filter的sizingMethod屬性。

sizingMethod屬性:可選值,設(shè)置或檢索的方式來(lái)顯示一個(gè)圖像在對(duì)象邊界顯示方式。有三個(gè)值:crop裁剪圖像以適應(yīng)對(duì)象的尺寸;image,默認(rèn)值,擴(kuò)大或減少對(duì)象的邊界,以適應(yīng)圖像的尺寸;scale,伸展或收縮圖像填充對(duì)象的邊界;

這兒使用image才能得到濾鏡圖片的原始大小。然后返回。
如果一開(kāi)始只是把這個(gè)url返回回去,沒(méi)有返回濾鏡圖片的實(shí)際大小,就不能達(dá)到自適應(yīng)的效果。

當(dāng)然上面獲取圖片的url用到的是window.createObjectURL,也可以用FileReader.readAsDataURL讀取指定Blob或File的內(nèi)容。
簡(jiǎn)單實(shí)現(xiàn)一下:

if (input.files && input.files[0]) {
    var reader = new FileReader();
    reader.onload = function (e) { 
        var showImg = document.getElementById("showViewImg");
        showImg.src = e.target.result;
        showImg.style.width = "150px";
        showImg.style.height = "80px";        
    };
    reader.readAsDataURL(input.files[0]);
}

這兒就不詳細(xì)介紹了,只是這兒得到的url是base64編碼的字符串,所以我一般還是選中上面第一種方式。

接下來(lái)就是圖片自適應(yīng)的比較方法:

DealPic.prototype.getPicResult = function(targetWidth,targetHeight,callback){
    if(this.oriWidth / this.oriHeight > targetWidth / targetHeight){
        var th = this.oriHeight;
        var tw = this.oriHeight / targetHeight * targetWidth; 
    }else{
       var tw = this.oriWidth;
       var th = this.oriWidth / targetWidth * targetHeight;
    }
    if(callback){
        callback(tw,th);
    }
}

這兒就不細(xì)說(shuō)了。

最后就是綁定到file按鈕上的change事件的方法了。

function getCurrFile(){
    var fileObj = document.getElementById("filePath");
    var showImgObj = document.getElementById("showViewImg");
    var newPicObj = new DealPic(150,150);
    var resultFileObj = newPicObj.getObjectURL(fileObj);
    if(fileObj.files){
        var newImg = new Image();
        newImg.onload = function(){
            newPicObj.getPicResult(newImg.width,newImg.height,function(tw,th){
                showImgObj.style.width = tw + "px";
                showImgObj.style.height = th + "px";
            });    
        }
        newImg.src = resultFileObj.url;
        showImgObj.setAttribute("src",resultFileObj.url);
    }else{
        showImgObj.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale)";
        showImgObj.filters.item("DXImageTransform.Microsoft.AlphaImageLoader").src = resultFileObj.url;
        //IE9低版本不設(shè)置圖片src會(huì)顯示裂圖,所以設(shè)置一個(gè)透明圖片或者base64的透明圖片
        showImgObj.setAttribute("src","./images/transparent.png");
        //showImgObj.src = "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";
        newPicObj.getPicResult(resultFileObj.width,resultFileObj.height,function(resw,resh){
            showImgObj.style.width = resw + "px";
            showImgObj.style.height = resh + "px";
        });    
    }   
}

最后的js代碼總結(jié):

function DealPic(width,height){
    this.oriWidth = width;
    this.oriHeight = height;
}

DealPic.prototype.getObjectURL = function(fileObj){
    var result = {} ;
    var file;
    if(fileObj.files){
        file = fileObj.files[0];
        if (window.createObjectURL!=undefined) { // basic
            result.url = window.createObjectURL(file) ;
        }else if (window.URL!=undefined) { // mozilla(firefox)
            result.url = window.URL.createObjectURL(file) ;
        }else if (window.webkitURL!=undefined) { // webkit or chrome
            result.url = window.webkitURL.createObjectURL(file) ;
        }
    }else{
       var hiddenAlphaImageWidth,hiddenAlphaImageHeight;
        var hiddenAlphaImage = document.createElement("img");
        document.body.appendChild(hiddenAlphaImage);
        fileObj.select();
        fileObj.blur();
        result.url = document.selection.createRange().text;
        hiddenAlphaImage.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=image)";
        hiddenAlphaImage.filters.item("DXImageTransform.Microsoft.AlphaImageLoader").src = result.url;
        //但是當(dāng)濾鏡使用的圖片超過(guò)10M大小,使用上面的代碼頁(yè)面會(huì)報(bào)錯(cuò),說(shuō)hiddenAlphaImage出現(xiàn)未指明的錯(cuò)誤;
        //解決辦法就是使用下面的注釋的方式,注釋上面的兩行代碼
        //使用下面代碼濾鏡圖片超過(guò)10M后本地預(yù)覽不了,通過(guò)這個(gè)濾鏡得到的圖片的寬高始終是28*30
        //hiddenAlphaImage.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod="image",src="" + result.url + "")"; 
        
        result.width = hiddenAlphaImage.offsetWidth;
        result.height = hiddenAlphaImage.offsetHeight;
        if(hiddenAlphaImage.parentNode){
            hiddenAlphaImage.parentNode.removeChild(hiddenAlphaImage);
        }
    }
    return result;
}

DealPic.prototype.getPicResult = function(targetWidth,targetHeight,callback){
    if(this.oriWidth / this.oriHeight > targetWidth / targetHeight){
        var th = this.oriHeight;
        var tw = this.oriHeight / targetHeight * targetWidth; 
    }else{
       var tw = this.oriWidth;
       var th = this.oriWidth / targetWidth * targetHeight;
    }
    if(callback){
        callback(tw,th);
    }
}

function getCurrFile(){
    var fileObj = document.getElementById("filePath");
    var showImgObj = document.getElementById("showViewImg");
    var newPicObj = new DealPic(150,150);
    var resultFileObj = newPicObj.getObjectURL(fileObj);
    if(fileObj.files){
        var newImg = new Image();
        newImg.onload = function(){
            newPicObj.getPicResult(newImg.width,newImg.height,function(tw,th){
                showImgObj.style.width = tw + "px";
                showImgObj.style.height = th + "px";
            });    
        }
        newImg.src = resultFileObj.url;
        showImgObj.setAttribute("src",resultFileObj.url);
    }else{
        showImgObj.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale)";
        showImgObj.filters.item("DXImageTransform.Microsoft.AlphaImageLoader").src = resultFileObj.url;
        //IE9低版本不設(shè)置圖片src會(huì)顯示裂圖,所以設(shè)置一個(gè)透明圖片或者base64的透明圖片
        showImgObj.setAttribute("src","./images/transparent.png");
        //showImgObj.src = "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";
        newPicObj.getPicResult(resultFileObj.width,resultFileObj.height,function(resw,resh){
            showImgObj.style.width = resw + "px";
            showImgObj.style.height = resh + "px";
        });    
    }   
}  

最后本地預(yù)覽的效果如圖所示:

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/84572.html

相關(guān)文章

  • Javascript實(shí)現(xiàn)圖片預(yù)加載功能

    摘要:本文同步自我得博客最近要用做一個(gè)動(dòng)畫(huà)功能,為了確保動(dòng)畫(huà)在播放的時(shí)候能夠順利和平滑,我需要對(duì)所用到的圖片素材進(jìn)行預(yù)加載,下面跟大家分享一下我實(shí)現(xiàn)這個(gè)功能的過(guò)程單圖片預(yù)加載目前最常見(jiàn)的一種實(shí)現(xiàn)方式如下接下來(lái)可以使用圖片了接下來(lái)可以使用圖片了首先 本文同步自我得博客:http://www.joeray61.com 最近要用javascript做一個(gè)動(dòng)畫(huà)功能,為了確保動(dòng)畫(huà)在播放的時(shí)候能夠順利和...

    KavenFan 評(píng)論0 收藏0
  • 簡(jiǎn)記html中常用文檔加載方法

    摘要:簡(jiǎn)介最近對(duì)于文檔加載方法有了新的理解,因此整理成一片簡(jiǎn)記,方便以后進(jìn)行查閱。此狀態(tài)為樹(shù)構(gòu)建完成后觸發(fā),和一樣,但在其之后觸發(fā)兼容性以上可用方法當(dāng)瀏覽器窗口,文檔或其資源將要卸載時(shí),會(huì)觸發(fā)事件。沒(méi)有賦值時(shí),該事件不做任何響應(yīng)。 簡(jiǎn)介 最近對(duì)于文檔加載方法有了新的理解,因此整理成一片簡(jiǎn)記,方便以后進(jìn)行查閱。先來(lái)一段Html,作為我們研究的基礎(chǔ)吧。 ...

    gaosboy 評(píng)論0 收藏0
  • 簡(jiǎn)記html中常用文檔加載方法

    摘要:簡(jiǎn)介最近對(duì)于文檔加載方法有了新的理解,因此整理成一片簡(jiǎn)記,方便以后進(jìn)行查閱。此狀態(tài)為樹(shù)構(gòu)建完成后觸發(fā),和一樣,但在其之后觸發(fā)兼容性以上可用方法當(dāng)瀏覽器窗口,文檔或其資源將要卸載時(shí),會(huì)觸發(fā)事件。沒(méi)有賦值時(shí),該事件不做任何響應(yīng)。 簡(jiǎn)介 最近對(duì)于文檔加載方法有了新的理解,因此整理成一片簡(jiǎn)記,方便以后進(jìn)行查閱。先來(lái)一段Html,作為我們研究的基礎(chǔ)吧。 ...

    shenhualong 評(píng)論0 收藏0
  • 前端知識(shí)普及之頁(yè)面加載

    摘要:如果你的文件涉及操作,可以直接在里面添加回調(diào)函數(shù),或者說(shuō)基本上我們的文件都可以寫(xiě)在里面進(jìn)行調(diào)用其實(shí),這和我們將文件放在底部,在上面加以及異步加載文件的效果是一樣一樣的。 如果大家想繼續(xù)看下面的內(nèi)容的話(huà),有一個(gè)要求,就是回答我一個(gè)問(wèn)題:你這樣寫(xiě)過(guò)代碼嗎? window.onload = function(){ $(.gravatar).on(click,function(){ ...

    tianyu 評(píng)論0 收藏0
  • 拼圖小游戲

    摘要:學(xué)習(xí)小游戲開(kāi)發(fā)中最常用的碰撞檢測(cè)狀態(tài)監(jiān)控刷新保持狀態(tài)的處理方法。保存縮略圖的信息是當(dāng)游戲結(jié)束后顯示源縮略圖時(shí),根據(jù)中的內(nèi)容展示圖片。 如果您想要綜合使用javascript中canvas、原生拖拽、本地存儲(chǔ)等多種技術(shù)完成一個(gè)有趣的項(xiàng)目,那么這篇博文將非常適合您,水平有限,還望感興趣的開(kāi)發(fā)人員給予更多代碼優(yōu)化建議。 1 簡(jiǎn)介和源碼 該項(xiàng)目中的拼圖小游戲使用javascript原創(chuàng),相比于...

    svtter 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<