jQuery輪播(一)

效果預(yù)覽

預(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>

預(yù)覽鏈接

第二步:使用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>

預(yù)覽鏈接

可能出現(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è)。

  • targetcurrentTarget 的使用與區(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

封裝2.0-預(yù)覽鏈接

封裝 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)

封裝3.0-預(yù)覽效果

封裝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)
})

封裝4.0-預(yù)覽鏈接

參考鏈接:

輪播的原理-知乎

輪播案例

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末撩嚼,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子挖帘,更是在濱河造成了極大的恐慌完丽,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拇舀,死亡現(xiàn)場離奇詭異逻族,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)你稚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門瓷耙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來朱躺,“玉大人,你說我怎么就攤上這事搁痛〕げ螅” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵鸡典,是天一觀的道長源请。 經(jīng)常有香客問我,道長彻况,這世上最難降的妖魔是什么谁尸? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮纽甘,結(jié)果婚禮上良蛮,老公的妹妹穿的比我還像新娘。我一直安慰自己悍赢,他們只是感情好决瞳,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著左权,像睡著了一般皮胡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上赏迟,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天屡贺,我揣著相機(jī)與錄音,去河邊找鬼锌杀。 笑死甩栈,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的抛丽。 我是一名探鬼主播谤职,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼亿鲜!你這毒婦竟也來了允蜈?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤蒿柳,失蹤者是張志新(化名)和其女友劉穎饶套,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體垒探,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡妓蛮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了圾叼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蛤克。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡捺癞,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出构挤,到底是詐尸還是另有隱情髓介,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布筋现,位于F島的核電站唐础,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏矾飞。R本人自食惡果不足惜一膨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望洒沦。 院中可真熱鬧豹绪,春花似錦、人聲如沸申眼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽豺型。三九已至,卻和暖如春买乃,著一層夾襖步出監(jiān)牢的瞬間姻氨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工剪验, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留肴焊,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓功戚,卻偏偏與公主長得像娶眷,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子啸臀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,527評論 25 707
  • 話說清明節(jié)剛過届宠,大清早就有人給我發(fā)荔灣廣場靈異事件的視頻,一架梯子在自動(dòng)行走乘粒,仿佛有無形的力量操控其間豌注。這種事情...
    Mulcully閱讀 447評論 1 0
  • 我喜歡你 如清甜的雨絲 滴滴答答 滋潤在心里 我喜歡你 如清晨的陽光 明媚溫暖 照亮了心底 我喜歡你嗲嗲的聲音 如...
    初繾綣閱讀 198評論 0 0
  • 我大學(xué)畢業(yè)的時(shí)候回了一次家。 我媽幾年前已經(jīng)回來灯萍,跟爸一起在附近做散工轧铁,爸沒有再去挖煤了。 我們住的那個(gè)小鎮(zhèn)就在黑...
    糖卡torncat閱讀 1,056評論 5 3
  • 剛?cè)胧痔O果的時(shí)候不懂旦棉,用bash,然后CC跟我說齿风,用zsh呀药薯,我給你百度找一個(gè)配置,好用救斑。從此我就算是zsh的人了...
    BetaFun閱讀 1,153評論 0 0