最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

原生JS實現(xiàn)旋轉(zhuǎn)木馬式圖片輪播插件

 更新時間:2021年10月12日 15:10:41   作者:小蚊  
這篇文章主要介紹了原生JS實現(xiàn)旋轉(zhuǎn)木馬式圖片輪播插件的相關(guān)資料,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本人自己寫過三個圖片輪播,一個是簡單的原生JS實現(xiàn)的,沒有什么動畫效果的,一個是結(jié)合JQuery實現(xiàn)的,淡入淡出切換的?,F(xiàn)在想做一個酷一點的放在博客或者個人網(wǎng)站,到時候可以展示自己的作品。逛了一下慕課網(wǎng),發(fā)現(xiàn)有個旋轉(zhuǎn)木馬的jquery插件課程,有點酷酷的,于是就想著用原生JS封裝出來。做起來才發(fā)現(xiàn),沒有自己想象中的那么容易。。。不啰嗦了,講解一下實現(xiàn)過程吧。

效果

由于自己的服務(wù)器還沒弄好。在線演示不了(ORZ...),只能放一張效果圖了。

 

從圖片上還是可以看出大概效果的,我就不多說了。想看真實代碼效果的,歡迎到我的github上面download代碼,別忘了給我的github項目點個星星噢^_^

實現(xiàn)過程

html結(jié)構(gòu)

<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/1.jpg"></a>
  </li>
  <li class="carrousel-item">
  <a href="#"><img src="img/2.jpg"></a>
  </li>
  <li class="carrousel-item">
  <a href="#"><img src="img/3.jpg"></a>
  </li>
  <li class="carrousel-item">
  <a href="#"><img src="img/4.jpg"></a>
  </li>
  <li class="carrousel-item">
  <a href="#"><img src="img/5.jpg"></a>
 </ul>
 <div class="carrousel-btn carrousel-btn-next"></div>
 </div> 

這個結(jié)構(gòu)和一般輪播的html代碼結(jié)構(gòu)是一樣的,稍有不同就是,主輪播div上面有一個data-setting的屬性,這個屬性里面就是一些輪播效果的參數(shù)。參數(shù)的具體意義稍后再講解。

css部分的代碼就不貼了,最重要就是要注意元素的絕對定位,由效果圖可以看出來,每張圖片的位置、大小都不一樣,所以這些都是通過js控制的,因此需要絕對定位。下面重點講一下js實現(xiàn)過程。

JS實現(xiàn)過程

下面講幾個JS的關(guān)鍵步驟,做好了這幾個步驟之后,應(yīng)該就沒有什么難點了。

①默認參數(shù)

既然是封裝插件,那么肯定會有一些參數(shù)的默認值需要配置的啦。這個插件中,主要有如下參數(shù):
width:1000,  //幻燈片區(qū)域的寬度
height:400,  //幻燈片區(qū)域的高度
carrouselWidth:700, //幻燈片第一幀的寬度
carrouselHeight:400, //幻燈片第一幀的高度
scale:0.9,//記錄顯示比例關(guān)系,例如第二張圖比第一張圖顯示的時候?qū)捀咝《嗌?br /> autoPlay:true,//是否自動播放
timeSpan:3000,//自動播放時間間隔
verticalAlign:'middle'  //圖片對齊方式,有top\middle\bottom三種方式,默認為middle 

②封裝對象

因為一個網(wǎng)站可能有多個地方都會用到同一個輪播插件,所以封裝很關(guān)鍵。定義了這個對象之后,如果給對象定義一個初始化方法是可以創(chuàng)建多個對象的,只需要把所有類相同的dom傳進去就可以了。所以,我的初始化方法如下:

Carousel.init=function(carrousels){
 var _this=this;
 //將nodeList轉(zhuǎn)換為數(shù)組
 var cals= toArray(carrousels); <br> /*因為原生JS獲取所有的類,得到的是一個nodeList,是一個類數(shù)組,如果想要使用數(shù)組的方法則需要轉(zhuǎn)化為真正的數(shù)組。這里toArray為轉(zhuǎn)化方法。*/
 cals.forEach(function(item,index,array){
 new _this(item);
 });
 }

這樣的話,我在window.onload的時候,調(diào)用Carrousel.init(document.querySelectorAll('.carrousel-main'));這樣就可以創(chuàng)建多個輪播啦!

③初始化好第一幀的位置參數(shù)

因為,第一幀之后的所有幀的相關(guān)參數(shù)都是參照第一幀來定義的,因此,定義好第一幀很關(guān)鍵。

setValue:function(){
this.carrousel.style.width=this.Settings.width+'px';
this.carrousel.style.height=this.Settings.height+'px';
 /*左右按鈕設(shè)置,這里要讓左右按鈕平均地瓜分輪播區(qū)域?qū)挏p去第一幀寬度之后的區(qū)域,z-index要比除第一幀外所有圖片都高,而圖片剛好左右分放置,因此z-index的值就是圖片數(shù)量的一半。*/
 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);
 //第一幀相關(guān)設(shè)置
 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);
},

這里,就是new對象的時候,就到dom結(jié)點中獲取data-setting參數(shù),然后更新默認參數(shù)配置。這里有個地方需要注意的,獲取dom的參數(shù)不能直接以賦值的方式更新默認參數(shù),因為用戶配置參數(shù)的時候,不一定會所有參數(shù)都配置一次。如果直接賦值而用戶剛好不是所有參數(shù)都配置的話就會造成參數(shù)丟失。這里我是自己寫了一個類似JQuery中的$.extend方法的對象擴展方法來更新參數(shù)的。具體就不列舉了,感興趣的可以去下載。

 ④其他圖片位置設(shè)置

這里的圖片實際上就是把除第一張之外的圖片,平均地分到左右兩則,而左邊的圖片位置和右邊的是不同的,因此需要分別配置:

//設(shè)置右邊圖片的位置關(guān)系
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的值越小,可以用圖片數(shù)量的一般逐漸遞減
 item.style.width=rw+'px';
 item.style.height=rh+'px';
 item.style.opacity=1/(++i);//越往右邊透明度越小<br>  //這里的gap計算方法為:輪播區(qū)域減去第一幀寬度,除2,再除左邊或者右邊的圖片張數(shù)
 item.style.left=(constOffset+(++index)*gap-rw)+'px';//left的值實際上就是第一幀的left+第一幀的寬度+item的間距減去item的寬度
 item.style.top=carrouselSelf.setCarrouselAlign(rh)+'px';
});

左邊的設(shè)置方法類似且更為簡單,就不細說了。

⑤旋轉(zhuǎn)時所有圖片的位置大小調(diào)整

這一步很關(guān)鍵,點擊右邊按鈕下一張的即為左旋轉(zhuǎn),而點擊左邊按鈕上一張即為右旋轉(zhuǎn)。此時,我們只需要把所有的圖片看成一個環(huán)形那樣,點擊一次,換一次位置即完成旋轉(zhuǎn)。具體為左旋轉(zhuǎn)的時候,令第二張的參數(shù)等于第一張,第三張等于第二張...而最后一張等于第一張即可。右旋轉(zhuǎn)的時候,令第一張的參數(shù)等于第二張,第二張的參數(shù)等于第三張...而最后一張的參數(shù)等于第一張即可。

這里就說說左旋轉(zhuǎn)吧

if(dir=='left'){
 toArray(this.carrouselItems).forEach(function(item,index,array){
 var pre;
 if(index==0){//判斷是否為第一張
  pre=_this.carrouselLat;//讓第一張的pre等于最后一張
  var width=pre.offsetWidth; //獲取相應(yīng)參數(shù)
  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;
 }
  //這里需要注意,因為第二張圖片是參照第一張的,而這樣改變的時候,第一張是首先被改變的,因此必須先把第一張的相關(guān)參數(shù)臨時保存起來。
 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動畫函數(shù)
  _this.rotateFlag=true;
  });
 });
}

這里的旋轉(zhuǎn),如果不使用一些動畫過度,會顯得很生硬。但是原生JS并沒有動畫函數(shù),這里我是自己寫了一個模仿的動畫函數(shù)。其原理就是獲取dom原來的樣式值,與新傳入的值比較。用一些方法定義一個速度。我這里的速度就是用其差值除18.然定義一個計時器,參考了一下jquery源碼里面的時間間隔為每13毫秒執(zhí)行一次。然后才原來的樣式值每次加上speed后等于傳入的值的時候清楚計時器即可。具體可以看這里。

好啦,關(guān)鍵的地方都差不多啦,如果明白這些過程應(yīng)該就很容易了!

四、總結(jié)思考

總結(jié):

個人感覺這還是一個比較好理解的插件。如果能結(jié)合JQuery來做就相當簡單了。但是用原生來寫的話,還是有一些不那么流暢的感覺。應(yīng)該是自定義動畫比不上JQuery封裝好的動畫吧。

還有,這個插件因為圖片需要平均分到左右兩邊,于是對于偶數(shù)數(shù)量的圖片來說,這里用的方法是克隆第一張,然后加到最后,形成一個奇數(shù)。

思考:

如果說有bug的話,那就是我定義了一個rotateFlag的標志去判斷當前能否旋轉(zhuǎn),就是預(yù)防快速點擊的時候跟不上。我在按下的時候把rotateFlag設(shè)置為false,然后在動畫結(jié)束后再把rotateFlag設(shè)置為true,但是好像作用并不明顯,希望有關(guān)大神可以指教一下,大家共同進步。

以上就是本文的全部內(nèi)容,更多內(nèi)容請參考:javascript圖片輪播效果匯總 ,謝謝大家的閱讀。

相關(guān)文章

  • JS實現(xiàn)從對象獲取對象中單個鍵值的方法示例

    JS實現(xiàn)從對象獲取對象中單個鍵值的方法示例

    這篇文章主要介紹了JS實現(xiàn)從對象獲取對象中單個鍵值的方法,涉及javascript數(shù)組對象遍歷、事件監(jiān)聽、處理等相關(guān)操作技巧,需要的朋友可以參考下
    2019-06-06
  • 微信小程序?qū)崿F(xiàn)照片裁剪

    微信小程序?qū)崿F(xiàn)照片裁剪

    這篇文章主要為大家詳細介紹了微信小程序?qū)崿F(xiàn)照片裁剪,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • JS?簡單實現(xiàn)拖拽評星的示例代碼

    JS?簡單實現(xiàn)拖拽評星的示例代碼

    本文主要介紹了JS?簡單實現(xiàn)拖拽評星,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • 簡介EasyUI datagrid editor combogrid搜索框的實現(xiàn)

    簡介EasyUI datagrid editor combogrid搜索框的實現(xiàn)

    這篇文章主要介紹了EasyUI datagrid editor combogrid搜索框的實現(xiàn),涉及到EasyUI中combogrid的使用方法的相關(guān)知識,非常具有參考價值,需要的朋友可以參考下
    2016-04-04
  • JS判斷是否在微信瀏覽器打開的簡單實例(推薦)

    JS判斷是否在微信瀏覽器打開的簡單實例(推薦)

    下面小編就為大家?guī)硪黄狫S判斷是否在微信瀏覽器打開的簡單實例(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-08-08
  • JavaScript中第三方庫Apollo的使用詳解

    JavaScript中第三方庫Apollo的使用詳解

    Apollo 是一個廣泛使用的 JavaScript 第三方庫,主要用于構(gòu)建與 GraphQL API 交互的應(yīng)用程序,下面就跟隨小編一起來學(xué)習(xí)一下它的具體應(yīng)用吧
    2024-02-02
  • js實現(xiàn)的星星評分功能函數(shù)

    js實現(xiàn)的星星評分功能函數(shù)

    這篇文章主要介紹了js實現(xiàn)的星星評分功能函數(shù),涉及JavaScript響應(yīng)鼠標事件實現(xiàn)針對頁面元素的遍歷與樣式屬性的修改技巧,非常簡單實用的代碼,需要的朋友可以參考下
    2015-12-12
  • JS?解決Cannot?set?properties?of?undefined的問題

    JS?解決Cannot?set?properties?of?undefined的問題

    遇到這樣問題當前的是當前對象或者數(shù)組是undefined,但是卻用來引用屬性或者索引,遇到這樣的問題如何解決呢,下面通過本文給大家介紹JS?如何解決Cannot?set?properties?of?undefined,需要的朋友可以參考下
    2024-01-01
  • webpack構(gòu)建打包的性能優(yōu)化實戰(zhàn)指南

    webpack構(gòu)建打包的性能優(yōu)化實戰(zhàn)指南

    webpack是前端開發(fā)中比較常用的打包工具之一,另外還有g(shù)ulp,grunt,下面這篇文章主要給大家介紹了關(guān)于webpack構(gòu)建打包的性能優(yōu)化的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-03-03
  • js replace(a,b)之替換字符串中所有指定字符的方法

    js replace(a,b)之替換字符串中所有指定字符的方法

    下面小編就為大家?guī)硪黄猨s replace(a,b)之替換字符串中所有指定字符的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-08-08

最新評論

察雅县| 图们市| 西安市| 甘孜县| 鄯善县| 乐业县| 昆明市| 奉化市| 台州市| 德令哈市| 泰来县| 三门县| 永定县| 鄂温| 屏南县| 安图县| 于田县| 临沭县| 黄梅县| 津市市| 承德县| 正宁县| 宜君县| 清镇市| 延吉市| 柞水县| 灵川县| 浏阳市| 永寿县| 高要市| 托克逊县| 武鸣县| 沭阳县| 双江| 夹江县| 鄱阳县| 石泉县| 德化县| 维西| 武冈市| 任丘市|