首先,放上慕课网的课程链接,源码是在这个课程里分享出来的,https://www.imooc.com/learn/386。

文章适合学习过这个课程的同学,再看这篇文章,可能有更深入的理解。主要是对各种this,$(this),self等的指代,这里只对js文件进行了注释,需要其它css文件以及html文件的,请到官网下载

最先看得部分应该是Carousel.init的方法,然后再从上往下看

;(function($){

    var Carousel = function(poster){
//console.log(poster);由于一直不清楚这里poster和this的区别,所以我把他们打印出来了,poster就是下面init方法里面new Carousel的时候传进来的
//console.log(this); this指代的是Carousel{}
var self = this;
//保存单个旋转木马对象
this.poster = poster; //把poster的值传递给当前对象this的poster属性,值传递
this.posterItemMain = poster.find("ul.poster-list");
this.nextBtn = poster.find("div.poster-next-btn");
this.prevBtn = poster.find("div.poster-prev-btn");
this.posterItems =poster.find("li.poster-item");
if(this.posterItems.size()%2==0){
this.posterItemMain.append(this.posterItems.eq(0).clone());
this.posterItems = this.posterItemMain.children();
};
this.posterFirstItem = this.posterItems.first();
this.posterLastItem = this.posterItems.last();
this.rotateFlag = true;
//默认配置参数
this.setting = {
"width":1000, //幻灯片的宽度
"height":270, //幻灯片的高度
"posterWidth":640, //幻灯片第一帧的宽度
"posterHeight":270, //幻灯片第一帧的高度
"scale":0.9, //记录显示比例关系
"speed":500,
"autoPlay":false,
"delay":5000,
"verticalAlign":"middle" //top bottom
};
$.extend(this.setting,this.getSetting()); //把自定义的配置与默认配置合并,如果自定义配置了相同的参数,将会覆盖默认的参数,否则会保留默认参数 //设置配置参数值
this.setSettingValue();
this.setPosterPos();
//左旋转按钮
this.nextBtn .click(function(){
if(self.rotateFlag){
self.rotateFlag = false;
self.carouseRotate("left"); //这里不能再用this.rotate();因为这里的this是button这个dom节点,所以我们要在上面保存self
};
});
//右旋转按钮
this.prevBtn .click(function(){
if(self.rotateFlag){
self.rotateFlag = false;
self.carouseRotate("right");
};
});
//是否开启自动播放
if(this.setting.autoPlay){
this.autoPlay();
this.poster.hover(function(){
window.clearInterval(self.timer);
},function(){
self.autoPlay();
}); }; };
Carousel.prototype = { //完全重写了prototype为一个对象实例,不明白的可以百度一下“prototype完全重写”
autoPlay:function(){
var self = this;
this.timer = window.setInterval(function(){
self.nextBtn.click();
},this.setting.delay); }, //旋转
carouseRotate:function(dir){
var _this_ = this;
var zIndexArr = [];
//左旋转
if(dir === "left"){
this.posterItems .each(function(){
var self = $(this),
prev = self.prev().get(0)?self.prev():_this_.posterLastItem,
width = prev.width(),
height =prev.height(),
zIndex = prev.css("zIndex"),
opacity = prev.css("opacity"),
left = prev.css("left"),
top = prev.css("top");
zIndexArr.push(zIndex);
self.animate({
width:width,
height:height,
//zIndex:zIndex,
opacity:opacity,
left:left,
top:top
},_this_.setting.speed,function(){
_this_.rotateFlag = true;
});
});
//zIndex需要单独保存再设置,防止循环时候设置再取的时候值永远是最后一个的zindex
this.posterItems.each(function(i){
$(this).css("zIndex",zIndexArr[i]);
});
}else if(dir === "right"){//右旋转
this.posterItems .each(function(){
var self = $(this),
next = self.next().get(0)?self.next():_this_.posterFirstItem,
width = next.width(),
height =next.height(),
zIndex = next.css("zIndex"),
opacity = next.css("opacity"),
left = next.css("left"),
top = next.css("top");
zIndexArr.push(zIndex);
self.animate({
width:width,
height:height,
//zIndex:zIndex,
opacity:opacity,
left:left,
top:top
},_this_.setting.speed,function(){
_this_.rotateFlag = true;
}); });
//zIndex需要单独保存再设置,防止循环时候设置再取的时候值永远是最后一个的zindex
this.posterItems.each(function(i){
$(this).css("zIndex",zIndexArr[i]);
});
};
},
//设置剩余的帧的位置关系
setPosterPos:function(){
var self = this;
var sliceItems = this.posterItems.slice(1),
sliceSize = sliceItems.size()/2,
rightSlice = sliceItems.slice(0,sliceSize),
level = Math.floor(this.posterItems.size()/2),
leftSlice =sliceItems.slice(sliceSize); //设置右边帧的位置关系和宽度高度top
var rw = this.setting.posterWidth,
rh = this.setting.posterHeight,
gap = ((this.setting.width-this.setting.posterWidth)/2)/level; var firstLeft = (this.setting.width-this.setting.posterWidth)/2;
var fixOffsetLeft = firstLeft+rw;
//设置左边位置关系
rightSlice.each(function(i){
level--;
rw = rw *self.setting.scale;
rh = rh *self.setting.scale
var j = i;
$(this).css({
zIndex:level,
width:rw,
height:rh,
opacity:1/(++j),
left:fixOffsetLeft+(++i)*gap-rw,
top:self.setVerticalAlign(rh)
});
});
//设置左边的位置关系
var lw = rightSlice.last().width(),
lh =rightSlice.last().height(),
oloop = Math.floor(this.posterItems.size()/2);
leftSlice.each(function(i){
$(this).css({
zIndex:i,
width:lw,
height:lh,
opacity:1/oloop,
left:i*gap,
top:self.setVerticalAlign(lh)
});
lw = lw/self.setting.scale;
lh = lh/self.setting.scale;
oloop--;
});
},
//设置垂直排列对齐
setVerticalAlign:function(height){
var verticalType = this.setting.verticalAlign,
top = 0;
if(verticalType === "middle"){
top = (this.setting.height-height)/2;
}else if(verticalType === "top"){
top = 0;
}else if(verticalType === "bottom"){
top = this.setting.height-height;
}else{
top = (this.setting.height-height)/2;
};
return top;
},
//设置配置参数值去控制基本的宽度高度。。。
setSettingValue:function(){
this.poster.css({
width:this.setting.width,
height:this.setting.height
});
this.posterItemMain.css({
width:this.setting.width,
height:this.setting.height
});
//计算上下切换按钮的宽度
var w = (this.setting.width-this.setting.posterWidth)/2;
//设置切换按钮的宽高,层级关系
this.nextBtn.css({
width:w,
height:this.setting.height,
zIndex:Math.ceil(this.posterItems.size()/2)
});
this.prevBtn.css({
width:w,
height:this.setting.height,
zIndex:Math.ceil(this.posterItems.size()/2)
}); this.posterFirstItem.css({
width:this.setting.posterWidth,
height:this.setting.posterHeight,
left:w,
top:0,
zIndex:Math.floor(this.posterItems.size()/2)
});
},
//获取人工配置参数
getSetting:function(){ var setting = this.poster.attr("data-setting");
if(setting&&setting!=""){
return $.parseJSON(setting);
}else{
return {};
};
} };
Carousel.init = function(posters){ //为Carousel添加方法init,传入一个posters List作为参数
var _this_ = this; //既然是为Carousel添加的方法,那么这里的this就是指代Carousel对象,可以打印出来看效果
posters.each(function(){//遍历poster List参数,遍历出来的是每一个poster HTML DOM
new _this_($(this));//把每一个遍历出来的 poster HTML DOM 对象变成jQuery对象,再new 新的Carousel对象出来,这样页面上各个轮播区域就会互不相关,并且new出来的对象拥有了Carousel对象所拥有的所有属性和方法,所以能实现轮播效果(变成jQuery对象主要是为了接下来的用jQuery的方法,first()之类的)
});
};
window["Carousel"] = Carousel;
})(jQuery);

旋转木马幻灯片切换效果JS源码详解的更多相关文章

  1. 源码详解系列(六) ------ 全面讲解druid的使用和源码

    简介 druid是用于创建和管理连接,利用"池"的方式复用连接减少资源开销,和其他数据源一样,也具有连接数控制.连接可靠性测试.连接泄露控制.缓存语句等功能,另外,druid还扩展 ...

  2. 源码详解系列(八) ------ 全面讲解HikariCP的使用和源码

    简介 HikariCP 是用于创建和管理连接,利用"池"的方式复用连接减少资源开销,和其他数据源一样,也具有连接数控制.连接可靠性测试.连接泄露控制.缓存语句等功能,另外,和 dr ...

  3. spring事务详解(三)源码详解

    系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.引子 ...

  4. Activiti架构分析及源码详解

    目录 Activiti架构分析及源码详解 引言 一.Activiti设计解析-架构&领域模型 1.1 架构 1.2 领域模型 二.Activiti设计解析-PVM执行树 2.1 核心理念 2. ...

  5. 源码详解系列(七) ------ 全面讲解logback的使用和源码

    什么是logback logback 用于日志记录,可以将日志输出到控制台.文件.数据库和邮件等,相比其它所有的日志系统,logback 更快并且更小,包含了许多独特并且有用的特性. logback ...

  6. Mybatis源码详解系列(四)--你不知道的Mybatis用法和细节

    简介 这是 Mybatis 系列博客的第四篇,我本来打算详细讲解 mybatis 的配置.映射器.动态 sql 等,但Mybatis官方中文文档对这部分内容的介绍已经足够详细了,有需要的可以直接参考. ...

  7. [转]【视觉 SLAM-2】 视觉SLAM- ORB 源码详解 2

    转载地址:https://blog.csdn.net/kyjl888/article/details/72942209 1 ORB-SLAM2源码详解 by 吴博 2 https://github.c ...

  8. vue 源码详解(一):原型对象和全局 `API`的设计

    vue 源码详解(一):原型对象和全局 API的设计 1. 从 new Vue() 开始 我们在实际的项目中使用 Vue 的时候 , 一般都是在 main.js 中通过 new Vue({el : ' ...

  9. vue 源码详解(二): 组件生命周期初始化、事件系统初始化

    vue 源码详解(二): 组件生命周期初始化.事件系统初始化 上一篇文章 生成 Vue 实例前的准备工作 讲解了实例化前的准备工作, 接下来我们继续看, 我们调用 new Vue() 的时候, 其内部 ...

随机推荐

  1. CentOS安装Nginx-1.6.2+安全配置+性能配置

    注:以下所有操作均在CentOS 6.5 x86_64位系统下完成. #准备工作# 在安装Nginx之前,请确保已经使用yum安装了pcre等基础组件,具体见<CentOS安装LNMP环境的基础 ...

  2. Android复习

    第一章 1.Android系统架构:(四层) Linux内核层:为安卓设备的各种硬件提供底层的驱动. 系统运行库层:为Android系统提供主要的特性支持. 应用框架层:提供了构建应用程序可能用到的各 ...

  3. Grafana+Prometheus监控

    添加模板一定要看说明以及依赖 监控redis https://blog.52itstyle.com/archives/2049/ http://www.cnblogs.com/sfnz/p/65669 ...

  4. Log表新的RowKey设计,预Split

    1 目前Rawlog表的问题 region数量庞大,空region 率大 共有12791个region 11409空region, 比例为89.19% 剩余的region大小也是极度不均衡,最大的re ...

  5. Hello 2019 Solution

    A. Gennady and a Card Game 签到. #include <bits/stdc++.h> using namespace std; ], t[]; bool solv ...

  6. hdu 5111 树链剖分加函数式线段树

    这题说的是给了两棵树,各有100000 个节点,然后Q个操作Q<=50000; 每个操作L1 R1 L2 R2.因为对于每棵树都有一个与本棵树其他点与众不同的值, 最后问 在树上从L1到R1这条 ...

  7. IDFA踩坑记录

    IDFA踩坑记录: 1.iOS10.0 以下,即使打开“限制广告跟踪”,依然可以读取idfa: 2.打开“限制广告跟踪”,然后再关闭“限制广告跟踪”,idfa会改变: 3.越狱机器安装开发证书打的包, ...

  8. Float类型出现舍入误差的原因(round 取位)

    在练习时,输入如下代码: 结果不准确. 原因:https://blog.csdn.net/bitcarmanlee/article/details/51179572 浮点数一个普遍的问题就是在计算机的 ...

  9. Intellij IDEA 创建控制台项目,断点调试快捷方式

    在idea 2016中创建一个控制台项目(经常会忘) 打开创建界面 注意,什么都不要选,点击next(最坑的地方,经常忘) 再次点击next ============================= ...

  10. 一种不太合规的PreparedStatement使用方式

    这是一种不太合规的PreparedStatement调用使用方式 , 没有让Dao单独执行它单纯的任务. AccountDao.java package heartl_jdbc; /** * 银行操作 ...