亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

JavaScript實現圖片輪播組件代碼示例

2019-11-19 18:53:26
字體:
來源:轉載
供稿:網友

本文介紹了JavaScript實現圖片輪播組件,廢話不多說了直接看下面:

效果:

  • 自動循環播放圖片,下方有按鈕可以切換到對應圖片。
  • 添加一個動畫來實現圖片切換。
  • 鼠標停在圖片上時,輪播停止,出現左右兩個箭頭,點擊可以切換圖片。
  • 鼠標移開圖片區域時,從當前位置繼續輪播。
  • 提供一個接口,可以設置輪播方向,是否循環,間隔時間。

對HTML、CSS的要求:

<div class="carousel-box">  <div class="carousel">    <ul class="clearfix" >      <li><img src="img/carousel01.jpg" alt=""></li>      <li><img src="img/carousel02.jpg" alt=""></li>      <li><img src="img/carousel03.jpg" alt=""></li>      <li><img src="img/carousel04.jpg" alt=""></li>      <li><img src="img/carousel05.jpg" alt=""></li>      <li><img src="img/carousel06.jpg" alt=""></li>    </ul>  </div></div>
  • 必須是兩個盒子嵌套,最里面的盒子需要有一個ul,圖片需要被包含在li里。
  • 可以更改類名,同時將css文件中的相應類名替換即可。配置組件時傳入正確的DOM元素即可。
  • 不限制圖片寬度和數量,在css文件中更改數值即可。
/*需要更改的值*/.carousel img{   width: 600px;  height: 400px;}.carousel,.carousel-box {  width: 600px; /*單張圖片寬度*/  height: 400px; /*單張圖片高度*/}.carousel ul{  width: 3600px; /*單張圖片寬度x圖片數量*/}

原理:

將所有圖片橫向排列,最外層容器和包裹容器設置overflow:hidden。最外層容器用于按鈕和箭頭的定位。利用包裹容器的scrollLeft屬性控制顯示哪張圖片。

思路:

想要實現這些功能,應該有以下一些方法:

1.圖片切換函數。接受一個參數,表示滾動方向。調用緩動函數切換圖片。調用切換按鈕圖標函數點亮相應的按鈕。

2.緩動函數。

3.點亮按鈕函數。

4.初始化函數。用于綁定事件,創建按鈕和箭頭,初始化最初位置。

5.創建箭頭函數。

6.創建按鈕函數。

7.開始輪播函數。

8.輪播函數。

9.停止函數。用于停止輪播。

還有一些公用方法:$():選擇DOM元素。addClass(ele,"className"):給元素添加類名。removeClass(ele,"className")移除元素的類名。$.add(ele,"type",fun):給一個DOM節點綁定事件。getCSS(ele,"prop"):獲取元素相應屬性的值。$.delegateTag("selector","tagName","type",fun):事件代理。

實現:

假設有6張圖片,每張圖片寬度為600px。按照功能的獨立性來完成:

1.緩動函數  liner

緩動函數的作用是一點一點的改變目標元素的屬性值,直到達到目標值。使用它的元素可能是水平輪播的圖片,也可能是垂直輪播的圖片,也可能是一個想從頁面左端到達頁面右端的小盒子。所以它應該接收四個參數(目標元素,要改變的屬性值,目標值,移動次數)。

liner=function(ele,prop,next,num){  var speed=(next-ele[prop])/num,    i=0;  (function(){    ele[prop]+=speed;    i++;    if (i<num) {      setTimeout(arguments.callee,30);    }  })();  },

2.點亮按鈕函數  light

點亮按鈕本質上就是給按鈕添加一個active類,熄滅按鈕就是給按鈕移除active類。

那么如何知道當前按鈕是哪一個呢?

最簡單的方法是直接獲取,所以可以給每個按鈕添加一個index屬性,當需要點亮按鈕時,將要點亮的按鈕的index傳給這個函數即可。

那么如何知道要熄滅的按鈕是哪一個呢?

最簡單的方法也是直接獲取,所以可以在作用域鏈末端添加一個變量active,記住當前亮著的按鈕,這個函數直接將他熄滅就可以了。

light=function(index){  removeClass(active,"active");  active=$(this.wrapSelec+" "+"[index="+index+"]");  addClass(active,"active");}

3.圖片切換函數  go

需要計算出下一個scrollLeft的值:

如果是向左移動的話,scrollLeft應該-600,如果已經是0,就切換為3000.所以是ele.scrollLeft===0?width*(len-1):ele.scrollLeft-width;

如果是向右移動的話,scrollLeft應該+600,即0――>600,600――>1200,...,3000――>0。這里可以像上面那樣用判斷,也可以用一個公式next=(cur+distance)%(distance*num)。即(ele.scrollLeft+width)%(width*len)

需要獲得下一個要被點亮的按鈕的index:

和計算scrollLeft的思路一樣,往左移動:index===0? len-1:index-1; 往右移動:(index+1)%len

go=function(dire){  var index=active.getAttribute("index")-0,    nextIndex,    nextPosition;  if (dire==="next") {    nextIndex=(index+1)%len;    nextPosition=(ele.scrollLeft+width)%(width*len);  }else{    nextIndex=index===0? len-1:index-1,    nextPosition=ele.scrollLeft===0?width*len:ele.scrollLeft-width;  }  light(nextIndex);  animate.liner(ele,"scrollLeft",nextPosition);  }

其中的len(圖片總數)、width(圖片寬度)、ele(包裹容器)也會被其他函數訪問,所以也添加到作用域鏈末端。

len=ele.getElementsByTagName("img").length

width=parseInt(getCSS(ele.getElementsByTagName("img")[0],"width");

ele=$(eleSelec),eleSelec是包裹容器的selector,比如.carousel

4.創建箭頭函數 createArrow

創建一個向左的箭頭,綁定事件處理函數,用于向左移動。創建一個向右的箭頭,綁定事件處理函數,用于向右移動。

createArrow=function(){  var prev=document.createElement("div"),    next=document.createElement("div");  prev.appendChild(document.createTextNode("<"));  next.appendChild(document.createTextNode(">"));  prev.className="arrow prev";  next.className="arrow next";    container.appendChild(prev);  container.appendChild(next);  addClass(container,"hide");  $.add(next,"click",function(){    go("next");  });  $.add(prev,"click",function(){    go("prev");  });}

container代表最外層容器,也會被其他函數訪問,所以也添加到作用域鏈末端。

container=$(wrapSelec),wrapSelec是最外層容器的selector,比如.carousel-box

5.創建按鈕函數 createBtn

給每個按鈕添加一個index用于點亮和熄滅,給按鈕組添加一個類名用于設置樣式和獲取它:

createBtn=function(){  var div=document.createElement("div"),    btns='';  for(var i=0;i<len;i++){    btns+='<a href="#" index="'+i+'"></a>';  }  div.innerHTML=btns;  addClass(div,"carousel-btn");  container.appendChild(div);}

6.輪播函數

根據要求(順時針、逆時針)判斷要調用go("prev")還是go("next")。

如果要求循環,則再次調用自己。如果不循環,則在輪播一輪后停止。

所以這里需要一個變量來判斷方向,一個變量來判斷是否循環,一個變量來計數。

所以又有四個變量被加到作用域鏈末端。direction、loop、count、begin用于清除定時器。

circle=function(){  count++;  if (loop||count<len) {    if (direction==="forward") {      go("next");    }else{      go("prev");    }  }  begin=setTimeout(arguments.callee,t);}

7.停止函數 stop

stop=function(){  clearTimeout(begin);}

8.初始化函數 init

如果是第一次使用輪播,則創建按鈕和箭頭,并給按鈕綁定click事件處理程序(獲取點擊的按扭index點亮它,切換到相應圖片),然后根據順時針或逆時針來展示相應的圖片和按鈕。

所以這里又需要有一個變量加在作用域鏈末端,用于表示是否已經初始化。

init=function(){  createBtn();  createArrow();  $.delegateTag(wrapSelec+" "+".carousel-btn","a","click",function(e,target){    $.prevent(e);    light(target.getAttribute("index"));    animate.liner(ele,"scrollLeft",target.getAttribute("index")*width);  });  $.add(container,"mouseenter",function(){    stop();    removeClass(container,"hide");  });  $.add(container,"mouseleave",function(){    addClass(container,"hide");    begin=setTimeout(circle,t);   });if (direction==="forward") {    light(0);  }else{    light(len-1);    ele.scrollLeft=width*(len-1);  }  haveStart=true;}

9.開始輪播函數 start

這個函數當做接口,用于控制輪播方向,間隔時間,和是否循環。計數器歸零。

因為可能重復的開始輪播,所以每次開始之前都需要清除定時器。

start=function(dir,th,lo){  stop();  count=0;  direction=dir;  t=th*1000;  loop=lo;  if (!haveStart) {    init();  }  begin=setTimeout(circle,t);}

到這里,所有需要用到的函數已經寫完了,如果把這些函數和那些需要的變量扔到一個函數里,把外層容器盒包裹容器的類名或ID傳給它,這個函數返回一個包含start和stop方法的對象,這個組件就可以使用了。

但是有一個問題,這個函數只有一個,也就是說,一個頁面只能有一個輪播實例。所以,如果想要一個頁面能有兩個輪播實例都用這個組件的話,就不能把它們扔到一個函數里。那么就只能放到對象里。每個對象有自己的變量,他們共用一組方法。

那么,這些變量就不能直接訪問了,需要通過對象的屬性訪問,即this。

這時候就會出現問題,this是會指向調用它的那個環境,所以當那些變量在事件處理程序中,或是在定時器中被訪問的時候,就不能用this,而是要創建一個閉包。

即,在能獲取到this時,將this賦值給一個變量,然后在事件處理程序或是定時器中訪問這個變量,就會獲取到正確的對象。

以init函數為例來改裝:

carouselProto.init=function(){  var that=this;  this.createBtn();  this.createArrow();  $.delegateTag(this.wrapSelec+" "+".carousel-btn","a","click",function(e,target){    $.prevent(e);    that.light(target.getAttribute("index"));    animate.liner(that.ele,"scrollLeft",target.getAttribute("index")*that.width);  });  $.add(this.container,"mouseenter",function(){    that.stop();    removeClass(that.container,"hide");  });  $.add(this.container,"mouseleave",function(){    addClass(that.container,"hide");    that.begin=setTimeout(function(){      that.circle();    },that.t);   });if (this.direction==="forward") {    this.light(0);  }else{    this.light(this.len-1);    this.ele.scrollLeft=this.width*(this.len-1);  }  this.haveStart=true;};

這樣改裝完之后,就可以創建實例了,每個實例都會有自己的屬性用于記錄狀態,他們都共用原型中的方法。

如果采用原型繼承的方式的話,可以創建一個對象作為實例的原型對象,然后創建一個函數來生產實例:

var carouselProto={};//把上面那些方法給這個對象carouselProto.light=...carouselProto.go=...carouselProto.stop=...//創建實例對象函數var carousel=function(eleSelec,wrapSelec){  var that=Object.create(carouselProto);  that.wrapSelec=wrapSelec;  that.ele=$(eleSelec);  that.container=$(wrapSelec);  that.len=that.ele.getElementsByTagName("img").length;  that.width=parseInt(getCSS(that.ele.getElementsByTagName("img")[0],"width"));  return that;}//創建實例,使用組件var carousel1=carousel(".carousel",".carousel-box");   carousel1.start("forward",3,true);var carousel2=carousel(".carousel2",".carousel-box2");   carousel2.start("backward",2,true); 

性能優化:

1.當點擊的按鈕剛好是當前被點亮的按鈕時,依然會調用一次light和animate.liner。所以可以添加一個判斷語句,如果點擊的按鈕剛好是正確的,就不要執行下面的了。

$.delegateTag(this.wrapSelec+" "+".carousel-btn","a","click",function(e,target){  $.prevent(e);  var index=target.getAttribute("index");  if (index===that.active.getAttribute("index")) {    return  }  that.light(index);  animate.liner(that.ele,"scrollLeft",target.getAttribute("index")*that.width);});

2.當圖片切換的時候,緩動動畫正在執行。如果在緩動動畫還沒執行完時就點擊按鈕或者箭頭,就會進入下一次動畫,于是就會出現混亂,圖片錯位。性能也會受到影響。為了防止這種情況發生,可以使用一個變量,用于記錄緩動動畫是否正在執行,沒有執行的話點擊按鈕或箭頭才會執行函數。

liner=function(ele,prop,next){  var speed=(next-ele[prop])/10,    i=0;  ele.animating=true;  (function(){    ele[prop]+=speed;    i++;    if (i<10) {      setTimeout(arguments.callee,60);    }else{      ele.animating=false;    }  })();  }if (!this.ele.animating) {  this.light(nextIndex);    animate.liner(this.ele,"scrollLeft",nextPosition);}

源碼:源碼下載demo

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩福利在线播放| 精品久久香蕉国产线看观看gif| 亚洲精品欧美日韩专区| 欧美性黄网官网| 欧美午夜美女看片| 久久中文久久字幕| 国产97在线亚洲| 欧美丝袜美女中出在线| 成人性生交大片免费看小说| 亚洲伊人一本大道中文字幕| 中国china体内裑精亚洲片| 最新亚洲国产精品| 亚洲精选在线观看| 日本aⅴ大伊香蕉精品视频| 在线不卡国产精品| 国模私拍一区二区三区| 国产九九精品视频| 亚洲国产日韩一区| 欧美日韩国产激情| 久久99精品久久久久久青青91| 欧美在线免费看| 欧美激情在线观看| 国产综合在线看| 亚洲第一中文字幕在线观看| 欧美日韩国产精品一区二区不卡中文| 操日韩av在线电影| 亚洲女同性videos| 日韩av网址在线| 秋霞午夜一区二区| 久久精品91久久久久久再现| 亚洲欧美综合另类中字| 亚洲免费视频网站| 亚洲一区二区三区久久| 亚洲一区二区久久久久久| 亚洲精品一区av在线播放| 欧美性猛交视频| 日韩精品久久久久| 欧美国产在线电影| 成人免费视频xnxx.com| 久久国产精品久久久久久久久久| 欧美裸体xxxx极品少妇| 日韩av电影免费观看高清| 国产精品91久久| 在线观看日韩视频| 按摩亚洲人久久| 久久精品99无色码中文字幕| 伦伦影院午夜日韩欧美限制| 波霸ol色综合久久| 亚洲国产成人一区| 国产男女猛烈无遮挡91| 亚洲精品视频网上网址在线观看| 日韩一区二区三区国产| 在线精品91av| 欧美中文字幕视频| 亚洲另类xxxx| 亚洲成人在线视频播放| 91在线中文字幕| 国产精品一区二区女厕厕| 国产成人一区二区三区| 亚洲国产欧美一区| 欧美日本国产在线| 精品国产区一区二区三区在线观看| 国产在线视频不卡| 在线观看国产精品日韩av| 国产亚洲人成a一在线v站| 久久久久国色av免费观看性色| 精品性高朝久久久久久久| 亚洲老司机av| 久久91超碰青草是什么| 欧美综合国产精品久久丁香| 成人精品久久一区二区三区| 亚洲午夜性刺激影院| 深夜福利亚洲导航| 亚洲丝袜一区在线| 久久久极品av| 国产精品高潮粉嫩av| 91黄色8090| 亚洲欧美日韩精品久久奇米色影视| 国产精品吹潮在线观看| 亚洲精品一区二区三区婷婷月| 日韩电影在线观看永久视频免费网站| 成人免费在线网址| 性夜试看影院91社区| 国产精品极品美女粉嫩高清在线| 成人夜晚看av| 精品欧美aⅴ在线网站| 欧美日韩性视频在线| 91成人在线观看国产| 青青草精品毛片| 8x拔播拔播x8国产精品| 色播久久人人爽人人爽人人片视av| 91极品女神在线| 日韩精品久久久久久福利| 久久国内精品一国内精品| 国产精品成人一区| 欧美日韩在线看| 亚洲精品欧美日韩| 成人h片在线播放免费网站| 国产97在线亚洲| 久久天堂av综合合色| 亚洲综合国产精品| 色婷婷久久av| 欧美一级视频在线观看| 欧美日韩一区二区三区在线免费观看| 日本久久久久久久久| 色婷婷av一区二区三区在线观看| 国产视频久久久久久久| 亚洲另类图片色| 亚洲一区二区三区视频播放| 欧美激情精品久久久久久| 美女久久久久久久久久久| 欧洲午夜精品久久久| 久久久久久久97| 国产香蕉一区二区三区在线视频| 欧美日韩国产一区二区| 日韩在线视频一区| 九九热精品在线| 一本大道久久加勒比香蕉| 欧美中文字幕精品| 亚洲日本中文字幕免费在线不卡| 亚洲欧美激情精品一区二区| 国产91在线播放精品91| 欧美精品日韩三级| 精品网站999www| 欧美伊久线香蕉线新在线| 欧美激情免费视频| 日韩在线观看网址| 亚洲国产天堂久久国产91| 成人精品一区二区三区电影免费| 亚洲最大福利网站| 亚洲综合小说区| 日本欧美一级片| 日韩电影第一页| 久久伊人精品视频| 亚洲成人动漫在线播放| 亚洲国产精品字幕| 国产人妖伪娘一区91| 北条麻妃99精品青青久久| 亚洲伊人成综合成人网| 92福利视频午夜1000合集在线观看| 国产精品国产三级国产专播精品人| 久久网福利资源网站| 亚洲剧情一区二区| 亚洲一级黄色片| 中文字幕亚洲综合久久筱田步美| 欧美成人在线免费视频| 亚洲女同精品视频| 欧美日韩xxxxx| 欧美激情在线观看视频| 欧美裸体xxxx极品少妇软件| 97精品国产aⅴ7777| 欧美专区在线视频| 日韩av电影手机在线| 久久久av免费| 疯狂蹂躏欧美一区二区精品| 久久久久久久影院| 88国产精品欧美一区二区三区| 视频在线一区二区| 日韩视频在线一区| 欧美精品午夜视频| 欧美电影在线观看网站| 亚洲第一中文字幕在线观看| 亚洲乱码国产乱码精品精| 精品久久久av|