JS基本篇--搞清Image加载事宜(onload)、加载状况(complete)后,完成图片的当地预览,并自适应于父元素内

onload与complete引见

complete只是HTMLImageElement对象的一个属性,能够推断图片加载完成,不论图片是不是是有缓存;而onload则是这个Image对象的load事宜回调,当图片加载完成后实行onload绑定的函数。

给下面一个例子,诠释下:

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');  
    }  
} 

打印结果:
第一次点击,谷歌浏览器结果为:dd;IE浏览器结果为:ff。
第二次点击,谷歌浏览器结果为:dd,ff;IE浏览器结果为:ff。
第三次点击,谷歌浏览器结果为:dd,ff;IE浏览器结果为: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";  
} 

打印结果:
第一次点击,谷歌浏览器结果为:dd,ff;IE浏览器结果为:ff。
第二次点击,谷歌浏览器结果为:dd,ff;IE浏览器结果为:ff。
第二次点击,谷歌浏览器结果为:dd,ff;IE浏览器结果为: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="";     
}  

打印结果:
第一次点击,谷歌浏览器结果为:dd;IE浏览器结果为:空。
第二次点击,谷歌浏览器结果为:dd;IE浏览器结果为:空。
第二次点击,谷歌浏览器结果为:dd;IE浏览器结果为:空。

依据结果得出:关于 complete 属性来说,IE是依据图片是不是显现过来推断,就是说当加载的图片显现出来后,complete 属性的值才为 true ,不然一直是 false ,和之前是不是加载过该张图片没有关系,即和缓存没有关系!然则别的浏览器表现出来确实不一样,只需之前加载过该图,浏览器有缓存,也不管src是不是有值,胜利与否,只需猎取到image,就能够实行,complete 就为 true。所以这个complete在差别浏览器中结果是不一样的。

当地图片预览

起首先写下规划,html代码:

<div class="centerView">
    <div class="localPreview">
        <img id="showViewImg"/>
    </div>
    <a class="inputParent" href="javascript:void(0)">
        <i>点击上传文件</i>
        <input type="file" id="filePath" onchange="getCurrFile()"/>
    </a>
</div>

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;
}

静态页面的结果如图所示:
《JS基本篇--搞清Image加载事宜(onload)、加载状况(complete)后,完成图片的当地预览,并自适应于父元素内》

梳理一下思绪,我们要完成图片的当地预览,须要以下几点:
1.点击file上传文件按钮后,选中图片后,取得图片的途径。
2.依据图片实例一个new Image()获得图片的现实的大小。
3.获得图片的现实大小,再依据显现地区的宽高来处置惩罚图片的宽高,让其自顺应于父元素地区中。
4.在IE9以及低版本浏览器中须要运用滤镜来完成图片的预览。

依据以上几点我们就写以下代码,起首我们先建立一个组织函数。

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

这个oriWidth与oriHeight指的是父地区的宽高,也就是图片要跟该宽高举行比较的值。

接下来完成一个getObjectURL,干吗的呢,假如支撑file对象支撑files,就返回只包含url的一个对象,假如是IE9以及低版本浏览器返回的对象中还包含滤镜图片的原始大小。

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;
        //然则当滤镜运用的图片凌驾10M大小,运用上面的代码页面会报错,说hiddenAlphaImage涌现未指明的毛病;
        //解决办法就是运用下面的解释的体式格局,解释上面的两行代码
        //运用下面代码滤镜图片凌驾10M后当地预览不了,经由过程这个滤镜获得的图片的宽高始终是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低版本浏览器为何要如许处置惩罚呢,假如我们要获得滤镜图片的元素大小,起首得建立一个img元素,然后经由过程IE浏览器的document.selection.createRange().text获得图片途径,然后给这个img元素举行设置,这儿症结得用到filter的sizingMethod属性。

sizingMethod属性:可选值,设置或检索的体式格局来显现一个图象在对象边境显现体式格局。有三个值:crop裁剪图象以顺应对象的尺寸;image,默认值,扩展或削减对象的边境,以顺应图象的尺寸;scale,舒展或压缩图象添补对象的边境;

这儿运用image才获得滤镜图片的原始大小。然后返回。
假如一开始只是把这个url返回归去,没有返回滤镜图片的现实大小,就不能到达自顺应的结果。

固然上面猎取图片的url用到的是window.createObjectURL,也能够用FileReader.readAsDataURL读取指定Blob或File的内容。
简朴完成一下:

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]);
}

这儿就不细致引见了,只是这儿获得的url是base64编码的字符串,所以我平常照样选中上面第一种体式格局。

接下来就是图片自顺应的比较要领:

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);
    }
}

这儿就不细说了。

末了就是绑定到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低版本不设置图片src会显现裂图,所以设置一个通明图片或许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代码总结:

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;
        //然则当滤镜运用的图片凌驾10M大小,运用上面的代码页面会报错,说hiddenAlphaImage涌现未指明的毛病;
        //解决办法就是运用下面的解释的体式格局,解释上面的两行代码
        //运用下面代码滤镜图片凌驾10M后当地预览不了,经由过程这个滤镜获得的图片的宽高始终是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低版本不设置图片src会显现裂图,所以设置一个通明图片或许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基本篇--搞清Image加载事宜(onload)、加载状况(complete)后,完成图片的当地预览,并自适应于父元素内》

    原文作者:风雨后见彩虹
    原文地址: https://segmentfault.com/a/1190000010465626
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞