旋转木马幻灯片切换效果JS源码详解
首先,放上慕课网的课程链接,源码是在这个课程里分享出来的,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源码详解的更多相关文章
- 源码详解系列(六) ------ 全面讲解druid的使用和源码
简介 druid是用于创建和管理连接,利用"池"的方式复用连接减少资源开销,和其他数据源一样,也具有连接数控制.连接可靠性测试.连接泄露控制.缓存语句等功能,另外,druid还扩展 ...
- 源码详解系列(八) ------ 全面讲解HikariCP的使用和源码
简介 HikariCP 是用于创建和管理连接,利用"池"的方式复用连接减少资源开销,和其他数据源一样,也具有连接数控制.连接可靠性测试.连接泄露控制.缓存语句等功能,另外,和 dr ...
- spring事务详解(三)源码详解
系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.引子 ...
- Activiti架构分析及源码详解
目录 Activiti架构分析及源码详解 引言 一.Activiti设计解析-架构&领域模型 1.1 架构 1.2 领域模型 二.Activiti设计解析-PVM执行树 2.1 核心理念 2. ...
- 源码详解系列(七) ------ 全面讲解logback的使用和源码
什么是logback logback 用于日志记录,可以将日志输出到控制台.文件.数据库和邮件等,相比其它所有的日志系统,logback 更快并且更小,包含了许多独特并且有用的特性. logback ...
- Mybatis源码详解系列(四)--你不知道的Mybatis用法和细节
简介 这是 Mybatis 系列博客的第四篇,我本来打算详细讲解 mybatis 的配置.映射器.动态 sql 等,但Mybatis官方中文文档对这部分内容的介绍已经足够详细了,有需要的可以直接参考. ...
- [转]【视觉 SLAM-2】 视觉SLAM- ORB 源码详解 2
转载地址:https://blog.csdn.net/kyjl888/article/details/72942209 1 ORB-SLAM2源码详解 by 吴博 2 https://github.c ...
- vue 源码详解(一):原型对象和全局 `API`的设计
vue 源码详解(一):原型对象和全局 API的设计 1. 从 new Vue() 开始 我们在实际的项目中使用 Vue 的时候 , 一般都是在 main.js 中通过 new Vue({el : ' ...
- vue 源码详解(二): 组件生命周期初始化、事件系统初始化
vue 源码详解(二): 组件生命周期初始化.事件系统初始化 上一篇文章 生成 Vue 实例前的准备工作 讲解了实例化前的准备工作, 接下来我们继续看, 我们调用 new Vue() 的时候, 其内部 ...
随机推荐
- MYSQL查看数据表最后更新时间
MYSQL查看数据表最后更新时间 - 拨云见日 - CSDN博客 https://blog.csdn.net/warnerwu/article/details/73352774 mysql> S ...
- Kafka Consumer接口
对于kafka的consumer接口,提供两种版本, high-level 一种high-level版本,比较简单不用关心offset, 会自动的读zookeeper中该Consumer grou ...
- laydate设置起始时间,laydate设置开始时间和结束时间
//设置开始时间 var startDate = laydate.render({ elem: '#start_date',//开始时间选择控件id min:'2018-6-1', type: 'da ...
- scrapy之定制命令
单爬虫运行 import sys from scrapy.cmdline import execute if __name__ == '__main__': execute(["scrapy ...
- mysql 数据操作 单表查询 having 过滤 练习
1. 查询各岗位内包含的员工个数小于2的岗位名.岗位内包含员工名字.个数 mysql> select post,group_concat(name),count(id) from employe ...
- python使用set来去重碰到TypeError: unhashable type
新版:Python 的 unhashable type 错误分析及解决 python使用set来去重是一种常用的方法. 一般使用方法如下: # int a = [1, 2, 3, 4, 5, 1, 2 ...
- 反射获取成员方法(Method)
1.1.1 反射公开的非静态的成员方法 Method getDeclaredMethod(String name,Class ... parameterTypes)获取某个方法. 说明: 1)在Cla ...
- Linux笔记 #06# 在VPS上自建Git服务
参考: GitHub Help: Connecting to GitHub with SSH 廖雪峰的官方网站: 搭建Git服务器 菜鸟教程: Git 服务器搭建 1. 安装记录(可能有错...) 本 ...
- poj3071 Football(概率dp)
poj3071 Football 题意:有2^n支球队比赛,每次和相邻的球队踢,两两淘汰,给定任意两支球队相互踢赢的概率,求最后哪只球队最可能夺冠. 我们可以十分显然(大雾)地列出转移方程(设$f[ ...
- MySQL "tinyInt1isBit or tinyint(1)" 相关问题解析
问题描述 tinyInt 的数据类型,在JAVA数据类型 和 MySQL的数据类型转换,要注意存储长度为 1 的情况.查询时,该字段对应的Java类型为Boolean 源数据: 读取后数据: 问题分析 ...