走馬燈這么基礎的效果,沒必要動用jQuery插件,jQuery本身就已經很強大了好么?
概述
首先構建一個靜態的ul,然后通過jQuery的.animate()方法來控制ul的margin來實現滾動,橫向滾動是控制margin-left
,縱向滾動則是控制margin-top
。動畫執行之后,在回調里巧妙的使用兩行語句就OK了。就這么簡單。
這個思路的優勢:
- 不借助CSS3,兼容性好。
- 不借助絕對定位,容易理解。
- 給
margin-left
設置負值屬于正當的CSS規范寫法,不屬于hack,兼容性可以放心。
下面先以橫向走馬燈為例。
橫向走馬燈
準備ul列表
由于要保證ul在margin-left
為負值的時候被父元素修剪,所以必須給ul搞一個父元素,而且父元素設置overflow:hidden;
。基于組件化的考慮,這個父元素應該是本組件的元素之一,所以,單獨搞一個父元素比較好。
HTML代碼:
<div class="content">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
<li>11</li>
<li>12</li>
<li>13</li>
<li>14</li>
<li>15</li>
<li>16</li>
<li>17</li>
<li>18</li>
<li>19</li>
<li>20</li>
<li>21</li>
<li>22</li>
<li>23</li>
<li>24</li>
</ul>
</div>
CSS代碼
.content{
width: 960px;
height:120px; /* 高度值一般就是一個li的盒子高度 */
overflow: hidden;
border: #333 solid 1px;
margin: auto;
}
.content ul{
margin: 0;
padding: 0;
width: 200%; /* 不一定非要200%,只要比100%多出一個li盒子寬度即可,但由于最極端的寬度也就是顯示一個li,再多出一個li,一共兩個li,所以最合適的值是200% */
height:100%;
}
.content ul li{
list-style: none;
float: left;
width: 108px;
height: 108px;
border: #ccc solid 1px;
display: block;
margin: 5px;
}
CSS代碼都是最簡化的,不解釋了。
JS代碼
引用jQuery:
<script src="http://cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
JS:
function scroll() {
$(".content ul").animate({"margin-left":"-120px"}, function() {
$(".content ul li:eq(0)").appendTo($(".content ul"));
$(".content ul").css({"margin-left": 0});
});
}
var scrolling = setInterval(scroll, 1000);
$('.content').hover(function() {
clearInterval(scrolling);
}, function() {
scrolling = setInterval(scroll, 1000);
});
這段JS就好玩了:
先說“-120px”是哪里算出來的:一個li的盒子寬度:108+5+5+1+1=120px。
然后說一下.animate()的參數:
animate(params,[speed],[easing],[fn])
params: 一組包含作為動畫屬性和終值的樣式屬性和及其值的集合
speed: 三種預定速度之一的字符串("slow","normal", or "fast")或表示動畫時長的毫秒數值(如:1000)
easing: 要使用的擦除效果的名稱(需要插件支持).默認jQuery提供"linear" 和 "swing".
fn:在動畫完成時執行的函數,每個元素執行一次。
JS的執行過程是:
1、先讓ul向左移動120px,簡單說就是,讓ul以.animate()的默認速度向左移動120px。這一步執行完成之后,界面暫時是這樣的,1號li已經出界,由于ul元素是被裁減的,所以1號li被隱藏:
2、執行回調第一句,把ul的第一個li挪到最后。這一步完成之后是這樣:
也就是說1號li現在已經到隊列的最后了,2號li到ul外了,3號li成了可見的排頭兵。不過3號成為排頭兵也只是一瞬間的輝煌,實際上人眼根本看不到。為什么是一瞬間的輝煌?往下看:
3、執行回調的第二句。將ul的margin-left
重置為0。完成之后是這樣:
也就是說,ul又挪回到了原位。2號li成了排頭兵。
問題:為什么ul挪到原位,沒有感到抖動?
答:因為JS執行的太快了,挪動li的排序和給ul還原位置都是幾乎同時的,而且是微秒級別的速度。
問題:想讓走馬燈向右走怎么辦?
答:首先說向右走不符合人眼的觀察習慣,我們閱讀都是從左往右讀的,所以向右走的走馬燈很少見。一定要向右走的話:
修改CSS:
.content ul li{
float: left; /* 這里left改成right */
}
修改JS:.animate({"margin-left":"-120px"})
的負號去掉。
縱向的走馬燈
縱向的話,設置每多少個li占一行并沒有難度,只需要調整li的寬度即可,一行撐不下自然會折行顯示。我們以一行四個li為例。
HTML代碼
不變。
CSS代碼
有兩處修改:
1、把li的寬度改成了960/4-1-1-5-5=228px。(如果你想一個li占一行,li的寬度就應該是960-1-1-5-5=948px。)
2、ul的寬度必須是100%。
.content{
width: 960px;
height:120px;
overflow: hidden;
border: #333 solid 1px;
margin:auto;
}
.content ul{
width: 100%;
height:100%;
margin: 0;
padding: 0;
}
.content ul li{
list-style: none;
float: left;
width: 228px;
height: 108px;
border:#ccc solid 1px;
display: block;
margin: 5px;
}
JS代碼
JS代碼也是略加改動,除了改成margin-top
之外,還有個.slice(0, 4)
:
function scroll() {
$(".content ul").animate({"margin-top":"-120px"}, function() {
$(".content ul li").slice(0,4).appendTo($(".content ul"));
$(".content ul").css({"margin-top": 0});
});
}
var scrolling = setInterval(scroll, 1000);
$('.content').hover(function() {
clearInterval(scrolling);
}, function() {
scrolling = setInterval(scroll, 1000);
});
問題:我想每兩行兩行的滾動,怎么辦?
答:首先margin-top
的值翻倍,然后.slice(0, 4)
改成.slice(0, 8)
。
問題:咱們這個走馬燈是走一步停一下,而常見的走馬燈是均勻的走,我想勻速走怎么辦?
答:往下看。
勻速走的走馬燈
以縱向的走馬燈為例。HTML代碼和CSS代碼都不變。JS代碼中animate
就加兩個參數。
JS代碼
function scroll() {
$(".content ul").animate({"margin-top":"-120px"}, 1000, 'linear', function() {
$(".content ul li").slice(0,4).appendTo($(".content ul"));
$(".content ul").css({"margin-top": 0});
});
}
//其他代碼略
改動在:.animate()
加了兩個參數:第一個參數,1000
,也就是跟定時器的時間間隔一致,第二個參數,'linear'
,也就是線性緩動。就這么簡單。