Home >Web Front-end >JS Tutorial >Native JS implements carousel-style image carousel plug-in

Native JS implements carousel-style image carousel plug-in

PHPz
PHPzOriginal
2016-05-16 15:04:002858browse

I have written three image carousels myself, one is implemented with simple native JS without any animation effects, and the other is implemented with JQuery and switches between fade-ins and fade-outs. Now I want to make a cooler one and put it on my blog or personal website so that I can showcase my work. I browsed the MOOC website and found a carousel jquery plug-in course, which was a bit cool, so I thought about encapsulating it with native JS. Only when I started doing it did I realize that it was not as easy as I thought. . . Without further ado, let’s explain the implementation process.

2. Effect

Because my server has not been completed yet. There is no online demonstration (ORZ...), so I can only put a rendering.

Native JS implements carousel-style image carousel plug-in

You can still see the approximate effect from the picture, so I won’t say more. If you want to see the real code effect, you are welcome to download the code on my github. Don’t forget to give a star to my github project ^_^

3. Implementation process

html structure

<div class="carrousel-main" data-setting=&#39;{"width":1000,"height":400,
 "carrouselWidth":750,
 "carrouselHeight":400,
 "scale":0.9,
 "verticalAlign":"middle"}&#39;>
 <div class="carrousel-btn carrousel-btn-pre"></div>
 <ul class="carrousel-list">
  <li class="carrousel-item">
  <a href="#"><img  src="img/Native JS implements carousel-style image carousel plug-in" alt="Native JS implements carousel-style image carousel plug-in" ></a>
  </li>
  <li class="carrousel-item">
  <a href="#"><img  src="img/2.jpg" alt="Native JS implements carousel-style image carousel plug-in" ></a>
  </li>
  <li class="carrousel-item">
  <a href="#"><img  src="img/3.jpg" alt="Native JS implements carousel-style image carousel plug-in" ></a>
  </li>
  <li class="carrousel-item">
  <a href="#"><img  src="img/4.jpg" alt="Native JS implements carousel-style image carousel plug-in" ></a>
  </li>
  <li class="carrousel-item">
  <a href="#"><img  src="img/5.jpg" alt="Native JS implements carousel-style image carousel plug-in" ></a>
 </ul>
 <div class="carrousel-btn carrousel-btn-next"></div>
 </div>

This structure is the same as the html code structure of the general carousel. The slight difference is that the main carousel div has a data-setting attribute on it. This Among the properties are some parameters of the carousel effect. The specific meaning of the parameters will be explained later.

I won’t post the code for the css part. The most important thing is to pay attention to the absolute positioning of the elements. As you can see from the renderings, the position and size of each picture are different, so these are controlled through js , so absolute positioning is required. The following focuses on the js implementation process.

JS implementation process

Let’s talk about a few key steps of JS. After completing these steps, there should be no difficulties.

①Default parameters

Since it is a package plug-in, there will definitely be some default values ​​of parameters that need to be configured. In this plug-in, the main parameters are as follows:
width:1000, //The width of the slide area
height:400, //The height of the slide area
carrouselWidth:700, //The first slide Frame width
carrouselHeight:400, //Height of the first frame of the slide
scale:0.9,//Record the display proportion relationship, for example, how much smaller the width and height of the second picture are compared to the first picture.
autoPlay:true,//Whether to automatically play
timeSpan:3000,//Auto play time interval
verticalAlign:'middle' //Picture alignment, there are three ways: topmiddlebottom, the default is middle

②Encapsulation object

Because a website may use the same carousel plug-in in multiple places, encapsulation is critical. After defining this object, if you define an initialization method for the object, you can create multiple objects. You only need to pass in the DOM of the same class for all classes. So, my initialization method is as follows:

Carousel.init=function(carrousels){
 var _this=this;
 //将nodeList转换为数组
 var cals= toArray(carrousels); <br> /*因为原生JS获取所有的类,得到的是一个nodeList,是一个类数组,如果想要使用数组的方法则需要转化为真正的数组。这里toArray为转化方法。*/
 cals.forEach(function(item,index,array){
 new _this(item);
 });
 }

In this case, when I am in window.onload, call Carrousel.init(document.querySelectorAll('.carrousel-main')); like this You can create multiple carousels!

③Initialize the position parameters of the first frame

Because the relevant parameters of all frames after the first frame refer to the first frame It is defined by frames, so it is critical to define the first frame well.

setValue:function(){
this.carrousel.style.width=this.Settings.width+&#39;px&#39;;
this.carrousel.style.height=this.Settings.height+&#39;px&#39;;
 /*左右按钮设置,这里要让左右按钮平均地瓜分轮播区域宽减去第一帧宽度之后的区域,z-index要比除第一帧外所有图片都高,而图片刚好左右分放置,因此z-index的值就是图片数量的一半。*/
 var btnW=(this.Settings.width-this.Settings.carrouselWidth)/2;
 this.preBtn.style.width=btnW+&#39;px&#39;;
 this.preBtn.style.height=this.Settings.height+&#39;px&#39;;
 this.preBtn.style.zIndex=Math.ceil(this.carrouselItems.length/2);
 
 this.nextBtn.style.width=btnW+&#39;px&#39;;
 this.nextBtn.style.height=this.Settings.height+&#39;px&#39;;
 this.nextBtn.style.zIndex=Math.ceil(this.carrouselItems.length/2);
 //第一帧相关设置
 this.carrouselFir.style.left=btnW+&#39;px&#39;;
 this.carrouselFir.style.top=this.setCarrouselAlign(this.Settings.carrouselHeight)+&#39;px&#39;;
 this.carrouselFir.style.width=this.Settings.carrouselWidth+&#39;px&#39;;
 this.carrouselFir.style.height=this.Settings.carrouselHeight+&#39;px&#39;;
 this.carrouselFir.style.zIndex=Math.floor(this.carrouselItems.length/2);
},

Here, when it comes to the new object, go to the dom node to get the data-setting parameters, and then update the default parameter configuration. There is something to note here. Obtaining the dom parameters cannot directly update the default parameters by assigning values, because when the user configures the parameters, all parameters may not be configured once. If values ​​are assigned directly and the user does not configure all parameters, the parameters will be lost. Here I wrote an object extension method similar to the $.extend method in JQuery to update the parameters. I won’t list them specifically, but those who are interested can download them.

④Other picture position settings

The pictures here are actually dividing the pictures except the first one evenly to the left and right Two, and the picture position on the left is different from that on the right, so they need to be configured separately:

//设置右边图片的位置关系
var rightIndex=level;
rightSlice.forEach(function(item,index,array){
 rightIndex--;
 var i=index;
 rw=rw*carrouselSelf.Settings.scale;//右边的图片是按照scale比例逐渐变小的
 rh=rh*carrouselSelf.Settings.scale;
 
 item.style.zIndex=rightIndex;//越往右边z-index的值越小,可以用图片数量的一般逐渐递减
 item.style.width=rw+&#39;px&#39;;
 item.style.height=rh+&#39;px&#39;;
 item.style.opacity=1/(++i);//越往右边透明度越小<br>  //这里的gap计算方法为:轮播区域减去第一帧宽度,除2,再除左边或者右边的图片张数
 item.style.left=(constOffset+(++index)*gap-rw)+&#39;px&#39;;//left的值实际上就是第一帧的left+第一帧的宽度+item的间距减去item的宽度
 item.style.top=carrouselSelf.setCarrouselAlign(rh)+&#39;px&#39;;
});

The setting method on the left is similar and simpler, so I won’t go into details.

⑤ Adjust the position and size of all pictures during rotation

This step is very critical. Click the button on the right to rotate the next picture to the left. Click the button on the left to rotate right. At this time, we only need to view all the pictures as a ring, click once, change the position once and complete the rotation. Specifically, when rotating left, make the parameters of the second picture equal to the first picture, the third picture equal to the second picture... and the last picture equal to the first picture. When rotating right, make the parameters of the first picture equal to the second picture, the parameters of the second picture equal to the third picture... and the parameters of the last picture equal the first picture.

这里就说说左旋转吧

if(dir==&#39;left&#39;){
 toArray(this.carrouselItems).forEach(function(item,index,array){
 var pre;
 if(index==0){//判断是否为第一张
  pre=_this.carrouselLat;//让第一张的pre等于最后一张
  var width=pre.offsetWidth; //获取相应参数
  var height=pre.offsetHeight;
  var zIndex=pre.style.zIndex;
  var opa=pre.style.opacity;
  var top=pre.style.top;
  var left=pre.style.left;
 }else{
  var width = tempWidth;
  var height = tempHeight;
  var zIndex = tempZIndex;
  var opa = tempOpacity;
  var top = tempTop;
  var left = tempLeft;
 }
  //这里需要注意,因为第二张图片是参照第一张的,而这样改变的时候,第一张是首先被改变的,因此必须先把第一张的相关参数临时保存起来。
 tempWidth = item.offsetWidth;
 tempHeight = item.offsetHeight;
 tempZIndex = item.style.zIndex;
 tempOpacity = item.style.opacity;
 tempTop = item.style.top;
 tempLeft = item.style.left;
 
 item.style.width=width+&#39;px&#39;;
 item.style.height=height+&#39;px&#39;;
 item.style.zIndex=zIndex;
 item.style.opacity=opa;
 item.style.top=top;
  // item.style.left=left;
  animate(item,&#39;left&#39;,left,function(){//自定义的原生js动画函数
  _this.rotateFlag=true;
  });
 });
}

这里的旋转,如果不使用一些动画过度,会显得很生硬。但是原生JS并没有动画函数,这里我是自己写了一个模仿的动画函数。其原理就是获取dom原来的样式值,与新传入的值比较。用一些方法定义一个速度。我这里的速度就是用其差值除18.然定义一个计时器,参考了一下jquery源码里面的时间间隔为每13毫秒执行一次。然后才原来的样式值每次加上speed后等于传入的值的时候清楚计时器即可。具体可以看这里。

好啦,关键的地方都差不多啦,如果明白这些过程应该就很容易了!

四、总结思考

总结:

个人感觉这还是一个比较好理解的插件。如果能结合JQuery来做就相当简单了。但是用原生来写的话,还是有一些不那么流畅的感觉。应该是自定义动画比不上JQuery封装好的动画吧。

还有,这个插件因为图片需要平均分到左右两边,于是对于偶数数量的图片来说,这里用的方法是克隆第一张,然后加到最后,形成一个奇数。

思考:

如果说有bug的话,那就是我定义了一个rotateFlag的标志去判断当前能否旋转,就是预防快速点击的时候跟不上。我在按下的时候把rotateFlag设置为false,然后在动画结束后再把rotateFlag设置为true,但是好像作用并不明显,希望有关大神可以指教一下,大家共同进步。

更多编程相关知识,请访问:编程入门!!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn