jQuery轮播(一)

效果预览

预备知识:

  • flex 的使用
  • js基础语法
  • jQuery的基本使用
  • setInterval()定时器的使用

轮播的原理

轮播的原理
轮播原理

原理:窗口不动图片动!

好比是看电视一样,外层一个小窗口,里面的图片一帧一帧的变化,方向可以自己调试选择。

具体实现方法为:

​ 让图片并排排列好,然后让在视口以外的图片隐藏,每次显示不同的图片的时候修改其CSS以控制器位置的变化,实现轮播。

第一步:手动添加图片切换效果

  • 写好基本的结构(窗口、图片、具体每一张图片)
  • 使用 flex 实现图片横向布局,
  • 在flex中使用align-items:flex-start;解决图片压缩问题
    如果不是用这个样式设定,那么图片的布局将会随着窗口的大小而改变为纵向布局和横向布局
  • .window 定宽高,使用 overflow:hidden将其他图片隐藏
  • 使用transform:translateX(n px) 改变参数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、按钮控制和过渡效果

我们使用按钮点击控制图片的位置,使用到jQuery 知识

  • 给images添加id为 id=images
  • 给定 <button id=p1/p2/p3>
  • 引入jQuery,使用 jQuery 控制 CSS 样式
  • 给images添加过渡效果 transtion:transform 0.3s
    注意:这里不是给具体的图片添加过渡效果,而是给外层的images 添加,因为把三张 image 合并成一张图片了
  • 注意细节:$(id)$('#id')$('id') 之间是有区别的,最后一个写法是错误的,前2个才是正确的,且前2个意思相同;
 <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">  //设置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>

预览链接

可能出现的问题:即点击切换图片的时候,图片可能会晃动,具体是什么原因呢?

排查img、button、宽高等因素后,发现原因在 transform:translateX(n px) 或者是浏览器是否放大或缩小了比例,

此时可以使用margin-left: n px 来替换 transform:translateX(n px) 获得同样的效果

但是,注意个问题,在使用 jQuery 控制 CSS 样式中,如果属性有 - 需要使用引号包裹起来,即写法为

//错误写法
$(p1).on(click,function(){
  $(images).css({
  margin-left:'-300px'
  })
})

// 正确写法
$(p1).on(click,function(){
  $(images).css({
 'margin-left':'-300px'
  })
})

第三步:轮播封装,支持无限张图片轮播

​ 前面2步我们知道了轮播的基本思路就是点击按钮更改对应的CSS来得到轮播的效果,但是我们发现其中有很多的的重复代码,而且有些代码之间的有一定的逻辑关系,此时我们可以使用jQuery结合CSS进行封装

封装 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>

​ 上面虽然是简单的实现了基本的轮播封装,即如果有更多的图片,那么就要写更多的CSS,对应的jQuery也要增加,事实上代码都是一样的,只是参数值不同,因此我们可以再一次封装;

封装 2.0

​ 要实现无限张图片的轮播,那么就要获得每一张图片的id,同时修改对应id的CSS样式

  • DOM 对象封装成jQuery对象
    获得一个DOM对象,如何把它封装成一个jQuery对象?

    //如果获得一个DOM 对象为 buttons[i] ,将其封装成 jQuery对象为 $(buttons[i])
    
  • for 循环遍历得到节点的位置
    要获取一个元素在它父类元素的子节点中排第几个,如果是在DOM API中,就是使用 for 循环来获取

     x var n //s节点的下标
     var children = s.parentNode.children  //得到s节点的父元素的所有子节点
     for(let i=0;i<children.length;i++){ 
      if(children[i] === s){  
            n = i  // s 的下标值   
            break;    
            }
        }
    
  • $(id).index() 的使用
    事实上,在jQuery中已经对其进行了封装,直接调用使用$(id).index()即可得到 id 在其父元素的子节点的第几个。

  • targetcurrentTarget 的使用与区别

  • 字符串拼接 transform:'translate('+n+'px)'

<!DOCTYPE html>
<html>
<head>
<script src="//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  //定义个偏移数值,即每个不同的子节点对应的偏移量不同
    $('#images').css({
      transform:'translate('+n+'px)'  //使用字符串拼接
    })
  })
}
  </script>
  
</body>
</html>

其中,jQuery代码缩短为几行就实现了任意数量的轮播,核心代码如下:

  <script>
  var allButtons =  $('#allButtons>span')  //获得span节点,通过span节点切换到对应的图片
  for(let i=0;i<allButtons.length;i++){   //遍历得到每个span节点
    $(allButtons[i]).on('click',function(xxx){ 
      var index = $(xxx.currentTarget).index()
      var n = index  * -300  //定义个偏移数值,即每个不同的子节点对应的偏移量不同
      $('#images').css({
        transform:'translate('+n+'px)'  //使用字符串拼接
      })
    })
  }
  </script>
  • transform:translate(npx) === transform:translateX(npx)

    ​上面我们发现,及时使用 transform:translate(npx) 也能得到 transform:translateX(npx) 相同的效果,那么这两个属性是等价的吗?
    答案是肯定的,具体参考 translate-mdn

封装2.0-预览链接

封装 3.0 实现自动播放

原理:定时器的使用

  • setInterval 的使用
    首先,我们每隔1秒打印出一个数字

    var n = 0
    setInterval(()=>{
      n += 1
      console.log(n)
    },1000)
    

    ​ 然后,我们想,既然可以每隔一秒打印出一个数,是否可以每隔一秒点击下对应的 span呢 ?当然可以
    但是,有一个问题,因为图片的数量是有限的个数,那么图片就要循环播放,同时意味着要循环点击,此时就要使用到 求余

    var n =0 //定义一个变量
    var size = allButtons.length  //获得span的个数
    setInterval(()=>{  //定时器
      n += 1
     allButtons.eq(n%size).trigger('click').addClass('red').siblings('.red').removeClass('red')
    },1000)
    

  • allButtons.eq(n%3) 找出对应的DOM,并且把对应的DOM封装成对应的jQuery对象

  • 使用trigger() 执行事件

  • .siblings('.red') 找到 allButtons.eq(n%size) 的CSS样式为 red 的兄弟,注意这里不是一个类名,而是一个选择器 siblings('.red')

  • .removeClass('red') 上一步中找到对应的兄弟,移除他们的 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)'
    })
  })
}

// 定时器实现自动轮播
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-预览效果

封装4.0 鼠标事件的介入

​ 前面计次封装实现了简单的轮播和轮播的优化,由点击按钮轮播到自动轮播,那么,还有一种情况没有考虑进去,就是鼠标移入和移除的情况下,图片应该是不动,然后恢复到原来的动作的。

​ 这样,就要对定时器的代码进行简单的修改。

原理:鼠标移入和移出是相对于图片显示窗口的,即 .window ,所以要对 .window 进行事件监听

var timeId = setInterval(()=>{
  n += 1;
 allButtons.eq(n%size).trigger('click').addClass('red').siblings('.red').removeClass('red')
},1000) //对setInterval进行封装

$('.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-预览链接

参考链接:

轮播的原理-知乎

轮播案例

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,061评论 25 707
  • 话说清明节刚过,大清早就有人给我发荔湾广场灵异事件的视频,一架梯子在自动行走,仿佛有无形的力量操控其间。这种事情...
    Mulcully阅读 453评论 1 0
  • 我喜欢你 如清甜的雨丝 滴滴答答 滋润在心里 我喜欢你 如清晨的阳光 明媚温暖 照亮了心底 我喜欢你嗲嗲的声音 如...
    初缱绻阅读 200评论 0 0
  • 我大学毕业的时候回了一次家。 我妈几年前已经回来,跟爸一起在附近做散工,爸没有再去挖煤了。 我们住的那个小镇就在黑...
    糖卡torncat阅读 1,063评论 5 3
  • 刚入手苹果的时候不懂,用bash,然后CC跟我说,用zsh呀,我给你百度找一个配置,好用。从此我就算是zsh的人了...
    BetaFun阅读 1,156评论 0 0