• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >JavaScript > Vue自定义图片懒加载指令v-lazyload详解

Vue自定义图片懒加载指令v-lazyload详解

作者:断劫断念 字体:[增加 减小] 来源:互联网 时间:2017-05-11

断劫断念通过本文主要向大家介绍了vue详解,vue 指令详解,vue.js详解,vue.js路由详解,vue自定义指令等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

Vue是可以自定义指令的,最近学习过程中遇见了一个需要图片懒加载的功能,最后参考了别人的代码和思路自己重新写了一遍。以下将详细介绍如何实现自定义指令v-lazyload。

先看如何使用这个指令:  

<img v-lazyload="imageSrc" >
</div>

imageSrc是要加载的图片的实际路径。

为了实现这个指令,我们首先单独建立一个文件,名字为lazyload.js.并填写基本的代码,如下:  

//Vue 图片懒加载,导出模块
export default (Vue , options = {})=>{
  //初始化的选项,default是未加载图片时显示的默认图片
  var init = {
     default: 'https://gw.alicdn.com/tps/i1/TB147JCLFXXXXc1XVXXxGsw1VXX-112-168.png'
  }
  //addListener为Vue指令的具体实现功能函数,我们这里为所有使用v-lazyload的指令的元素添加监听
  //ele 是dom元素,binding是绑定的具体值,
  //例如:<img v-lazyload="imageSrc" > ele是img binding是imageSrc
  const addListenner = (ele,binding) =>{
    
  }
  //Vue自定义指令,lazyload为指令的名称
  Vue.directive('lazyload',{
    inserted:addListener,
    updated:addListener
  })
}
</div>

inserted 和 updated为Vue指令的执行不同阶段提供的钩子函数,查看Vue的官网可以看到一共有5个阶段, 

指令定义函数提供了几个钩子函数(可选):

bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。

inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。

update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。

componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。

unbind: 只调用一次, 指令与元素解绑时调用。

这里我们只用inserted和updated就够了。

  接下来我们具体实现addListener的实现。我们的具体思路如下:

  1、先看看这个图片是否需要懒加载。有两种情况,一是图片还没到达可视区域,二是图片已经加载过了。

  2、然后监听窗口的scroll事件,判断哪些图片可以进行懒加载了。

  这里我们需要一个需要进行监听需要懒加载的图片列表和一个需要记录已经加载过得图片列表。另外为了方便数组的操作,我们加一个数组的remove方法。

继续我们的代码。

//Vue 图片懒加载
export default (Vue , options = {})=>{
  
  //数组item remove方法
  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 init = {   
    default: 'https://gw.alicdn.com/tps/i1/TB147JCLFXXXXc1XVXXxGsw1VXX-112-168.png' 
  }  
  //需要进行监听的图片列表,还没有加载过得 
  var listenList = [];
  //已经加载过得图片缓存列表
  var imageCatcheList = [];
  //是否已经加载过了
  const isAlredyLoad = (imageSrc) => {
    
  }
  //检测图片是否可以加载,如果可以则进行加载
  const isCanShow = (item) =>{
    
  };
  //添加监听事件scroll
  const onListenScroll = () =>{
    
  }
  //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 = init.default;
    //再看看是否可以显示此图片
    if(isCanShow(item)){
      return
    }
    //否则将图片地址和元素均放入监听的lisenList里
    listenList.push(item);
    
    //然后开始监听页面scroll事件
    onListenScroll();
  }

  Vue.directive('lazyload',{
    inserted:addListener,
    updated:addListener
  })
}

</div>

接下来就几个空方法的实现了。

isAlredyLoad ,判断是否已经加载过了这个图片

const isAlredyLoad = (imageSrc) => {
    if(imageCatcheList.indexOf(imageSrc) > -1){
      return true;
    }else{
      return false;
    }
  }
</div>

isCanShow 图片是否进入可视区域,如果已经进入则进行加载

//检测图片是否可以加载,如果可以则进行加载
  const isCanShow = (item) =>{
    var ele = item.ele;
    var src = item.src;
    //图片距离页面顶部的距离
    var top = ele.getBoundingClientRect().top;
    //页面可视区域的高度
    var windowHeight = window.innerHight;
    //top + 10 已经进入了可视区域10像素
    if(top + 10 < window.innerHeight){
      var image = new Image();
      image.src = src;
      image.onload = function(){
        ele.src = src;
        imageCatcheList.push(src);
        listenList.remove(item);
      }
      return true;
    }else{
      return false;
    }
  };
</div>

onListenScroll监听滚动事件,并且检测是否进入可视区域。

const onListenScroll = () =>{
    window.addEventListener('scroll',function(){
      var length = listenList.length;
      for(let i = 0;i<length;i++ ){
        isCanShow(listenList[i]);
      }
    })
  }
</div>

最终我们的代码如下:

//Vue 图片懒加载
export default (Vue , options = {})=>{
  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 init = {
    lazyLoad: false,
    default: 'https://gw.alicdn.com/tps/i1/TB147JCLFXXXXc1XVXXxGsw1VXX-112-168.png'
  }

  var listenList = [];
  var imageCatcheList = [];

  const isAlredyLoad = (imageSrc) => {
    if(imageCatcheList.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 + 10 已经进入了可视区域10像素
    if(top + 10 < window.innerHeight){
      var image = new Image();
      image.src = src;
      image.onload = function(){
        ele.src = src;
        imageCatcheList.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 = init.default;
    //再看看是否可以显示此图片
    if(isCanShow(item)){
      return
    }
    //否则将图片地址和元素均放入监听的lisenList里
    listenList.push(item);
    
    //然后开始监听页面scroll事件
    onListenScroll();
  }

  Vue.directive('lazyload',{
    inserted:addListener,
    updated:addListener
  })
}

</div>

使用时需要在主文件中引入这个文件,并且vue.use();

import LazyLoad from 'lazyLoad.js'
Vue.use(LazyLoad);


</div>

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Vue 进阶教程之v-model详解
  • 详解Vue中使用v-for语句抛出错误的解决方案
  • Vue自定义图片懒加载指令v-lazyload详解
  • 详解Vue 普通对象数据更新与 file 对象数据更新
  • 详解Vue 动态添加模板的几种方法
  • 详解Vue 事件驱动和依赖追踪
  • 详解Vue使用 vue-cli 搭建项目
  • 详解vue表单验证组件 v-verify-plugin
  • Vue响应式原理详解
  • Vue生命周期示例详解

相关文章

  • 2017-05-11解决nodejs中使用http请求返回值为html时乱码的问题
  • 2017-05-11jquery做个日期选择适用于手机端示例
  • 2017-05-11easyUI combobox实现联动效果
  • 2017-05-11BootStrap select2 动态改变值的方法
  • 2017-05-11jquery 判断是否支持Placeholder属性的方法
  • 2017-05-11详解闭包解决jQuery中AJAX的外部变量问题
  • 2017-05-11微信小程序 图片加载(本地,网路)实例详解
  • 2017-05-11canvas实现图像放大镜
  • 2017-05-11Javascript for in的缺陷总结
  • 2017-05-11js 判断数据类型的几种方法

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • jQuery图片瀑布流的简单实现代码
    • vue-dialog的弹出层组件
    • jquery仿微信聊天界面
    • JavaScript实现鼠标点击导航栏变色特效
    • Bootstrap BootstrapDialog使用详解
    • 深入理解Javascript中的valueOf与toString
    • vue.js的提示组件
    • jQuery插件zTree实现单独选中根节点中第一个节点示例
    • JS生成一维码(条形码)功能示例
    • canvas实现图像布局填充功能

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有