最近在这里看了一篇关于面试的文章《回顾本身三次失败的面试经历》,做者三次倒在了轮播图上。囧,因此我也写个轮播图看看。
此次是用jQuery写的,由于最近一直在研究jQuery插件的写法,因此用jQuery写的,并且我发现,我vue用太多,彻底不熟悉dom操做,之后仍是要多多用用jQuery和原生jscss
献给小白们:jQuery插件开发精品教程,让你的jQuery提高一个台阶html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>slide</title> <script src="http://upcdn.b0.upaiyun.com/libs/jquery/jquery-2.0.2.min.js"></script> <script src="jquery.js"></script> <style> *{ margin:0; padding: 0; } li{ list-style: none; } ul{ display: flex; position: relative; } .contain{ width: 600px; overflow: hidden; position: relative; } ol{ position: absolute; bottom:10px; display: flex; justify-content: center; width: 100%; } ol li{ width: 10px; height: 10px; border-radius: 50%; background-color: #f60; margin:0 2px; } .conActive{ background-color: #fff; } </style> </head> <body> <div id="slide"> <div class="contain"> <ul> <li><img src="img/img11.jpg" alt=""></li> <li><img src="img/img21.jpg" alt=""></li> <li><img src="img/img33.jpg" alt=""></li> <li><img src="img/img39.jpg" alt=""></li> <li><img src="img/img55.jpg" alt=""></li> </ul> </div> </div> <style> $(function() { $(".contain").Slide() }) </style> </body> </html>
首先的插件的大致结构以下vue
;(function($, window, document, undefined) { var pluginName = "Slide", defaults = { }; function Slide(element, options) { this.element = element; this.settings = $.extend({}, defaults, options); this._defaults = defaults; this._name = pluginName; this.version = 'v1.0.0'; this.init(); } Slide.prototype = { init: function() { } }; $.fn[pluginName] = function(options) { this.each(function() { if (!$.data(this, "plugin_" + pluginName)) { $.data(this, "plugin_" + pluginName, new Slide(this, options)); } }); return this; }; })(jQuery, window, document);
接下来就是轮播图的大体逻辑了。jquery
由简入繁的写,第一步是考虑怎么让轮播图动起来git
轮播图在网页上大体是这个样子的,只有一张暴露在视野内,其余的在视野外,用overflow:hidden隐藏就行。
那动起来就很是简单github
$(element).animate({right:index*this.width+'px'}, 1000)//jQuery中animate方法
初始化的话,咱们须要计算整个ul的长度,获取单个li的长度。面试
;(function($, window, document, undefined) { var pluginName = "Slide", defaults = { }; function Slide(element, options) { this.element = element; this.width = $(this.element).find('ul li img')[0].width;//图片宽度 this.length = $(this.element).find('ul li').length//轮播数量 this.settings = $.extend({}, defaults, options); this._defaults = defaults; this._name = pluginName; this.version = 'v1.0.0'; this.init(); } Slide.prototype = { init: function() { let index=1//索引 const content = $(this.element).find('ul');//获取ul content.css('width',this.width*this.length);//计算长度 this.autoplay(content,index) }, autoplay: function(content,index) { const _this=this; timer=setInterval(function(){ $(content).animate({right:index*this.width+'px'}, 1000) index++ },2000) } }; $.fn[pluginName] = function(options) { this.each(function() { if (!$.data(this, "plugin_" + pluginName)) { $.data(this, "plugin_" + pluginName, new Slide(this, options)); } }); return this; }; })(jQuery, window, document);
到这里,轮播图已经在一张图一张图的往右跑了,轮播图的逻辑就这么多。可是别人的轮播图都会回头啊,这个轮播图跑着跑着白屏了。接下来就让他回头,利用声明的index实现。app
;(function($, window, document, undefined) { var pluginName = "Slide", defaults = { }; function Slide(element, options) { this.element = element; this.width = $(this.element).find('ul li img')[0].width;//图片宽度 this.length = $(this.element).find('ul li').length//轮播数量 this.settings = $.extend({}, defaults, options); this._defaults = defaults; this._name = pluginName; this.version = 'v1.0.0'; this.init(); } Slide.prototype = { init: function() { let index=1//索引 const content = $(this.element).find('ul');//获取ul content.css('width',this.width*this.length);//计算长度 this.autoplay(content,index) }, autoplay: function(content,index) { const _this=this; timer=setInterval(function(){ $(content).animate({right:index*this.width+'px'}, 1000) index===this.length-1?index=0:index++//若是索引到了this.length-1,说明到了最后一张图片,咱们将index调为0,下一次运行时,ul的样式就会归位,这样就成功回头 },2000) } }; $.fn[pluginName] = function(options) { this.each(function() { if (!$.data(this, "plugin_" + pluginName)) { $.data(this, "plugin_" + pluginName, new Slide(this, options)); } }); return this; }; })(jQuery, window, document);
这边已经实现了一个像模像样的轮播图了,但在尾->首切换的时候违和感太严重了,咱们须要的是平滑过渡,曾经我绞尽脑汁想不出办法,而后花了半分钟上网搜索到了答案,下次不再瞎想了。dom
如上图,在轮播图最后复制一个轮播图第一张,当划到最后一个slide1时,再当即将ul位置复原,切换到第一个slide1,咱们觉得划到了第一个slide1,这样就能实现平滑的过渡。jquery插件
;(function($, window, document, undefined) { var pluginName = "Slide", defaults = { }; function Slide(element, options) { this.element = element; this.width = $(this.element).find('ul li img')[0].width;//图片宽度 this.length = $(this.element).find('ul li').length//轮播数量 this.settings = $.extend({}, defaults, options); this._defaults = defaults; this._name = pluginName; this.version = 'v1.0.0'; this.init(); } Slide.prototype = { init: function() { let index=1//索引 const content = $(this.element).find('ul');//获取ul content.css('width',this.width*this.length);//计算长度 this.autoplay(content,index) }, autoplay: function(content,index) { const _this=this; timer=setInterval(function(){ $(content).animate({right:index*_this.width+'px'}, 1000) if(index===_this.length){ $(content).animate({right:0+'px'}, 0)//将ul回复到原位 index=1//index重置为1(这里是1,恢复到函数刚开始的索引) }else{ index++ } },2000) }, creat: function(){ $($(this.element).find('ul li')[0]).clone().appendTo($(this.element).find('ul')) },//克隆第一个li再添加到ul }; $.fn[pluginName] = function(options) { this.each(function() { if (!$.data(this, "plugin_" + pluginName)) { $.data(this, "plugin_" + pluginName, new Slide(this, options)); } }); return this; }; })(jQuery, window, document);
好的,完整版的轮播图就完成了,若是对轮播图没有任何须要,大体就是这样了。但咱们网站中的轮播图多种多样,用过插件的小伙伴也知道,不少轮播图能自定义参数来开启不一样的功能,例如强大的swiper插件。接下来咱们就来实现一些自定义的功能。
自定义参数:轮播间隔时间,轮播分页小点
;(function($, window, document, undefined) { var pluginName = "Slide", defaults = {//默认参数 pagination:true,//默认开启轮播分页小点 interval:2000//默认间隔时间2s };//这里不明白的小白朋友们麻烦去通读上面推荐的jquery插件的写法,就会明白 function Slide(element, options) { this.element = element; this.width = $(this.element).find('ul li img')[0].width;//图片宽度 this.length = $(this.element).find('ul li').length//轮播数量 this.settings = $.extend({}, defaults, options); this._defaults = defaults; this._name = pluginName; this.version = 'v1.0.0'; this.init(); } Slide.prototype = { init: function() { let index=1; this.creat(); this.settings.pagination?this.pagination():''//若是设置了pagination:true,建立小点 this.addStyle(0)//给第一个小点添加样式 const content = $(this.element).find('ul');//获取ul content.css('width',this.width*this.length);//计算长度 this.autoplay(content,index) }, autoplay: function(content,index) { const _this=this timer=setInterval(function(){ console.log(index*this.width) $(content).animate({right:index*_this.width+'px'}, 1000) if(index===_this.length){ $(content).animate({right:0+'px'}, 0) index=1 }else{ index++ } _this.addStyle(index-1)//index变化,致使小点样式变化 },this.settings.ininterval)//将自定义时间传入 }, creat: function(){ $($(this.element).find('ul li')[0]).clone().appendTo($(this.element).find('ul')) }, pagination: function(index){ let ol="<ol></ol>" $(this.element).append(ol) let li="<li></li>" for(i=1;i<this.length;i++){ $(this.element).find('ol').append(li) }//建立分页小点 }, addStyle: function(index){ let active=$(this.element).find('ul li')[index] $(active).addClass('active').siblings().removeClass('active') if(this.settings.pagination){ let conActive=$(this.element).find('ol li')[index] $(conActive).addClass('conActive').siblings().removeClass('conActive') } }//给活动的轮播图和小点添加样式 }; $.fn[pluginName] = function(options) { this.each(function() { if (!$.data(this, "plugin_" + pluginName)) { $.data(this, "plugin_" + pluginName, new Slide(this, options)); } }); return this; }; })(jQuery, window, document);
接下来就是改变下调用
$(function() { $(".contain").Slide({ pagination:false, interval:5000 }) })
这里就起做用了。
若是再有其余的功能,只须要往里面一步一步添加函数就能够了,好比前进后退按钮,好比一次滚动多张图片。
之因此要本身写一写这些小demo,是为了有助于咱们更好的使用别人的代码。并非全部人写的代码或者插件都适合小白使用,好比better-scroll,这是一个vue的滚动插件,大多数人使用了以后发现滚动不了,去做者github提issue,实际上是他们并不懂滚动的原理。我以前也是摸索了做者的实例才成功使用的,但这个插件并不仅是滚动,还有其余应用,好比手机端联系人列表插件,我彻底搞不懂这是怎么实现的,天然也使用不起来。最近我就用vue本身实现了一个手机端联系人列表,很是很是之简单,一个函数搞定,难点在于html的合理布局,因此没有发到这里,有兴趣的小伙伴能够去github看下。
知其然,更要知其因此然。这样才能慢慢进步,不然只能靠搬运插件混生活了。