图片懒加载

作者: 魔王哪吒 | 来源:发表于2019-07-20 06:08 被阅读11次
    标题图
    <view wx:for="{{list}}" class='item item-{{index}}'
     wx:key="{{index}}">
        <image class="{{item.show ? 'active': ''}}" src="{{item.show ? item.src : item.def}}"></image>
    </view>
    
    image{
        transition: all .3s ease;
        opacity: 0;
    }
    .active{
        opacity: 1;
    }
    
    image.png

    数据的异步加载
    开始时把一部分数据加载出来,后面滚动时才对应的加载。

    给需要懒加载的图片外层放置一个容器:

    <div class="banner">
     <img src="" alt="" trueImg="">
    </div>
    
    .banner {
     margin: 10px auto;
     width: 350px;
     height; 200px;
     border: 1px solid green;
     background: url("../img/default.gif") no-repeat center ;
    }
    
    .banner img {
     dispaly: noene;
     width: 100%;
     height: 100%;
    }
    

    用JavaScript实现图片懒加载

    new Image()来暂时存放一个图片
    onload方法判断图片是否加载成功

    var banner = document.querySelector('.banner');
    var imgFir = banner.getElementsByTagName('img')[0];
    
    window.setTimeout(function() {
     var oImg = new Image(); // 创建一个临时的img标签
     oImg.src = imgFir.getAttribute('trueImg');
     oImg.onload=function() { // 当图片能够正常加载就执行
     imgFir.src = this.src;
     imgFir.style.dispaly = "block";
     oImg = null;
     console.log('图片加载完成'):
     var now = new Date();
     }
     var time = new Date();
     }, 500);
    

    懒加载技术


    image.png image.png

    Vue实现一个图片懒加载插件
    Vue.use()、Vue.direction、Vue图片懒加载插件实现

    // 注册一个全局自定义指令 `v-focus`
    Vue.directive('focus', {
     // 当被绑定的元素插入到 DOM 中时……
     inserted: function (el) {
     // 聚焦元素
     el.focus()
     }
    })
    

    局部注册

    directives: {
     focus: {
     // 指令的定义
     inserted: function (el) {
     el.focus()
     }
     }
    }
    

    bind:只调用一次,指令第一次绑定到元素时调用
    inserted:被绑定元素插入父节点时调用
    update:所在组件的 VNode 更新时调用
    unbind:只调用一次

    Vue图片懒加载插件实现

    // 引入Vue构造函数
    import Vue from 'vue'
     
    var lazyload = {
     // Vue.use() 默认加载install,并且将Vue当做第一个参数传递过来
     install(vue,payload) {
     // 数组扩展移除元素
     if(!Array.prototype.remove){
     Array.prototype.remove = function(item){
     if(!this.length) return
     var index = this.indexOf(item);
     if( index > -1){
     this.splice(index,1);
     return this
     }
     }
     }
     
     // 默认值图片 
     var defaultImage = payload.defaultImage || 'https://.png';
     var errorImage = payload.errorImage || 'https://.png';
     // 默认离可视区10px时加载图片
     var distanece = payload.scrollDistance || 10;
     // 收集未加载的图片元素和资源
     var listenList = [];
     // 收集已加载的图片元素和资源
     var imageCacheList = [];
     
     // 是否已经加载完成的图片
     const isAlredyLoad = (imageSrc) => {
     if(imageCacheList.indexOf(imageSrc) > -1){
     return true;
     }else{
     return false;
     }
     }
     
     //检测图片是否可以加载,如果可以则进行加载
     const isCanShow = (item) =>{
     var ele = item.ele;
     var src = item.src;
     //图片距离页面顶部的距离
     var top = ele.getBoundingClientRect().top;
     //页面可视区域的高度
     var windowHeight = window.innerHight;
     // top - distance 距离可视区域还有distance像素
     if(top - distanece < window.innerHeight){ 
     var image = new Image();
     image.src = src;
     image.onload = function() {
     ele.src = src;
     imageCacheList.push(src);
     listenList.remove(item);
     }
     image.onerror = function() {
     ele.src = errorImage;
     imageCacheList.push(src);
     listenList.remove(item);
     }
     return true;
     }else{
     return false;
     }
     };
     
     const onListenScroll = () => {
     window.addEventListener('scroll',function(){
     var length = listenList.length;
     for(let i = 0;i<length;i++ ){
     isCanShow(listenList[i]);
     }
     })
     
     }
     
     //Vue 指令最终的方法
     const addListener = (ele,binding) =>{
     //绑定的图片地址
     var imageSrc = binding.value;
     
     // 防止重复加载。如果已经加载过,则无需重新加载,直接将src赋值
     if(isAlredyLoad(imageSrc)){ 
     ele.src = imageSrc;
     return false;
     }
     
     var item = {
     ele: ele,
     src: imageSrc
     }
     
     //图片显示默认的图片
     ele.src = defaultImage;
     
     //再看看是否可以显示此图片
     if(isCanShow(item)){
     return
     }
     
     //否则将图片地址和元素均放入监听的lisenList里
     listenList.push(item);
      
     //然后开始监听页面scroll事件
     onListenScroll();
     }
     
     Vue.directive('lazyload',{
     inserted: addListener,
     updated: addListener
     })
     }
    }
     
    export default lazyload;
    

    插件的调用:

    import Vue from 'vue'
    import App from './App'
    import router from './router'
    import Lazyload from './common/js/lazyload'
     
    // 参数均为可选
    Vue.use(Lazyload,{
     scrollDistance: 15, // 距离可视区还有15px时开发加载资源
     defaultImage: '', // 资源图片未加载前的默认图片(绝对路径)
     errorImage:'' // 资源图片加载失败时要加载的资源(绝对路径)
    })
    

    请点赞!因为你们的赞同/鼓励是我写作的最大动力!

    欢迎关注达叔小生的简书!

    这是一个有质量,有态度的博客

    博客

    相关文章

      网友评论

        本文标题:图片懒加载

        本文链接:https://www.haomeiwen.com/subject/fdfylctx.html