預(yù)備知識:
- flex 的使用
- js基礎(chǔ)語法
- jQuery的基本使用
-
setInterval()
定時(shí)器的使用
輪播的原理
原理:窗口不動(dòng)圖片動(dòng)!
好比是看電視一樣,外層一個(gè)小窗口绍坝,里面的圖片一幀一幀的變化,方向可以自己調(diào)試選擇核芽。
具體實(shí)現(xiàn)方法為:
? 讓圖片并排排列好榨婆,然后讓在視口以外的圖片隱藏,每次顯示不同的圖片的時(shí)候修改其CSS以控制器位置的變化氮唯,實(shí)現(xiàn)輪播鉴吹。
第一步:手動(dòng)添加圖片切換效果
- 寫好基本的結(jié)構(gòu)(窗口、圖片惩琉、具體每一張圖片)
- 使用 flex 實(shí)現(xiàn)圖片橫向布局豆励,
- 在flex中使用
align-items:flex-start;
解決圖片壓縮問題
如果不是用這個(gè)樣式設(shè)定,那么圖片的布局將會(huì)隨著窗口的大小而改變?yōu)榭v向布局和橫向布局 - 給
.window
定寬高琳水,使用overflow:hidden
將其他圖片隱藏 - 使用
transform:translateX(n px)
改變參數(shù)n的值以改變圖片的位置
代碼為
<style>
.images{
border:1px solid red;
display:flex;
align-items:flex-start;
transform:translateX(-600px)
}
.window{
width:300px;
height:207px;
overflow:hidden;
border:1px solid green;
}
</style>
</head>
<body>
<div class="window">
<div class="images">
<img src="https://i.loli.net/2017/12/27/5a430f3034252.png" width="300px">
<img src="https://i.loli.net/2017/12/27/5a430f3040f46.png" alt="dog3" width="300px" >
<img src="https://i.loli.net/2017/12/27/5a430f30423a2.png" width="300px" alt="ddog2">
</div>
</div>
</body>
第二步:使用jQuery肆糕、按鈕控制和過渡效果
我們使用按鈕點(diǎn)擊控制圖片的位置,使用到j(luò)Query 知識
- 給images添加id為
id=images
- 給定
<button id=p1/p2/p3>
- 引入jQuery在孝,使用 jQuery 控制 CSS 樣式
- 給images添加過渡效果
transtion:transform 0.3s
注意:這里不是給具體的圖片添加過渡效果诚啃,而是給外層的images
添加,因?yàn)榘讶龔?image 合并成一張圖片了 - 注意細(xì)節(jié):
$(id)
私沮、$('#id')
和$('id')
之間是有區(qū)別的始赎,最后一個(gè)寫法是錯(cuò)誤的,前2個(gè)才是正確的,且前2個(gè)意思相同造垛;
<head>
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
<style>
.images{
border:1px solid red;
display:flex;
align-items:flex-start;
transition:transform 0.3s; //添加過渡效果
}
.window{
width:300px;
height:207px;
overflow:hidden;
border:1px solid green;
}
</style>
</head>
<body>
<div class="window">
<div class="images" id="images"> //設(shè)置id為 images以便于后面 jQuery 可以獲取
<img src="https://i.loli.net/2017/12/27/5a430f3034252.png" width="300px">
<img src="https://i.loli.net/2017/12/27/5a430f3040f46.png" alt="dog3" width="300px" >
<img src="https://i.loli.net/2017/12/27/5a430f30423a2.png" width="300px" alt="ddog2">
</div>
</div>
<button id="p1">第1張</button>
<button id="p2">第2張</button>
<button id="p3">第3張</button>
<script>
$(p1).on('click',function(){
$(images).css({
transform:'translateX(0)'
})
})
$(p2).on('click',function(){
$(images).css({
transform:'translateX(-300px)'
})
})
$(p3).on('click',function(){
$(images).css({
transform:'translateX(-600px)'
})
})
</script>
</body>
可能出現(xiàn)的問題:即點(diǎn)擊切換圖片的時(shí)候魔招,圖片可能會(huì)晃動(dòng),具體是什么原因呢五辽?
排查img办斑、button、寬高等因素后杆逗,發(fā)現(xiàn)原因在
transform:translateX(n px)
或者是瀏覽器是否放大或縮小了比例乡翅,此時(shí)可以使用
margin-left: n px
來替換transform:translateX(n px)
獲得同樣的效果但是,注意個(gè)問題罪郊,在使用 jQuery 控制 CSS 樣式中蠕蚜,如果屬性有
-
需要使用引號包裹起來,即寫法為//錯(cuò)誤寫法 $(p1).on(click,function(){ $(images).css({ margin-left:'-300px' }) }) // 正確寫法 $(p1).on(click,function(){ $(images).css({ 'margin-left':'-300px' }) })
第三步:輪播封裝悔橄,支持無限張圖片輪播
? 前面2步我們知道了輪播的基本思路就是點(diǎn)擊按鈕更改對應(yīng)的CSS來得到輪播的效果靶累,但是我們發(fā)現(xiàn)其中有很多的的重復(fù)代碼,而且有些代碼之間的有一定的邏輯關(guān)系癣疟,此時(shí)我們可以使用jQuery結(jié)合CSS進(jìn)行封裝
封裝 1.0
<body>
//略
</body>
<style>
images.position-1{
margin-left:0px;
}
images.position-2{
margin-left:-300px;
}
images.position-3{
margin-left:-600px;
}
</style>
<script>
$(p1).on('click',function(){
$(images).removeClass('position-2').removeClass('position-3').addClass('position-1')
})
$(p1).on('click',function(){
$(images).removeClass('position-1').removeClass('position-3').addClass('position-2')
})
$(p3).on('click',function(){
$(images).removeClass('position-2').removeClass('position-1').addClass('position-3')
})
</script>
? 上面雖然是簡單的實(shí)現(xiàn)了基本的輪播封裝挣柬,即如果有更多的圖片,那么就要寫更多的CSS争舞,對應(yīng)的jQuery也要增加凛忿,事實(shí)上代碼都是一樣的,只是參數(shù)值不同竞川,因此我們可以再一次封裝店溢;
封裝 2.0
? 要實(shí)現(xiàn)無限張圖片的輪播,那么就要獲得每一張圖片的id委乌,同時(shí)修改對應(yīng)id的CSS樣式
-
DOM 對象封裝成jQuery對象
獲得一個(gè)DOM對象床牧,如何把它封裝成一個(gè)jQuery對象?//如果獲得一個(gè)DOM 對象為 buttons[i] 遭贸,將其封裝成 jQuery對象為 $(buttons[i])
-
for 循環(huán)遍歷得到節(jié)點(diǎn)的位置
要獲取一個(gè)元素在它父類元素的子節(jié)點(diǎn)中排第幾個(gè)戈咳,如果是在DOM API中,就是使用for
循環(huán)來獲取x var n //s節(jié)點(diǎn)的下標(biāo) var children = s.parentNode.children //得到s節(jié)點(diǎn)的父元素的所有子節(jié)點(diǎn) for(let i=0;i<children.length;i++){ if(children[i] === s){ n = i // s 的下標(biāo)值 break; } }
$(id).index()
的使用
事實(shí)上壕吹,在jQuery中已經(jīng)對其進(jìn)行了封裝著蛙,直接調(diào)用使用$(id).index()
即可得到 id 在其父元素的子節(jié)點(diǎn)的第幾個(gè)。target
和currentTarget
的使用與區(qū)別字符串拼接
transform:'translate('+n+'px)'
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
<style>
.images{
border:1px solid red;
display:flex;
align-items:flex-start;
transition:transform 0.3s;
}
.window{
width:300px;
height:207px;
overflow:hidden;
border:1px solid green;
}
</style>
</head>
<body>
<div class="window">
<div class="images" id="images">
<img src="https://i.loli.net/2017/12/27/5a430f3034252.png" width="300px">
<img src="https://i.loli.net/2017/12/27/5a430f3040f46.png" alt="dog3" width="300px" >
<img src="https://i.loli.net/2017/12/27/5a430f30423a2.png" width="300px" alt="ddog2">
</div>
</div>
<span id="allButtons">
<span id="p1">第1張</span>
<span id="p2">第2張</span>
<span id="p3">第3張</span>
</span>
<script>
var allButtons = $('#allButtons>span')
for(let i=0;i<allButtons.length;i++){
$(allButtons[i]).on('click',function(xxx){
var index = $(xxx.currentTarget).index()
var n = index * -300 //定義個(gè)偏移數(shù)值耳贬,即每個(gè)不同的子節(jié)點(diǎn)對應(yīng)的偏移量不同
$('#images').css({
transform:'translate('+n+'px)' //使用字符串拼接
})
})
}
</script>
</body>
</html>
其中踏堡,jQuery代碼縮短為幾行就實(shí)現(xiàn)了任意數(shù)量的輪播,核心代碼如下:
<script>
var allButtons = $('#allButtons>span') //獲得span節(jié)點(diǎn)咒劲,通過span節(jié)點(diǎn)切換到對應(yīng)的圖片
for(let i=0;i<allButtons.length;i++){ //遍歷得到每個(gè)span節(jié)點(diǎn)
$(allButtons[i]).on('click',function(xxx){
var index = $(xxx.currentTarget).index()
var n = index * -300 //定義個(gè)偏移數(shù)值顷蟆,即每個(gè)不同的子節(jié)點(diǎn)對應(yīng)的偏移量不同
$('#images').css({
transform:'translate('+n+'px)' //使用字符串拼接
})
})
}
</script>
-
transform:translate(npx)
===transform:translateX(npx)
?上面我們發(fā)現(xiàn)诫隅,及時(shí)使用
transform:translate(npx)
也能得到transform:translateX(npx)
相同的效果,那么這兩個(gè)屬性是等價(jià)的嗎帐偎?
答案是肯定的逐纬,具體參考 translate-mdn
封裝 3.0 實(shí)現(xiàn)自動(dòng)播放
原理:定時(shí)器的使用
-
setInterval
的使用
首先,我們每隔1秒打印出一個(gè)數(shù)字var n = 0 setInterval(()=>{ n += 1 console.log(n) },1000)
? 然后削樊,我們想豁生,既然可以每隔一秒打印出一個(gè)數(shù),是否可以每隔一秒點(diǎn)擊下對應(yīng)的
span
呢 漫贞?當(dāng)然可以
但是沛硅,有一個(gè)問題,因?yàn)閳D片的數(shù)量是有限的個(gè)數(shù)绕辖,那么圖片就要循環(huán)播放,同時(shí)意味著要循環(huán)點(diǎn)擊擂红,此時(shí)就要使用到 求余var n =0 //定義一個(gè)變量 var size = allButtons.length //獲得span的個(gè)數(shù) setInterval(()=>{ //定時(shí)器 n += 1 allButtons.eq(n%size).trigger('click').addClass('red').siblings('.red').removeClass('red') },1000)
?
allButtons.eq(n%3)
找出對應(yīng)的DOM仪际,并且把對應(yīng)的DOM封裝成對應(yīng)的jQuery對象使用
trigger()
執(zhí)行事件.siblings('.red')
找到allButtons.eq(n%size)
的CSS樣式為red
的兄弟,注意這里不是一個(gè)類名昵骤,而是一個(gè)選擇器siblings('.red')
.removeClass('red')
上一步中找到對應(yīng)的兄弟树碱,移除他們的red
樣式
最終效果:
//js代碼如下
var allButtons = $('#allButtons>span')
for(let i=0;i<allButtons.length;i++){
$(allButtons[i]).on('click',function(xxx){
var index = $(xxx.currentTarget).index()
var n = index * -300
$('#images').css({
transform:'translateX('+n+'px)'
// transform:'translate('+n+'px)'
})
})
}
// 定時(shí)器實(shí)現(xiàn)自動(dòng)輪播
var n =0
var size = allButtons.length
setInterval(()=>{
n += 1
allButtons.eq(n%size).trigger('click').addClass('red').siblings('.red').removeClass('red')
},1000)
封裝4.0 鼠標(biāo)事件的介入
? 前面計(jì)次封裝實(shí)現(xiàn)了簡單的輪播和輪播的優(yōu)化,由點(diǎn)擊按鈕輪播到自動(dòng)輪播变秦,那么成榜,還有一種情況沒有考慮進(jìn)去,就是鼠標(biāo)移入和移除的情況下蹦玫,圖片應(yīng)該是不動(dòng)赎婚,然后恢復(fù)到原來的動(dòng)作的。
? 這樣樱溉,就要對定時(shí)器的代碼進(jìn)行簡單的修改挣输。
原理:鼠標(biāo)移入和移出是相對于圖片顯示窗口的,即
.window
福贞,所以要對.window
進(jìn)行事件監(jiān)聽
var timeId = setInterval(()=>{
n += 1;
allButtons.eq(n%size).trigger('click').addClass('red').siblings('.red').removeClass('red')
},1000) //對setInterval進(jìn)行封裝
$('.window').on('mouseenter',function(){
window.clearInterval(timeId)
})
$('.window').on('mouseleave',function(){
timeId = setInterval(()=>{
n += 1;
allButtons.eq(n%size).trigger('click').addClass('red').siblings('.red').removeClass('red')
},1000)
})
參考鏈接: