原生js選項卡的幾種寫法,整片文章我會由簡及難的描述幾種常用的原生選項卡的寫法;
Improve little by little every day!
1>基本選項卡:
思路:循環中先清除再添加,注意this的指向和自定義屬性的應用
html代碼:
<div id="tab">
<input class="on" type="button" value="aaa">
<input type="button" value="bbb">
<input type="button" value="ccc">
<div class="active">111</div>
<div>222</div>
<div>333</div>
</div>
css代碼:
#tab .on{
background:skyblue;
}
#tab div{
width: 200px;
height: 200px;
background:#ccc;
display:none;
}
#tab .active{
display:block;
}
js代碼:
window.onload=function(){
var oTab=document.getElementById('tab');
var aBtn=oTab.getElementsByTagName('input');
var aDiv=oTab.getElementsByTagName('div');
for(var i=0;i<aBtn.length;i++){
aBtn[i].index=i;
aBtn[i].onclick=function(){
for(var i=0;i<aBtn.length;i++){
aBtn[i].className='';
aDiv[i].className='';
}
this.className='on';
aDiv[this.index].className='active';
};
}
};
2>無縫滾動選項卡
布局思路:ul中圖片,在0.jpg-4.jpg前后分別添加一尾一頭的圖片。當圖片(ul)向前運動到4.jpg的時候繼續向前運動,當運動到最后一張0.jpg一結束的時候瞬間把ul拉回到第二張圖片的位置(0.jpg),然后在繼續向前運動;反之,當圖片向后運動到第一張圖片(4.jpg)的時候,運動一結束,瞬間將圖片(ul)拉倒倒數第二張(4.jpg)的位置,這樣便形成了無縫滾動;
布局的重點:
cont為遮罩層,pre和next組成了一個遮罩覆蓋在可視圖片之上,當鼠標點擊可視圖片左半部分的時候,圖片向前運動;當鼠標點擊可視區右半部分的時候,圖片向后運動;
js代碼中添加了一個iNow,用來對應當前正常照片的位置,並與下面ol中li圓點相對應;iNow還有一個作用是與ul的移動位置相關聯;
js需要注意的是判斷iNow的值來循環圖片
html代碼:
<div id="tab">
<ul>
<li><img src="img/4.jpg" alt=""></li>
<li><img src="img/0.jpg" alt=""></li>
<li><img src="img/1.jpg" alt=""></li>
<li><img src="img/2.jpg" alt=""></li>
<li><img src="img/3.jpg" alt=""></li>
<li><img src="img/4.jpg" alt=""></li>
<li><img src="img/0.jpg" alt=""></li>
</ul>
<div id="cont">
<div class="pre"><span>向左</span></div>
<div class="next"><span>向右</span></div>
<ol>
<li class="on"></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ol>
</div>
</div>
css代碼:
*{
padding: 0;
margin: 0;
list-style:none;
}
#tab{
width: 300px;
height: 172px;
position:relative;
margin:100px auto;
overflow:hidden;
}
#tab ul{
width:2100px;
overflow:hidden;
position:absolute;
top: 0;
left: 0px;
}
#tab ul li{
width: 300px;
float:left;
}
#tab ul li img{
width: 300px;
}
#cont{
width: 300px;
height: 172px;
position:absolute;
top:0;
left: 0;
}
#cont div{
width: 150px;
height: 100%;
float:left;
display:none;
}
#cont div span{
width: 40px;
height: 40px;
background:rgba(0,0,0,0.2);
text-align:center;
line-height: 40px;
font-size:20px;
color:#fff;
position:absolute;
top:50%;
margin-top:-20px;
}
#cont .pre span{
left:0;
}
#cont .next span{
right:0;
}
#cont ol{
width: 100px;
position:absolute;
left: 100px;
bottom:10px;
}
#cont ol li{
width: 10px;
height: 10px;
background:#ccc;
border-radius:50%;
margin:5px;
float:left;
}
#cont ol .on{
background:red;
}
js代碼:
這里我加入了一個自己寫的move運動函數;之后我會單獨寫一篇關於這個運動函數封裝的思想的文章;這里請先將這個運動函數文件引入你的js中;
<script src="move-end.js"></script>
window.onload=function(){
var oTab=document.getElementById('tab');
var oUl=oTab.getElementsByTagName('ul')[0];
var aLi=oUl.children;
var oCont=document.getElementById('cont');
var oBtn=oCont.getElementsByTagName('div');
var oBar=oCont.getElementsByTagName('ol')[0];
var aC=oBar.children;
//定位ul的初始位置
var iNow=1;
oUl.style.left=-aLi[0].offsetWidth*iNow+'px';
//當鼠標移入遮罩層,按鈕顯示,移出遮罩層,按鈕消失
oCont.onmouseover=function(){
oBtn[0].style.display='block';
oBtn[1].style.display='block';
};
oCont.onmouseleave=function(){
oBtn[0].style.display='none';
oBtn[1].style.display='none';
};
//圖片向前運動
function next(){
iNow--;
move(oUl,{left:-aLi[0].offsetWidth*iNow},{"complete":function(){
if(iNow==0){
iNow=aLi.length-2;
oUl.style.left=-aLi[0].offsetWidth*iNow+'px';
}
for(var i=0;i<aC.length;i++){
aC[i].className='';
}
aC[iNow-1].className='on';
}});
}
//向后運動
function pre(){
iNow++;
move(oUl,{left:-aLi[0].offsetWidth*iNow},{'complete':function(){
if(iNow==aLi.length-1){
iNow=1;
oUl.style.left=-aLi[0].offsetWidth*iNow+'px';
}
for(var i=0;i<aC.length;i++){
aC[i].className='';
}
aC[iNow-1].className='on';
}});
}
oBtn[0].onclick=function(){
pre();
};
oBtn[1].onclick=function(){
next();
};
};
move函數:
/* Created by Jason on 2016/9/7.
*/
function getStyle(obj,sName){
return (obj.currentStyle || getComputedStyle(obj,false))[sName];
}
function move(obj,json,options){
var options=options || {};
var duration=options.duration || 1000;
var easing=options.easing || 'linear';
var start={};
var dis={};
for(name in json){
start[name]=parseFloat(getStyle(obj,name));
dis[name]=json[name]-start[name];
}
//start {width:50,} dis {width:150}
//console.log(start,dis);
var count=Math.floor(duration/30);
var n=0;
clearInterval(obj.timer);
obj.timer=setInterval(function(){
if(n>count){
clearInterval(obj.timer);
options.complete && options.complete();
}else{
for(name in json){
switch(easing){
case 'linear':
var a=n/count;
var cur=start[name]+dis[name]*a;
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;
}else{
obj.style[name]=cur+'px';
}
}
}
n++;
},30);
}
今天先寫到這里,明天我會繼續完善選項卡之自動播放無縫選項卡;
