JS原生輪播圖實現
阿新 • • 發佈:2018-11-08
作為一個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:
將所有圖片排成一行
將按鈕排到輪播圖中間底部
設定按鈕的狀態樣式
程式碼如下:
獲取輪播圖片總數(用於計算顯示輪迴)
獲取每屏寬度(用於計算每次偏移量)
程式碼:
第三步:實現輪播
設定定時器實現隔3秒切換一張圖片
切換圖片時,需要傳入切換到指定圖片的編號
計算偏移量
設定定時器實現偏移時的動畫效果
實現按鈕狀態同步變化
JS程式碼:
給所有按鈕新增事件
點選時停止自動播放,切換到指定的圖片
JS程式碼:
如果能自己使用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:
將所有圖片排成一行
將按鈕排到輪播圖中間底部
設定按鈕的狀態樣式
程式碼如下:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>輪播圖1</title>
- <style>
- .banner{overflow:hidden;position:relative;border:4px solid #f00;width:1000px;}
- .banner ul{margin:0;padding:0;list-style:none;}
- .banner .list li{float:left;}
- .banner .list img{display:block;width:100%;}
-
- .icos{position:absolute;z-index:1;left:50%;bottom:14px;}
- .icos li{text-indent:-9999px;background:#ccc;width:12px;height:12px;float:left;margin:0 5px;border-radius:100%;}
- .icos li.on{background:#f00;}
- </style>
- </head>
- <body>
- <div class="banner">
- <ul class="list">
- <li><img src="images/01.jpg"></li>
- <li><img src="images/02.jpg"></li>
- <li><img src="images/03.jpg"></li>
- </ul>
- <ul class="icos">
- <li class="on">0</li>
- <li>1</li>
- <li>2</li>
- </ul>
- </div>
- </body>
- </html>
獲取輪播圖片總數(用於計算顯示輪迴)
獲取每屏寬度(用於計算每次偏移量)
程式碼:
- <script>
- window.onload=function(){
- //獲取所有元素
- var list=document.querySelector('.list');
- var icos=document.querySelectorAll('.icos li');
- var li=document.querySelectorAll('.list li');
- var len=li.length; //一共幾張圖
- var li_width=document.querySelector('.banner').clientWidth; //每張圖的寬度
- list.innerHTML=list.innerHTML+list.innerHTML; //在列表最後新增一份,在展示最後一張切到第一張時實際展示的是剛新增的這張
- li=document.querySelectorAll('.list li'); //重新獲取所有節點
- //為每一個li設定寬度
- for(var i=0;i<li.length;i++){
- li[i].style.width=li_width+'px';
- }
- list.style.width=li_width*li.length+"px"; //設定總寬度,讓所有圖片在一行顯示
- }
- </script>
第三步:實現輪播
設定定時器實現隔3秒切換一張圖片
切換圖片時,需要傳入切換到指定圖片的編號
計算偏移量
設定定時器實現偏移時的動畫效果
實現按鈕狀態同步變化
JS程式碼:
- //通過偏移實現動畫
- function show(n){
- if(n==1){ //這個判斷順序很關鍵,必須放在上面,實現最後一張瞬間切回第一張,再轉到第二張
- list.style.marginLeft='0px';
- }
- /*
- 默認出現第1張
- n=1 動畫出現第二張,第一張消失
- n=2 動畫出現第三張,第二張消失
- n=0 動畫出現第四張(第一張的複製),第三張消失
- n=1 瞬間切回第一張(由於第一張和第四張相同,肉眼看不出變化),再動畫出現第二張,第一張消失
- */
-
- var w=n>0 ? -(n-1)*li_width : -(len-1)*li_width; //計算偏移量,以實現動畫效果,等於0時特殊處理,展示手動加的那一張
- var step=20; //步長可根據寬度計算得到
- var i=step;
- var timer=setInterval(function(){
- list.style.marginLeft=(w-i)+'px';
- i+=step;
- if(i>li_width){ //顯示完一張圖就停止
- clearInterval(timer);
- }
- },20);
-
- //改變按鈕狀態
- for(var j=0; j<icos.length; j++){
- if(n==j){
- icos[j].className='on';
- }else{
- icos[j].className='';
- }
- }
- }
-
- //自動播放函式
- function autoplay(){
- var count=1; //初始是第1張,自動播放從第2張開始
- timeId=setInterval(function(){
- show(count % len); //取餘數實現輪流播放
- count++;
- },3000);
- }
-
- autoplay();
給所有按鈕新增事件
點選時停止自動播放,切換到指定的圖片
JS程式碼:
- //給每一個按鈕繫結事件
- for(var i=0; i<icos.length; i++){
- icos[i].onmouseover=function(){ //滑鼠移到小圖示上時取消自動播放並切換到指定的圖片上
- clearInterval(timeId);
- show(this.innerText);
- }
- icos[i].onmouseout=function(){ //滑鼠移開時繼續自動播放
- autoplay();
- }
- }
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>輪播圖1</title>
- <style>
- .banner{overflow:hidden;position:relative;border:4px solid #f00;width:1000px;}
- .banner ul{margin:0;padding:0;list-style:none;}
- .banner .list li{float:left;}
- .banner .list img{display:block;width:100%;}
-
- .icos{position:absolute;z-index:1;left:50%;bottom:14px;}
- .icos li{text-indent:-9999px;background:#ccc;width:12px;height:12px;float:left;margin:0 5px;border-radius:100%;}
- .icos li.on{background:#f00;}
- </style>
- </head>
- <body>
- <div class="banner">
- <ul class="list">
- <li><img src="images/01.jpg"></li>
- <li><img src="images/02.jpg"></li>
- <li><img src="images/03.jpg"></li>
- </ul>
- <ul class="icos">
- <li class="on">0</li>
- <li>1</li>
- <li>2</li>
- </ul>
- </div>
-
- <script>
- window.onload=function(){
- //獲取所有元素
- var list=document.querySelector('.list');
- var icos=document.querySelectorAll('.icos li');
- var li=document.querySelectorAll('.list li');
- var len=li.length; //一共幾張圖
- var li_width=document.querySelector('.banner').clientWidth; //每張圖的寬度
- list.innerHTML=list.innerHTML+list.innerHTML; //在列表最後新增一份,在展示最後一張切到第一張時實際展示的是剛新增的這張
- li=document.querySelectorAll('.list li'); //重新獲取所有節點
-
- //為每一個li設定寬度
- for(var i=0;i<li.length;i++){
- li[i].style.width=li_width+'px';
- }
- list.style.width=li_width*li.length+"px"; //設定總寬度,讓所有圖片在一行顯示
-
- //給每一個按鈕繫結事件
- for(var i=0; i<icos.length; i++){
- icos[i].onmouseover=function(){ //滑鼠移到小圖示上時取消自動播放並切換到指定的圖片上
- clearInterval(timeId);
- show(this.innerText);
- }
- icos[i].onmouseout=function(){ //滑鼠移開時繼續自動播放
- autoplay();
- }
- }
-
- //通過偏移實現動畫
- function show(n){
- if(n==1){ //這個判斷順序很關鍵,必須放在上面,實現最後一張瞬間切回第一張,再轉到第二張
- list.style.marginLeft='0px';
- }
- /*
- 默認出現第1張
- n=1 動畫出現第二張,第一張消失
- n=2 動畫出現第三張,第二張消失
- n=0 動畫出現第四張(第一張的複製),第三張消失
- n=1 瞬間切回第一張(由於第一張和第四張相同,肉眼看不出變化),再動畫出現第二張,第一張消失
- */
-
- var w=n>0 ? -(n-1)*li_width : -(len-1)*li_width; //計算偏移量,以實現動畫效果,等於0時特殊處理,展示手動加的那一張
- var step=20; //步長可根據寬度計算得到
- var i=step;
- var timer=setInterval(function(){
- list.style.marginLeft=(w-i)+'px';
- i+=step;
- if(i>li_width){ //顯示完一張圖就停止
- clearInterval(timer);
- }
- },20);
-
- //改變按鈕狀態
- for(var j=0; j<icos.length; j++){
- if(n==j){
- icos[j].className='on';
- }else{
- icos[j].className='';
- }
- }
- }
-
- //自動播放函式
- function autoplay(){
- var count=1; //初始是第1張,自動播放從第2張開始
- timeId=setInterval(function(){
- show(count % len); //取餘數實現輪流播放
- count++;
- },3000);
- }
-
- autoplay();
- }
- </script>
- </body>
- </html>
總結,和所有的PHP框架一樣,所有JS框架和庫都是基於原生JS編寫的,只有把原生JS的程式碼掌握好,才能以不變應萬變,在技術領域平靜對待各種變化。
本文來源:http://bbs.itsource.cn/thread-1662-1-1.html,轉載請註明出處!