jQuery图片轮播(二)利用构造函数和原型创建对象以实现继承


Posted in Javascript onDecember 06, 2016

上一篇文中完成的封装,还存在一个小问题,就是该轮播对象不能在同一页面中重复使用,本文将通过组合使用javascript的构造函数和原型模式创建对象来解决这个问题。

没有看过上一篇文章的朋友可以点此查看上一篇文章 (jQuery图片轮播实现并封装(一))

首先回顾一下,上文的问题所在,上文中的carsouel对象是采用字面量的方式来定义的,这样carsouel本就是一个实例,想要使用在多处时,这个对象的方法会发生冲突,最终只会执行最后的那一个。而通过采用构造函数的方式来定义对象carsouel,每次需要使用时只需要用new操作符来实例化一个新对象,页面中需要几处轮播就实例化几个对象,这样就可以满足需求。所以,将代码改成以下形式。

function Carousel(){
  this.now = 0;          //当前显示的图片索引
  this.hasStarted = false;     //是否开始轮播
  this.interval = null;      //定时器
  this.liItems = null;       //要轮播的li元素集合
  this.len = 0;         //liItems的长度
  this.aBox : null;        //包含指示器的dom对象
  this.bBox : null;        //包含前后按钮的dom对象
  /**
   * 初始化及控制函数
   * @param bannnerBox string 包含整个轮播图盒子的id或class
   * @param aBox string 包含指示器的盒子的id或class
   * @param btnBox string 包含前后按钮的盒子的id或class
   */
  this.startPlay = function(bannnerBox,aBox,btnBox) {
    //初始化对象参数
    var that = this;
    this.liItems = $(bannnerBox).find('ul').find('li');
    this.len = this.liItems.length;
    this.aBox = $(bannnerBox).find(aBox);
    this.bBox = $(bannnerBox).find(btnBox);
    //让第一张图片显示,根据轮播图数量动态创建指示器,并让第一个指示器处于激活状态,隐藏前后按钮
    this.liItems.first('li').css({'opacity': 1, 'z-index': 1}).siblings('li').css({'opacity': 0, 'z-index': 0});
    var aDom = '';
    for (var i = 0; i < this.len; i++){
      aDom += '<a></a>';
    }
    $(aDom).appendTo(this.aBox);
    this.aBox.find('a:first').addClass("indicator-active");
    this.bBox.hide();
    //鼠标移入banner图时,停止轮播并显示前后按钮,移出时开始轮播并隐藏前后按钮
    $(bannnerBox).hover(function (){
      that.stop();
      that.bBox.fadeIn(200);
    }, function (){
      that.start();
      that.bBox.fadeOut(200);
    });
    //鼠标移入指示器时,显示对应图片,移出时继续播放
    this.aBox.find('a').hover(function (){
      that.stop();
      var out = that.aBox.find('a').filter('.indicator-active').index();
      that.now = $(this).index();
      if(out!=that.now) {
        that.play(out, that.now)
      }
    }, function (){
      that.start();
    });
    //点击左右按钮时显示上一张或下一张
    $(btnBox).find('a:first').click(function(){that.next()});
    $(btnBox).find('a:last').click(function(){that.prev()});
    //开始轮播
    this.start()
  };
  //前一张函数
  this.prev = function (){
    var out = this.now;
    this.now = (--this.now + this.len) % this.len;
    this.play(out, this.now);
  };
  //后一张函数
  this.next = function (){
    var out = this.now;
    this.now = ++this.now % this.len;
    this.play(out, this.now);
  };
  /**
   * 播放函数
   * @param out number 要消失的图片的索引值
   * @param now number 接下来要轮播的图的索引值
   */
  this.play = function (out, now){
    this.liItems.eq(out).stop().animate({opacity:0,'z-index':0},500).end().eq(now).stop().animate({opacity:1,'z-index':1},500);
    this.aBox.find('a').removeClass('imgnum-active').eq(now).addClass('indicator-active');
  };
  //开始函数
  this.start = function(){
    if(!this.hasStarted) {
      this.hasStarted = true;
      var that = this;
      this.interval = setInterval(function(){
        that.next();
      },2000);
    }
  };
  //停止函数
  this.stop = function (){
    clearInterval(this.interval);
    this.hasStarted = false;
  }
};

调用时采用new操作符,如下:

var banner1 = new Carousel();
  var banner2 = new Carousel();
  var banner3 = new carousel();
  banner1.startPlay('#J_bg_ban1','#J_bg_indicator1','#J_bg_btn1');
  banner2.startPlay('#J_bg_ban2','#J_sm_indicator2','#J_bg_btn2');
  banner3.startPlay('#J_bg_ban3','#J_sm_indicator3','#J_bg_btn3');

上述方法可实现需求,但是仔细分析发现,这与上一篇文中使用extend复制对象的方法几乎是一样的,这里的new操作符实际上也是将构造函数完全复制了一份出来作为一个新的对象,那就和上文中提到的方法存在共同的缺点,那就是内部函数不能复用,每次执行用new操作符来实例化,都会创建新的内部函数,这也是单独使用构造函数来自定义对象的缺点。

在Carousel对象内的next函数,prev函数,strat函数,stop函数其实都是可以共用的,多个轮播件共用这些函数是完全没有问题的,而初始化函数和play函数需要作为私有函数来调用。单独使用构造函数创建的对象,当使用new操作符创建新实例的时候,初始化方法和play方法会被重新在每个实例上创建一遍,这正是我们想要的结果,而next方法、prev方法、start方法、stop方法这些可共用的方法也会被重新创建,而创造多个完成一样任务的方法是完全没有必要的,所以需要将这些共有的方法提出来,让所有Carousel对象的实例都可以公用,这样就可以解决函数复用的问题。

通过将这些共用的方法写在Carousel的原型对象上,在创建Carousel新实例的时候就可以通过原型链来共享这些方法,这样这些公用函数也就得到了复用,代码如下:

function Carousel(){
  this.now = 0;          //当前显示的图片索引
  this.hasStarted= false;     //是否开始轮播
  this.interval = null;      //定时器
  this.liItems = null;       //要轮播的li元素集合
  this.len = 0;          //liItems的长度
  this.aBox = null;        //包含指示器的dom对象
  this.bBox = null;        //包含前后按钮的dom对象
  /**
   * 初始化及控制函数
   * @param bannnerBox string 包含整个轮播图盒子的id或class
   * @param aBox string 包含指示器的盒子的id或class
   * @param btnBox string 包含前后按钮的盒子的id或class
   */
  this.startPlay = function(bannnerBox,aBox,btnBox) {
    //初始化对象参数
    var that = this;
    this.liItems = $(bannnerBox).find('ul').find('li');
    this.len = this.liItems.length;
    this.aBox = $(bannnerBox).find(aBox);
    this.bBox = $(bannnerBox).find(btnBox);
    //让第一张图片显示,根据轮播图数量动态创建指示器,并让第一个指示器处于激活状态,隐藏前后按钮
    this.liItems.first('li').css({'opacity': 1, 'z-index': 1}).siblings('li').css({'opacity': 0, 'z-index': 0});
    var aDom = '';
    for (var i = 0; i < this.len; i++){
      aDom += '<a></a>';
    }
    $(aDom).appendTo(this.aBox);
    this.aBox.find('a:first').addClass("imgnum-active");
    this.bBox.hide();
    //鼠标移入banner图时,停止轮播并显示前后按钮,移出时开始轮播并隐藏前后按钮
    $(bannnerBox).hover(function (){
      that.stop();
      that.bBox.fadeIn(200);
    }, function (){
      that.start();
      that.bBox.fadeOut(200);
    });
    //鼠标移入指示器时,显示对应图片,移出时继续播放
    this.aBox.find('a').hover(function (){
      that.stop();
      var out = that.aBox.find('a').filter('.indicator-active').index();
      that.now = $(this).index();
      if(out!=that.now) {
        that.play(out,that.now)
      }
    }, function (){
      that.start();
    });
    //点击左右按钮时显示上一张或下一张
    $(btnBox).find('a:first').click(function(){that.next()});
    $(btnBox).find('a:last').click(function(){that.prev()});
    //开始轮播
    this.start()
  };
  /**
   * 播放函数
   * @param out number 要消失的图片的索引值
   * @param now number 接下来要轮播的图的索引值
   */
  this.play = function (out,now){
    this.liItems.eq(out).stop().animate({opacity:0,'z-index':0},500).end().eq(now).stop().animate({opacity:1,'z-index':1},500);
    this.aBox.find('a').removeClass('imgnum-active').eq(now).addClass('indicator-active');
  };
}
Carousel.prototype = {
  //前一张函数
  prev : function (){
    var out = this.now;
    this.now = (--this.now + this.len) % this.len;
    this.play(out,this.now)
  },
  //后一张函数
  next : function (){
    var out = this.now;
    this.now = ++this.now % this.len;
    this.play(out,this.now);
  },
  //开始函数
  start : function(){
    if(!this.hasStarted) {
      this.hasStarted = true;
      var that = this;
      this.interval = setInterval(function(){
        that.next();
      },2000);
    }
  },
  //停止函数
  stop : function (){
    clearInterval(this.interval);
    this.hasStarted = false;
  }
};

在这里用字面量重写了Carousel对象的原型对象,将next方法,perv方法,start方法和stop方法写进了Carousel的原型对象中,这样每次实例化的对象就可以共用这些方法。当然,实例化的方法也是使用new操作符。

这种组合使用构造函数和原型的模式,是创建自定义类型最常用的方法,至此我们就完成了这个简单轮播对象的封装。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
javascript创建数组之联合数组的使用方法示例
Dec 26 Javascript
基于jquery实现在线选座订座之影院篇
Aug 24 Javascript
jQuery模拟360浏览器切屏效果幻灯片(附demo源码下载)
Jan 29 Javascript
基于JavaScript实现滑动门效果
Mar 16 Javascript
validationEngine 表单验证插件使用实例代码
Jun 15 Javascript
简单实现js轮播图效果
Jul 14 Javascript
将jquery.qqFace.js表情转换成微信的字符码
Dec 01 jQuery
微信小程序仿微信运动步数排行(交互)
Jul 13 Javascript
vue指令之表单控件绑定v-model v-model与v-bind结合使用
Apr 17 Javascript
微信小程序实现下拉刷新动画
Jun 21 Javascript
element实现合并单元格通用方法
Nov 13 Javascript
2020淘宝618理想生活列车自动领喵币js脚本的代码
Jun 02 Javascript
jQuery File Upload文件上传插件使用详解
Dec 06 #Javascript
vue2.0开发实践总结之入门篇
Dec 06 #Javascript
微信小程序中单位rpx和rem的使用
Dec 06 #Javascript
JavaScript定时器实现的原理分析
Dec 06 #Javascript
原生js实现弹出层登录拖拽功能
Dec 05 #Javascript
详解Vue.js——60分钟组件快速入门(上篇)
Dec 05 #Javascript
原生js编写基于面向对象的分页组件
Dec 05 #Javascript
You might like
escape unescape的php下的实现方法
2007/04/27 PHP
phpExcel中文帮助手册之常用功能指南
2014/08/18 PHP
php函数连续调用实例分析
2015/07/30 PHP
PHP和C#可共用的可逆加密算法详解
2015/10/26 PHP
js宝典学习笔记(上)
2007/01/10 Javascript
ExtJS DOM元素操作经验分享
2013/08/28 Javascript
JavaScript实现同一页面内两个表单互相传值的方法
2015/08/12 Javascript
JavaScript缓冲运动实现方法(2则示例)
2016/01/08 Javascript
jQuery命名空间与闭包用法示例
2017/01/12 Javascript
Angular.js中ng-if、ng-show和ng-hide的区别介绍
2017/01/20 Javascript
基于JavaScript实现自定义滚动条
2017/01/25 Javascript
老生常谈jacascript DOM节点获取
2017/04/17 Javascript
js获取文件里面的所有文件名(实例)
2017/10/17 Javascript
js实现图片3D轮播效果
2019/09/21 Javascript
Nodejs封装类似express框架的路由实例详解
2020/01/05 NodeJs
详解Django中的form库的使用
2015/07/18 Python
Python编写电话薄实现增删改查功能
2016/05/07 Python
Python实现PS图像调整颜色梯度效果示例
2018/01/25 Python
python中找出numpy array数组的最值及其索引方法
2018/04/17 Python
python使用Matplotlib画饼图
2018/09/25 Python
python发送多人邮件没有展示收件人问题的解决方法
2019/06/21 Python
OpenCV 轮廓检测的实现方法
2019/07/03 Python
Django  ORM 练习题及答案
2019/07/19 Python
python ffmpeg任意提取视频帧的方法
2020/02/21 Python
python中怎么表示空值
2020/06/19 Python
Python创建临时文件和文件夹
2020/08/05 Python
python 基于DDT实现数据驱动测试
2021/02/18 Python
CSS3媒体查询Media Queries基础学习教程
2016/02/29 HTML / CSS
狗狗玩具、零食和咀嚼物的月度送货服务:Super Chewer
2018/08/22 全球购物
英国设计师珠宝网站:Joshua James Jewellery
2020/03/01 全球购物
积极向上的团队口号
2014/06/06 职场文书
党的作风建设心得体会
2014/10/22 职场文书
2015圣诞节贺卡寄语
2015/03/24 职场文书
jquery插件实现悬浮的菜单
2021/04/24 jQuery
Python中Cookies导出某站用户数据的方法
2021/05/17 Python
教你使用Python获取QQ音乐某个歌手的歌单
2022/04/03 Python