1. 程式人生 > >JS原生輪播圖實現

JS原生輪播圖實現

作為一個PHP全棧攻城獅,不僅要會後端PHP和資料庫,還要會前端JS。今天原始碼時代 PHP培訓 學科老師要和大家分享一下JS原生編寫輪播圖的外掛。 說起輪播圖,很多人會選擇使用各種外掛,比如基於JQuery或其它框架的。不瞞大家,我也用過,甚至還用過Flash的輪播圖。總體來說,用起來是比較簡單,但是有一個非常嚴重的問題,那就是載入速度非常非常慢。

如果能自己使用JS原生寫一個輪播圖,不僅速度快,那感覺也是高大上,頗有高階前端工程師的feel啊。不過今天為了大家好理解,我們使用面向過程的程式碼編寫(面向過程關注細節,方便理解原理;面向物件使用方便,但不方便新手理解)。

在開始編寫之前我們需要準備幾張測試圖片,以及一些技術基礎:JavaScript、HTML、CSS。為了方便測試,我們約定一下測試環境:三張相同大小的圖片放在images目錄中,所有的JS、HTML、CSS程式碼寫在一個html檔案中;由於使用了新的DOM API,所以建議使用chrome50以上版本的瀏覽器。


編寫思路:
1)來三張圖和三個按鈕,將所有圖片排成一行,將第一張複製一份放在最後(也可以全部複製放在後面,但只會用到第一張,重複出現一次三張圖,一共六張圖)
2)通過外邊距偏移實現輪播
預設顯示第1張圖
第1次改變,第1張圖移出,第2張圖出現
第2次改變,第2張圖移出,第3張圖出現
第0次改變,第3張圖移出,第4張圖出現(第4張是第1張的複製,使用者感覺是回到了第1張)
輪迴,第0次改變,瞬間將移回第1張,由於第4張圖和第1張一樣,所以使用者無法感覺這個變化,然後繼續第1張圖移出,第2張出現
...
3)給按鈕新增點選事件
觸發時停止自動播放,並切換到指定的圖片


第一步:編寫HTML和CSS
編寫HTML:
三張圖
三個按鈕
編寫CSS:
將所有圖片排成一行
將按鈕排到輪播圖中間底部
設定按鈕的狀態樣式
                
程式碼如下:
  1. <!DOCTYPE html>
  2.         <html>
  3.         <head>
  4.         <meta charset="UTF-8">
  5.         <title>輪播圖1</title>
  6.         <style>
  7.         .banner{overflow:hidden;position:relative;border:4px solid #f00;width:1000px;}
  8.         .banner ul{margin:0;padding:0;list-style:none;}
  9.         .banner .list li{float:left;}
  10.         .banner .list img{display:block;width:100%;}
  11.         
  12.         .icos{position:absolute;z-index:1;left:50%;bottom:14px;}
  13.         .icos li{text-indent:-9999px;background:#ccc;width:12px;height:12px;float:left;margin:0 5px;border-radius:100%;}
  14.         .icos li.on{background:#f00;}
  15.         </style>
  16.         </head>
  17.         <body>
  18.         <div class="banner">
  19.         <ul class="list">
  20.                 <li><img src="images/01.jpg"></li>
  21.                 <li><img src="images/02.jpg"></li>
  22.                 <li><img src="images/03.jpg"></li>
  23.         </ul>
  24.         <ul class="icos">
  25.                 <li class="on">0</li>
  26.                 <li>1</li>
  27.                 <li>2</li>
  28.         </ul>
  29.         </div>
  30.         </body>
  31.         </html>
複製程式碼 第二步:編寫JavaScript獲取元素
獲取輪播圖片總數(用於計算顯示輪迴)
獲取每屏寬度(用於計算每次偏移量)
        
程式碼:
  1. <script>
  2.         window.onload=function(){
  3.                 //獲取所有元素
  4.                 var list=document.querySelector('.list');
  5.                 var icos=document.querySelectorAll('.icos li');
  6.                 var li=document.querySelectorAll('.list li');
  7.                 var len=li.length; //一共幾張圖
  8.                 var li_width=document.querySelector('.banner').clientWidth; //每張圖的寬度
  9.                 list.innerHTML=list.innerHTML+list.innerHTML; //在列表最後新增一份,在展示最後一張切到第一張時實際展示的是剛新增的這張
  10.                 li=document.querySelectorAll('.list li'); //重新獲取所有節點
  11.                 //為每一個li設定寬度
  12.                 for(var i=0;i<li.length;i++){
  13.                         li[i].style.width=li_width+'px';
  14.                 }
  15.                 list.style.width=li_width*li.length+"px"; //設定總寬度,讓所有圖片在一行顯示
  16.         }
  17.         </script>
複製程式碼        
第三步:實現輪播
設定定時器實現隔3秒切換一張圖片
切換圖片時,需要傳入切換到指定圖片的編號
計算偏移量
設定定時器實現偏移時的動畫效果
實現按鈕狀態同步變化
        
        JS程式碼:
  1. //通過偏移實現動畫
  2.         function show(n){
  3.                 if(n==1){ //這個判斷順序很關鍵,必須放在上面,實現最後一張瞬間切回第一張,再轉到第二張
  4.                         list.style.marginLeft='0px';
  5.                 }
  6.                 /*
  7.                 默認出現第1張
  8.                 n=1        動畫出現第二張,第一張消失
  9.                 n=2        動畫出現第三張,第二張消失
  10.                 n=0        動畫出現第四張(第一張的複製),第三張消失
  11.                 n=1        瞬間切回第一張(由於第一張和第四張相同,肉眼看不出變化),再動畫出現第二張,第一張消失
  12.                 */
  13.                 
  14.                 var w=n>0 ? -(n-1)*li_width : -(len-1)*li_width; //計算偏移量,以實現動畫效果,等於0時特殊處理,展示手動加的那一張
  15.                 var step=20; //步長可根據寬度計算得到
  16.                 var i=step;
  17.                 var timer=setInterval(function(){
  18.                         list.style.marginLeft=(w-i)+'px';
  19.                         i+=step;
  20.                         if(i>li_width){ //顯示完一張圖就停止
  21.                                 clearInterval(timer);
  22.                         }
  23.                 },20);
  24.                 
  25.                 //改變按鈕狀態
  26.                 for(var j=0; j<icos.length; j++){
  27.                         if(n==j){
  28.                                 icos[j].className='on';
  29.                         }else{
  30.                                 icos[j].className='';
  31.                         }
  32.                 }
  33.         }
  34.         
  35.         //自動播放函式
  36.         function autoplay(){
  37.                 var count=1; //初始是第1張,自動播放從第2張開始
  38.                 timeId=setInterval(function(){
  39.                         show(count % len); //取餘數實現輪流播放
  40.                         count++;
  41.                 },3000);
  42.         }
  43.         
  44.         autoplay();
複製程式碼 第四步:按鈕功能
給所有按鈕新增事件
點選時停止自動播放,切換到指定的圖片
        
JS程式碼:
  1. //給每一個按鈕繫結事件
  2.         for(var i=0; i<icos.length; i++){
  3.                 icos[i].onmouseover=function(){ //滑鼠移到小圖示上時取消自動播放並切換到指定的圖片上
  4.                         clearInterval(timeId);
  5.                         show(this.innerText);
  6.                 }
  7.                 icos[i].onmouseout=function(){ //滑鼠移開時繼續自動播放
  8.                         autoplay();
  9.                 }
  10.         }
複製程式碼 程式碼彙總:
  1. <!DOCTYPE html>
  2. <html>
  3.         <head>
  4.                 <meta charset="UTF-8">
  5.                 <title>輪播圖1</title>
  6.                 <style>
  7.                         .banner{overflow:hidden;position:relative;border:4px solid #f00;width:1000px;}
  8.                         .banner ul{margin:0;padding:0;list-style:none;}
  9.                         .banner .list li{float:left;}
  10.                         .banner .list img{display:block;width:100%;}
  11.                         
  12.                         .icos{position:absolute;z-index:1;left:50%;bottom:14px;}
  13.                         .icos li{text-indent:-9999px;background:#ccc;width:12px;height:12px;float:left;margin:0 5px;border-radius:100%;}
  14.                         .icos li.on{background:#f00;}
  15.                 </style>
  16.         </head>
  17.         <body>
  18.                 <div class="banner">
  19.                         <ul class="list">
  20.                                 <li><img src="images/01.jpg"></li>
  21.                                 <li><img src="images/02.jpg"></li>
  22.                                 <li><img src="images/03.jpg"></li>
  23.                         </ul>
  24.                         <ul class="icos">
  25.                                 <li class="on">0</li>
  26.                                 <li>1</li>
  27.                                 <li>2</li>
  28.                         </ul>
  29.                 </div>
  30.                 
  31.                 <script>
  32.                         window.onload=function(){
  33.                                 //獲取所有元素
  34.                                 var list=document.querySelector('.list');
  35.                                 var icos=document.querySelectorAll('.icos li');
  36.                                 var li=document.querySelectorAll('.list li');
  37.                                 var len=li.length; //一共幾張圖
  38.                                 var li_width=document.querySelector('.banner').clientWidth; //每張圖的寬度
  39.                                 list.innerHTML=list.innerHTML+list.innerHTML; //在列表最後新增一份,在展示最後一張切到第一張時實際展示的是剛新增的這張
  40.                                 li=document.querySelectorAll('.list li'); //重新獲取所有節點
  41.                                 
  42.                                 //為每一個li設定寬度
  43.                                 for(var i=0;i<li.length;i++){
  44.                                         li[i].style.width=li_width+'px';
  45.                                 }
  46.                                 list.style.width=li_width*li.length+"px"; //設定總寬度,讓所有圖片在一行顯示
  47.                                 
  48.                                 //給每一個按鈕繫結事件
  49.                                 for(var i=0; i<icos.length; i++){
  50.                                         icos[i].onmouseover=function(){ //滑鼠移到小圖示上時取消自動播放並切換到指定的圖片上
  51.                                                 clearInterval(timeId);
  52.                                                 show(this.innerText);
  53.                                         }
  54.                                         icos[i].onmouseout=function(){ //滑鼠移開時繼續自動播放
  55.                                                 autoplay();
  56.                                         }
  57.                                 }
  58.                                 
  59.                                 //通過偏移實現動畫
  60.                                 function show(n){
  61.                                         if(n==1){ //這個判斷順序很關鍵,必須放在上面,實現最後一張瞬間切回第一張,再轉到第二張
  62.                                                 list.style.marginLeft='0px';
  63.                                         }
  64.                                         /*
  65.                                         默認出現第1張
  66.                                         n=1        動畫出現第二張,第一張消失
  67.                                         n=2        動畫出現第三張,第二張消失
  68.                                         n=0        動畫出現第四張(第一張的複製),第三張消失
  69.                                         n=1        瞬間切回第一張(由於第一張和第四張相同,肉眼看不出變化),再動畫出現第二張,第一張消失
  70.                                         */
  71.                                         
  72.                                         var w=n>0 ? -(n-1)*li_width : -(len-1)*li_width; //計算偏移量,以實現動畫效果,等於0時特殊處理,展示手動加的那一張
  73.                                         var step=20; //步長可根據寬度計算得到
  74.                                         var i=step;
  75.                                         var timer=setInterval(function(){
  76.                                                 list.style.marginLeft=(w-i)+'px';
  77.                                                 i+=step;
  78.                                                 if(i>li_width){ //顯示完一張圖就停止
  79.                                                         clearInterval(timer);
  80.                                                 }
  81.                                         },20);
  82.                                         
  83.                                         //改變按鈕狀態
  84.                                         for(var j=0; j<icos.length; j++){
  85.                                                 if(n==j){
  86.                                                         icos[j].className='on';
  87.                                                 }else{
  88.                                                         icos[j].className='';
  89.                                                 }
  90.                                         }
  91.                                 }
  92.                                 
  93.                                 //自動播放函式
  94.                                 function autoplay(){
  95.                                         var count=1; //初始是第1張,自動播放從第2張開始
  96.                                         timeId=setInterval(function(){
  97.                                                 show(count % len); //取餘數實現輪流播放
  98.                                                 count++;
  99.                                         },3000);
  100.                                 }
  101.                                 
  102.                                 autoplay();
  103.                         }
  104.                 </script>
  105.         </body>
  106. </html>
複製程式碼

總結,和所有的PHP框架一樣,所有JS框架和庫都是基於原生JS編寫的,只有把原生JS的程式碼掌握好,才能以不變應萬變,在技術領域平靜對待各種變化。

本文來源:http://bbs.itsource.cn/thread-1662-1-1.html,轉載請註明出處!