昨天,自己心血来潮,弄了一个轮播图的插件,说来你们可能不信,这是我人生第一个插件,好,那我直接讲讲我的思路好了。
首先,我以开发者的角度来看,一个好的插件的使用方式应该简单可靠,因为我做的是Jquery插件,所以最好的使用方式我觉得应该是,$(DOM).carousel(config)。其中DOM节点,用于填充轮播图片的地方,config是配置信息,包括是否循环,是否自动播放,播放时间间隔,图片地址等。因为时间短,我也只是简单实现了主要的功能。
我第一件事情做的就是布局,没错,我是先把CSS样式以及布局写好的。布局简单的说就是要让所有图片在同一行显示,溢出的用overflow:hidden隐藏。我是这么做的,有一个div叫carousel,它的大小是和开发者提供的地方大小一样,也就是width: 100%,height:100%。并且要设置overflow:hidden。接着里面就放一个div叫carousel-content。这里面就是放图片的,它的高度是占满carousel的,但是它的宽度应该是所有图片宽度的总和,这是用js设置的。而所有图片都应该是float:left,这是为了让它们并行显示。
我做的第二件事就是动画,因为我的布局不是position,所以我是用margin-left来实现位移的,margin-left:-图片宽度就能让第二张图片移动到carousel中。动画是使用jquery的animate函数。有关animate函数的使用详细的我就不说了,我只说我有用到的,animate(style,time,callback),这里的style是指最终样式,time是动画时长,callback是执行动画完后的回调函数。我只要对carousel-content做动画就可以了。
最后一件事就是开始设计js插件了。之前我们插件的使用方式已经有了,就是$(DOM).carousel(config)。所以我的代码如下所示
(function (w,$) { $.fn.carousel = function (config) { config = config || {}; var _config = { circle: config.circle || true, // 是否循环 auto: config.auto || true, // 是否自动轮播 speed: config.speed || 1000, // 轮播动画速度 interval: 1500, // 轮播间隔 }, _imgUrls = config.imgUrls || [], // 图片地址 _index = 0, // 当前图片 _carouselContent = null, // 生成的DOM节点 _carouselImgs = [], // 生成的图片DOM节点 _carouselIcons = [], _element = this[0], _intervalId = null; _config.interval += _config.speed; // 初始化 var _init = function () { var carousel = document.createElement("div"); carousel.className = "carousel"; // 设置图片hover事件,停止动画 carousel.onmouseenter = function () { if (_intervalId) { clearInterval(_intervalId) } } // 设置鼠标离开事件,开始动画 carousel.onmouseleave = function () { _setAnimate(); } _element.appendChild(carousel); var carouselContent = document.createElement("div"), img, icon; // 创建img for (var i = 0, len = _imgUrls.length; i < len; i++) { img = document.createElement("img"); img.src = _imgUrls[i]; img.className = "carousel-img"; img.width = carousel.offsetWidth; img.height = carousel.offsetHeight; carouselContent.appendChild(img); _carouselImgs.push(img); } // 创建圆形按钮 var icons = document.createElement("div"); for (var i = 0, len = _imgUrls.length; i < len; i++) { icon = document.createElement("div"); icon.className = "carousel-icon"; icons.appendChild(icon); if (i == 0) { icon.style.marginLeft = 0; icon.style.backgroundColor = "#E3E3E3"; } (function (i) { icon.onclick = function () { _index = i; _animateAction(); } })(i); _carouselIcons.push(icon); } carousel.appendChild(icons); icons.style.position = "absolute"; icons.style.bottom = "30px"; icons.style.left = "50%"; icons.style.marginLeft = -icons.offsetWidth/2+"px"; // 创建上一张和下一张按钮 var lt = document.createElement("span"), gt = document.createElement("span"); lt.className = "carousel-lt"; gt.className = "carousel-gt"; lt.innerText = "<"; gt.innerText = ">"; lt.style.lineHeight = carousel.offsetHeight + "px"; gt.style.lineHeight = carousel.offsetHeight + "px"; lt.onclick = function () { if (_index == 0) { _index = _imgUrls.length - 1; } else { _index--; } _animateAction(); } gt.onclick = function () { if (_index == _imgUrls.length - 1) { _index = 0; } else { _index++; } _animateAction(); } carousel.appendChild(lt); carousel.appendChild(gt); carouselContent.style.width = carousel.offsetWidth * len + "px"; carousel.appendChild(carouselContent); _carouselContent = carouselContent; _setAnimate(); // 窗口变化时的适配 w.onresize = function () { $(_carouselContent).stop(); _carouselContent.style.marginLeft = -(carousel.offsetWidth) * _index + "px" _carouselContent.style.width = carousel.offsetWidth * _carouselImgs.length + "px"; for (var i = 0, len = _carouselImgs.length; i < len; i++) { _carouselImgs[i].width = carousel.offsetWidth; _carouselImgs[i].height = carousel.offsetHeight; } } }, // 设置动画 _setAnimate = function () { // 自动播放 if (_config.auto) { _intervalId = setInterval(function () { // 最后一张图片 if (_index == _imgUrls.length - 1) { // 是否循环 if (_config.circle) { // 回到第一张 _index = 0; for (var i = 0, len = _carouselImgs.length; i < len; i++) { _carouselImgs[i].style.marginLeft = 0; } } else { clearInterval(_intervalId); } } else { _index++; } // 开始动画 _animateAction(); }, _config.interval) } }, // 开始动画 _animateAction = function () { for (var i = 0, len = _carouselIcons.length; i < len; i++) { _carouselIcons[i].style.backgroundColor = "#000"; } _carouselIcons[_index].style.backgroundColor = "#E3E3E3"; $(_carouselContent).animate({ marginLeft: -(_element.offsetWidth) * _index + "px" }, _config.speed); } _init(); } }) (window,jQuery)
上面最主要的代码是_init,_setAnimate,_animateAction这三个函数,_init函数是把生成DOM节点树,然后插入用户指定的地方。_setAnimate是设置动画,其实就是改变_index这个值。这个值是表示当前是到第几张图片,0表示第一张。_animateAction是设置动画,根据_index值使用animate设置动画。
好了,这只是很简单的轮播代码,下面是html代码
<!DOCTYPE html> <html> <head> <title></title> <style type="text/css"> .carousel { width: 100%; height: 100%; overflow: hidden; position: relative; } .carousel-img { float: left; } .carousel-lt { position: absolute; top: 0; left: 0; width: 30px; height: 100%; text-align: center; font-size: 30px; color: #E3E3E3; cursor: pointer; } .carousel-lt:hover { background: #000; } .carousel-gt { position: absolute; top: 0; right: 0; width: 30px; height: 100%; text-align: center; font-size: 30px; color: #E3E3E3; cursor: pointer; } .carousel-gt:hover { background: #000; } .carousel-icon { width: 20px; height: 20px; background-color: #000; display: inline-block; vertical-align: middle; border-radius: 50%; margin-left: 10px; cursor: pointer; } .active { background-color: #E3E3E3; } </style> </head> <body> <div id="content" style="width: 100%; height: 500px"> </div> <script type="text/javascript" src="./jquery.min.js"></script> <script type="text/javascript" src="./carousel.js"></script> <script type="text/javascript"> $(document.getElementById("content")).carousel({ imgUrls: [‘./2.jpg‘,‘./3.jpg‘,‘./4.jpg‘,‘./5.jpg‘] }); </script> </body> </html>