저는 세 개의 이미지 캐러셀을 직접 작성했는데, 하나는 애니메이션 효과 없이 간단한 기본 JS로 구현되었고, 다른 하나는 JQuery로 구현되어 페이드인과 페이드아웃 간을 전환합니다. 이제는 좀 더 멋진 작품을 만들어 블로그나 개인 홈페이지에 올려 작품을 선보이고 싶습니다. MOOC 웹사이트를 둘러보다가 carousel jquery 플러그인 강좌를 발견했는데, 좀 멋있어서 네이티브 JS로 캡슐화할까 생각도 했습니다. 막상 시작하고 나서야 생각보다 쉽지 않다는 걸 깨달았습니다. . . 더 이상 고민하지 않고 구현 프로세스를 설명하겠습니다.
2. 효과
아직 서버가 완성되지 않았기 때문이죠. 온라인 데모(ORZ...)가 없어 렌더링만 넣을 수 있습니다.
사진으로 대략적인 효과를 보실 수 있으니 더 말씀드리지 않겠습니다. 실제 코드 효과를 보려면 내 github 프로젝트에 별표를 표시하는 것을 잊지 마세요. ^_^
3. 🎜>
html 구조<div class="carrousel-main" data-setting='{"width":1000,"height":400, "carrouselWidth":750, "carrouselHeight":400, "scale":0.9, "verticalAlign":"middle"}'> <div class="carrousel-btn carrousel-btn-pre"></div> <ul class="carrousel-list"> <li class="carrousel-item"> <a href="#"><img src="img/네이티브 JS는 캐러셀 스타일 이미지 캐러셀 플러그인을 구현합니다." alt="네이티브 JS는 캐러셀 스타일 이미지 캐러셀 플러그인을 구현합니다." ></a> </li> <li class="carrousel-item"> <a href="#"><img src="img/2.jpg" alt="네이티브 JS는 캐러셀 스타일 이미지 캐러셀 플러그인을 구현합니다." ></a> </li> <li class="carrousel-item"> <a href="#"><img src="img/3.jpg" alt="네이티브 JS는 캐러셀 스타일 이미지 캐러셀 플러그인을 구현합니다." ></a> </li> <li class="carrousel-item"> <a href="#"><img src="img/4.jpg" alt="네이티브 JS는 캐러셀 스타일 이미지 캐러셀 플러그인을 구현합니다." ></a> </li> <li class="carrousel-item"> <a href="#"><img src="img/5.jpg" alt="네이티브 JS는 캐러셀 스타일 이미지 캐러셀 플러그인을 구현합니다." ></a> </ul> <div class="carrousel-btn carrousel-btn-next"></div> </div>
1기본 매개변수
패키지 플러그인이다 보니 반드시 설정해야 할 매개변수의 기본값이 있을 것이다. 구성되었습니다. 이 플러그인에서 주요 매개변수는 다음과 같습니다: width:1000, //슬라이드 영역의 너비
height:400, //슬라이드 영역의 높이
carrouselWidth:700, //첫 번째 슬라이드 프레임 너비
carrouselHeight:400, //슬라이드의 첫 번째 프레임 높이
scale:0.9,//표시 비율 관계를 기록합니다. 예를 들어 슬라이드의 너비와 높이가 얼마나 작은지 기록합니다. 두 번째 사진을 첫 번째 사진과 비교합니다.
autoPlay:true,//자동 재생 여부
timeSpan:3000,//자동 재생 시간 간격
VerticalAlign:'middle' //사진 정렬, 거기 세 가지 방법이 있습니다. topmiddlebottom, 기본값은 중간입니다.
②캡슐화 개체
웹사이트는 여러 위치에서 동일한 캐러셀 플러그인을 사용할 수 있기 때문입니다. , 캡슐화가 중요합니다. 이 객체를 정의한 후 해당 객체에 대한 초기화 방법을 정의하면 여러 객체를 생성할 수 있습니다. 모든 클래스에 대해 동일한 클래스의 DOM만 전달하면 됩니다. 따라서 내 초기화 방법은 다음과 같습니다.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); }); }
③첫 번째 프레임의 위치 매개변수를 초기화
첫 번째 프레임 이후의 모든 프레임의 해당 매개변수는 첫 번째 프레임을 참조하기 때문입니다. 프레임으로 정의되므로 첫 번째 프레임을 잘 정의하는 것이 중요합니다.setValue:function(){ this.carrousel.style.width=this.Settings.width+'px'; this.carrousel.style.height=this.Settings.height+'px'; /*左右按钮设置,这里要让左右按钮平均地瓜分轮播区域宽减去第一帧宽度之后的区域,z-index要比除第一帧外所有图片都高,而图片刚好左右分放置,因此z-index的值就是图片数量的一半。*/ var btnW=(this.Settings.width-this.Settings.carrouselWidth)/2; this.preBtn.style.width=btnW+'px'; this.preBtn.style.height=this.Settings.height+'px'; this.preBtn.style.zIndex=Math.ceil(this.carrouselItems.length/2); this.nextBtn.style.width=btnW+'px'; this.nextBtn.style.height=this.Settings.height+'px'; this.nextBtn.style.zIndex=Math.ceil(this.carrouselItems.length/2); //第一帧相关设置 this.carrouselFir.style.left=btnW+'px'; this.carrouselFir.style.top=this.setCarrouselAlign(this.Settings.carrouselHeight)+'px'; this.carrouselFir.style.width=this.Settings.carrouselWidth+'px'; this.carrouselFir.style.height=this.Settings.carrouselHeight+'px'; this.carrouselFir.style.zIndex=Math.floor(this.carrouselItems.length/2); },
④기타 사진 위치 설정
여기 사진들은 사실 첫 번째 사진을 제외한 사진을 좌우 균등하게 나누어 놓은 사진이 2개이고, 왼쪽 사진 위치가 오른쪽 사진 위치와 다르기 때문에 별도로 구성해야 합니다.//设置右边图片的位置关系 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+'px'; item.style.height=rh+'px'; item.style.opacity=1/(++i);//越往右边透明度越小<br> //这里的gap计算方法为:轮播区域减去第一帧宽度,除2,再除左边或者右边的图片张数 item.style.left=(constOffset+(++index)*gap-rw)+'px';//left的值实际上就是第一帧的left+第一帧的宽度+item的间距减去item的宽度 item.style.top=carrouselSelf.setCarrouselAlign(rh)+'px'; });
⑤ 회전하는 동안 모든 사진의 위치와 크기를 조정하세요
사진을 회전하려면 오른쪽에 있는 버튼을 클릭하는 것이 매우 중요합니다. 왼쪽의 다음 사진을 오른쪽으로 회전하려면 왼쪽에 있는 버튼을 클릭하세요. 이때 모든 사진을 링으로 보고 한 번 클릭하고 위치를 한 번 변경하고 회전을 완료하기만 하면 됩니다. 구체적으로 왼쪽으로 회전할 때 두 번째 사진의 매개변수를 첫 번째 사진과 동일하게 만들고, 세 번째 사진을 두 번째 사진과 동일하게 하고... 마지막 사진을 첫 번째 사진과 동일하게 만듭니다. 오른쪽으로 회전할 때 첫 번째 사진의 매개변수는 두 번째 사진과 같고, 두 번째 사진의 매개변수는 세 번째 사진과 같고... 마지막 사진의 매개변수는 첫 번째 사진과 같습니다.这里就说说左旋转吧
if(dir=='left'){ 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+'px'; item.style.height=height+'px'; item.style.zIndex=zIndex; item.style.opacity=opa; item.style.top=top; // item.style.left=left; animate(item,'left',left,function(){//自定义的原生js动画函数 _this.rotateFlag=true; }); }); }
这里的旋转,如果不使用一些动画过度,会显得很生硬。但是原生JS并没有动画函数,这里我是自己写了一个模仿的动画函数。其原理就是获取dom原来的样式值,与新传入的值比较。用一些方法定义一个速度。我这里的速度就是用其差值除18.然定义一个计时器,参考了一下jquery源码里面的时间间隔为每13毫秒执行一次。然后才原来的样式值每次加上speed后等于传入的值的时候清楚计时器即可。具体可以看这里。
好啦,关键的地方都差不多啦,如果明白这些过程应该就很容易了!
四、总结思考
总结:
个人感觉这还是一个比较好理解的插件。如果能结合JQuery来做就相当简单了。但是用原生来写的话,还是有一些不那么流畅的感觉。应该是自定义动画比不上JQuery封装好的动画吧。
还有,这个插件因为图片需要平均分到左右两边,于是对于偶数数量的图片来说,这里用的方法是克隆第一张,然后加到最后,形成一个奇数。
思考:
如果说有bug的话,那就是我定义了一个rotateFlag的标志去判断当前能否旋转,就是预防快速点击的时候跟不上。我在按下的时候把rotateFlag设置为false,然后在动画结束后再把rotateFlag设置为true,但是好像作用并不明显,希望有关大神可以指教一下,大家共同进步。
更多编程相关知识,请访问:编程入门!!