原生JS實(shí)現(xiàn)圖片無(wú)縫滾動(dòng)方法(附帶封裝的運(yùn)動(dòng)框架)
話說(shuō)輪播圖效果是前端er學(xué)習(xí)JS的必經(jīng)之路啊,很多同學(xué)寫的第一個(gè)JS效果應(yīng)該就是它了,在各大網(wǎng)站我們都會(huì)經(jīng)常見(jiàn)到,但是無(wú)縫滾動(dòng)運(yùn)動(dòng)效果的輪播圖,對(duì)于小白們來(lái)說(shuō)還是有一定難度的。
我們來(lái)看看思路吧~
首先我們要實(shí)現(xiàn)的效果有以下幾點(diǎn):
小圓點(diǎn):點(diǎn)擊小圓點(diǎn)顯示與之對(duì)應(yīng)的圖片
向左和向右按鈕:點(diǎn)擊向左按鈕圖片向后運(yùn)動(dòng),點(diǎn)擊向右按鈕圖片向前運(yùn)動(dòng)
定時(shí)器:每隔 2s 自動(dòng)播放
主要難點(diǎn)在于:
當(dāng)圖片運(yùn)動(dòng)到最后一張,點(diǎn)擊向右的按鈕時(shí),應(yīng)該顯示第一張;
當(dāng)前顯示的是第一張,點(diǎn)擊向左的按鈕時(shí),應(yīng)該顯示最后一張;
思路:
1、先將第一張圖片復(fù)制 添加到 ul 最后面,將最后一張圖片復(fù)制 添加到 ul 最前面(此時(shí) ul 的第一張圖片是pic3,最后一張圖片是pic0);
2、當(dāng)圖片(ul)運(yùn)動(dòng)到pic3,繼續(xù)向前運(yùn)動(dòng),運(yùn)動(dòng)到最后一張pic0時(shí),瞬間把 ul 拉回到第二張圖片pic0的位置,然后在繼續(xù)向前運(yùn)動(dòng);
3、當(dāng)圖片(ul)向后運(yùn)動(dòng)到第一張圖片pic3時(shí),瞬間把 ul 拉回到倒數(shù)第二張圖片pic3的位置。
4、還有非常關(guān)鍵的一點(diǎn):定義iNow變量,用于對(duì)應(yīng)當(dāng)前顯示的圖片與ol中的小圓點(diǎn),并且可以用來(lái)關(guān)聯(lián) ul 的位置。
html代碼:
<div id="tab">
<ul>
<li><img src="image/pic0.jpg" alt="" /></li>
<li><img src="image/pic1.jpg" alt="" /></li>
<li><img src="image/pic2.jpg" alt="" /></li>
<li><img src="image/pic3.jpg" alt="" /></li>
</ul>
<ol>
<li class="on"></li>
<li></li>
<li></li>
<li></li>
</ol>
<a href="javascript:;" rel="external nofollow" rel="external nofollow" class="prev" id="prev"><</a>
<a href="javascript:;" rel="external nofollow" rel="external nofollow" class="next" id="next">></a>
</div>
css代碼:
*{margin: 0; padding: 0;}
li{ list-style: none;}
#tab{
width: 670px;
height: 240px;
border: 1px solid #ccc;
margin: 50px auto;
position: relative;
}
#tab ul{
width: 2680px;
height: 240px;
position: absolute;
left: 0;
top: 0;
overflow: hidden;
}
#tab ul li{
float: left;
width: 670px;
}
#tab ul li img{
width: 670px;
}
#tab ol{
width: 80px;
position: absolute;
bottom: 10px;
left: 50%;
margin-left: -40px;
overflow: hidden;
}
#tab ol li{
float: left;
width: 10px;
height: 10px;
background: #ccc;
border-radius: 50%;
margin: 5px;
cursor: pointer;
}
#tab ol .on{
background: #f00;
}
#tab .prev,#tab .next{
display: none;
width: 40px;
height: 60px;
background: rgba(0,0,0,.3);
filter:alpha(opacity:30);
text-decoration: none;
text-align: center;
line-height: 60px;
font-size: 30px;
color: #fff;
position: absolute;
top: 50%;
margin-top: -30px;
}
#tab .prev{
left: 0;
}
#tab .next{
right: 0;
}
js 代碼:
其中animate()是封裝好的運(yùn)動(dòng)框架,最后面附有說(shuō)明
window.onload = function(){
var oTab = document.getElementById('tab');
var oUl = oTab.getElementsByTagName('ul')[0];
var aLi1 = oUl.children;
var oOl = oTab.getElementsByTagName('ol')[0];
var aLi2 = oOl.children;
var prev = document.getElementById('prev');
var next = document.getElementById('next');
//設(shè)置ul的初始位置
var iNow = 1;
oUl.style.left=-aLi1[0].offsetWidth*iNow+'px';
//定時(shí)器
var timer = null;
//克隆第一張圖片 添加在ul的最后面
var oLi1 = aLi1[0].cloneNode(true);
//克隆最后一張圖片 添加在ul的最前面
var oLi2 = aLi1[aLi1.length-1].cloneNode(true);
oUl.appendChild(oLi1);
oUl.insertBefore(oLi2,aLi1[0]);
oUl.style.width = aLi1[0].offsetWidth*aLi1.length+"px";
//鼠標(biāo)移入tab: 關(guān)閉定時(shí)器,左右按鈕顯示
oTab.onmouseover = function(){
clearInterval(timer);
prev.style.display = 'block';
next.style.display = 'block';
}
//鼠標(biāo)移出tab: 開(kāi)啟定時(shí)器,左右按鈕隱藏
oTab.onmouseout = function(){
timer = setInterval(function(){
toNext();
},2000);
prev.style.display = 'none';
next.style.display = 'none';
}
//點(diǎn)擊小圓點(diǎn)
for(var i=0;i<aLi2.length;i++){
(function(index){
aLi2[index].onclick = function(){
iNow = index+1;
for(var i=0;i<aLi2.length;i++){
aLi2[i].className = '';
}
aLi2[index].className = 'on';
animate(oUl,{left: -iNow*aLi1[0].offsetWidth});
}
})(i);
}
//上一個(gè)
prev.onclick=function(){
iNow--;
animate(oUl,{left: -iNow*aLi1[0].offsetWidth},{complete:function(){
if(iNow == 0){
iNow = aLi1.length-2;
oUl.style.left=-aLi1[0].offsetWidth*iNow+'px';
}
for(var i=0;i<aLi2.length;i++){
aLi2[i].className = '';
}
aLi2[iNow-1].className = 'on';
}});
}
//下一個(gè)
next.onclick=function(){
toNext();
}
function toNext(){
iNow++;
animate(oUl,{left: -iNow*aLi1[0].offsetWidth},{complete:function(){
if(iNow == aLi1.length-1){
iNow = 1;
oUl.style.left=-aLi1[0].offsetWidth*iNow+'px';
}
for(var i=0;i<aLi2.length;i++){
aLi2[i].className = '';
}
aLi2[iNow-1].className = 'on';
}});
}
//設(shè)置定時(shí)器
timer = setInterval(function(){
toNext();
},2000);
}
封裝的animate()運(yùn)動(dòng)框架
/*
* 參數(shù)說(shuō)明:
* obj: 運(yùn)動(dòng)對(duì)象
* json(json形式): 需要修改的屬性
* options(json形式):
* duration: 運(yùn)動(dòng)時(shí)間
* easing: 運(yùn)動(dòng)方式(勻速、加速、減速)
* complete: 運(yùn)動(dòng)完成后執(zhí)行的函數(shù)
*/
function animate(obj,json,options){
var options=options || {};
var duration=options.duration || 500; //運(yùn)動(dòng)時(shí)間,默認(rèn)值為500ms;
var easing=options.easing || 'linear'; //運(yùn)動(dòng)方式,默認(rèn)為linear勻速
var start={};
var dis={};
for(var name in json){
start[name]=parseFloat(getStyle(obj,name)); //起始位置
dis[name]=json[name]-start[name]; //總距離
}
var count=Math.floor(duration/30); //總次數(shù)
var n=0; //次數(shù)
clearInterval(obj.timer);
obj.timer=setInterval(function(){
if(n>count){
clearInterval(obj.timer);
options.complete && options.complete();
}else{
for(var name in json){
switch(easing){
//勻速
case 'linear':
var a=n/count;
var cur=start[name]+dis[name]*a; //當(dāng)前位置
break;
//加速
case 'ease-in':
var a=n/count;
var cur=start[name]+dis[name]*a*a*a;
break;
//減速
case 'ease-out':
var a=1-n/count;
var cur=start[name]+dis[name]*(1-a*a*a);
break;
}
if(name=='opacity'){
obj.style.opacity=cur;
obj.style.filter = 'alpha(opacity='+cur*100+')'; //兼容IE8及以下
}else{
obj.style[name]=cur+'px';
}
}
}
n++;
},30);
}
//獲取非行間樣式
function getStyle(obj,sName){
return (obj.currentStyle || getComputedStyle(obj,false))[sName];
}
以上這篇原生JS實(shí)現(xiàn)圖片無(wú)縫滾動(dòng)方法(附帶封裝的運(yùn)動(dòng)框架)就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- JS實(shí)現(xiàn)運(yùn)動(dòng)緩沖效果的封裝函數(shù)示例
- JS實(shí)現(xiàn)勻速與減速緩慢運(yùn)動(dòng)的動(dòng)畫效果封裝示例
- 原生JS封裝animate運(yùn)動(dòng)框架的實(shí)例
- 原生JS實(shí)現(xiàn)風(fēng)箱式demo,并封裝了一個(gè)運(yùn)動(dòng)框架(實(shí)例代碼)
- 原生js封裝運(yùn)動(dòng)框架的示例講解
- JS實(shí)現(xiàn)勻速運(yùn)動(dòng)的代碼實(shí)例
- 使用JavaScript 實(shí)現(xiàn)對(duì)象 勻速/變速運(yùn)動(dòng)的方法
- JavaScript中的勻速運(yùn)動(dòng)和變速(緩沖)運(yùn)動(dòng)詳細(xì)介紹
- 原生javascript實(shí)現(xiàn)勻速運(yùn)動(dòng)動(dòng)畫效果
- 淺談Javascript中勻速運(yùn)動(dòng)的停止條件
- js指定步長(zhǎng)實(shí)現(xiàn)單方向勻速運(yùn)動(dòng)
- 原生javascript運(yùn)動(dòng)函數(shù)的封裝示例【勻速、拋物線、多屬性的運(yùn)動(dòng)等】
相關(guān)文章
JavaScript時(shí)間與時(shí)間戳的轉(zhuǎn)換操作實(shí)例分析
這篇文章主要介紹了JavaScript時(shí)間與時(shí)間戳的轉(zhuǎn)換操作,結(jié)合實(shí)例形式分析了javascript日期與時(shí)間戳轉(zhuǎn)換相關(guān)函數(shù)與操作技巧,需要的朋友可以參考下2018-12-12
基于javascript實(shí)現(xiàn)按圓形排列DIV元素(二)
本篇文章主要介紹基于javascript實(shí)現(xiàn)按圓形排列DIV元素的方法,此文著重于介紹怎樣實(shí)現(xiàn)的按圓形排列DIV元素的運(yùn)動(dòng)原理和實(shí)現(xiàn)效果代碼,需要的朋友來(lái)看下吧2016-12-12
bootstrap table支持高度百分比的實(shí)例代碼
這篇文章給大家介紹了bootstrap table支持高度百分比的實(shí)例代碼,通過(guò)更改BootstrapTable.prototype.resetView 方法,以支持高度百分比定義,適應(yīng)不同高度屏幕,感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧2018-02-02
Some tips of wmi scripting in jscript (1)
Some tips of wmi scripting in jscript (1)...2007-04-04
基于JS正則表達(dá)式實(shí)現(xiàn)模板數(shù)據(jù)動(dòng)態(tài)渲染(實(shí)現(xiàn)思路詳解)
這篇文章主要介紹了基于JS正則表達(dá)式實(shí)現(xiàn)模板數(shù)據(jù)動(dòng)態(tài)渲染 ,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03
JavaScript ECMA-262-3 深入解析.第三章.this
在這篇文章里,我們將討論跟執(zhí)行上下文直接相關(guān)的更多細(xì)節(jié)。討論的主題就是this關(guān)鍵字2011-09-09

