美文网首页
task31 进阶:把轮播改成无缝轮播吧

task31 进阶:把轮播改成无缝轮播吧

作者: vivienYang2019 | 来源:发表于2019-05-17 19:50 被阅读0次

    1. 无缝的轮播怎么做

    什么是无缝轮播?


    有缝轮播.png

    从第一张到倒数第二张图片还好,但是从最后一张图片到第一张图片就有问题了,并没有从最后一张图片直接切换到第一张图片,而是经过了中间的图片慢慢过渡到第一张图片(第一张图片到最后一张图片也同理),这显然不是预期的效果。问题既然已经发现了,就要去解决它,那么如何才能达到从最后一张图片直接切换到第一张图片(或第一张到最后一张),也就是无缝的效果,答案很简单,我们需要多一张图片(这张图片和第一张图片是相同的)放在图片列表的最后!为什么需要这样一张图片,请往下看。
    我们在上面已经清楚要解决的就是首尾图片间的切换问题,所以在引入多一张图片之后,可以让轮播从倒数第二张图片(在没有引入图片之前的最后一张图片)切换到最后一张图片(新引入的图片)的动画完成之后,再瞬间跳转到第一张图片,请看下图(我把外面容器的overflow:hidden去掉了以便大家理解):


    无缝轮播原理.png
    • 把overflow:hidden加上,利用视觉差之后


      无缝轮播.png

    参考文档

    开始实现


    Emmet.png
    img[src="./$.png"][width=400[height=300][alert=图片]*5
    

    Emmet 语法


    image.png
    image.png
    box-sizing:border-box;//???什么意思
    

    box-sizing

    box-sizing.png 3s6s.png
    9s12s.png

    on('transitionend') 监听动画结束,让img回到可视window的右边
    one('transitionend') 只监听最近的一次,监听执行完一次后就把这个监听器给删了
    具体分析,拿3张图片测试要怎么移动,然后进行分析和抽象。
    进行分析和抽象,图片有3种状态:current,leave,enter(状态机的概念)

    • current:图片在当前可视window中
    • leave:图片离开可视window,在window的左侧
    • enter:图片进入可视window,在window的右侧

    有3种状态,对应可以写3个类
    css定义这3个类的位置等
    js负责改变每个img的类↓


    imgCss.png imgJs.png
    • 优化1-使用setInterval定时器↓
    $('.images > img:nth-child(1)').addClass('current')
    $('.images > img:nth-child(2)').addClass('enter')
    $('.images > img:nth-child(3)').addClass('enter')
    let n = 1
    setInterval(()=>{
      $(`.images > img:nth-child(${x(n)})`).removeClass('current').addClass('leave')
        .one('transitionend', (e)=>{
          $(e.currentTarget).removeClass('leave').addClass('enter')
        })
      $(`.images > img:nth-child(${x(n+1)})`).removeClass('enter').addClass('current')
      n += 1
    },3000)
    
    
    function x(n){
      if(n>3){
        n = n%3
        if (n===0){
          n =3
        }
      } // n = 1 2 3
      return n
    }
    
    • 优化2-封装成函数
    let n
    初始化()
    setInterval(()=>{
      makeLeave(getImage(n))
        .one('transitionend', (e)=>{
          makeEnter($(e.currentTarget))
        })
      makeCurrent(getImage(n+1))
      n += 1
    },3000)
    
    // 下面可以不看
    function getImage(n){
      return $(`.images > img:nth-child(${x(n)})`)
    }
    function x(n){
      if(n>3){
        n = n%3
        if (n===0){
          n =3
        }
      } // n = 1 2 3
      return n
    }
    function 初始化(){
      n = 1
      $(`.images > img:nth-child(${n})`).addClass('current')
        .siblings().addClass('enter')
    }
    function makeCurrent($node){
      return $node.removeClass('enter leave').addClass('current')
    }
    function makeLeave($node){
      return $node.removeClass('enter current').addClass('leave')
    }
    function makeEnter($node){
      return $node.removeClass('leave current').addClass('enter')
    }
    

    一个注意事项:current的z-index要比其他的大,因为从leave改变位置到enter位置会从current的区域经过

    .carouselWrapper .carouselBox > img.current{
      transform: translateX(0);
      z-index: 2;
    }
    

    2. DOM Events 知识

    事件的历史.png
    domLevel的版本
    dom level 2中的事件
    image.png
    https://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html image.png
    event flow, event capture, event bubbling(事件冒泡), mouse event, key events这些概念都是dom level 2中提出的,dom level3基本上没做修改,dom level 4还在草案阶段

    dom level 1的知识

    一道题,哪一个可以打印出hi?


    image.png

    答案:bcx
    为什么bc是对的?


    image.png
    为什么x是对的?
    image.png

    在html中的onclick要加括号'()'
    在js中的onclick不要加括号'()'

    dom level2的知识

    dom level1中的onclick和dom level 2中的addEventListener区别

    • onclick是一个属性,唯一的,会被覆盖


      onclick.png

      ——只会打印3

    • addEventListener是一个队列,先进先出


      addEventListener.png

    ——会打印出1和2,而且一定是先打印1再打印2,有顺序的


    removeEventListener.png

    ——只会打印出2,因为f1和f3在add后被remove掉了,xxx的click事件只剩f2监听了

    • jquery中的one是怎么实现的?


      image.png

      ——只会第一次点击的时候打印1,后面再次点击就不会打印1了(一次事件监听的实现)

    • 另一个例子,关于冒泡?


      image.png

      复杂的需要画图理解


      image.png
      image.png

    事件模型

    • true的走左边的队列(从上到下阶段,捕获阶段),false或不传的走右边的队列(从下到上阶段,冒泡阶段)

    • 先捕获,后冒泡

    • 如下,fn1是true,走左边,先执行。顺序是爷爷-儿子-爸爸


      事件模型.png
    • 最后一个结点是先捕获还是先冒泡??
      写的顺序 ???特例!!!就是写在点的元素本身上的event listener,不是按照先捕获后冒泡的顺序执行,而是按照写的顺序来执行


      image.png
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>事件模型</title>
      <style>
        div{
          padding: 30px;
          border: 1px solid salmon;
        }
      </style>
    </head>
    <body>
      <div id="grand1">
        爷爷
        <div id="parent1">
          爸爸
          <div id="child1">
            儿子
          </div>
        </div>
      </div>
      <script>
        // 1 当我点击儿子的时候,我是否点击了父亲和爷爷
        // yes
    
        // 2 当我点击儿子的时候,三个函数是否调用
        grand1.addEventListener('click',function fn1(){
          console.log('爷爷')
        })
        parent1.addEventListener('click',function fn2(){
          console.log('爸爸')
        })
        child1.addEventListener('click',function fn3(){
          console.log('儿子冒泡')
        },false)
        child1.addEventListener('click',function fn3(){
          console.log('儿子捕获')
        },true)
        // yes
    
        // 3 请问fn1,fn2,fn3的执行顺序
        // 1-2-3 or 3-2-1?
    
        // W3C 都可以
        // falsy值: false, 0, NaN, '', null, undefined
        // addEventListener不传第三个参数/传false 儿子-爸爸-爷爷
        // addEventListener第三个参数传true 爷爷-爸爸-儿子
    
        // 总结事件模型
        // true的走左边的队列(从上到下阶段,捕获阶段),
        // false或不传的走右边的队列(从下到上阶段,冒泡阶段)
        // 先捕获,后冒泡
        // 最后一个结点是先捕获还是先冒泡??
        // 写的顺序 ???特例!!!就是写在点的元素本身上的event listener,不是按照先捕获后冒泡的顺序执行,而是按照写的顺序来执行
      </script>
    </body>
    </html>
    

    相关文章

      网友评论

          本文标题:task31 进阶:把轮播改成无缝轮播吧

          本文链接:https://www.haomeiwen.com/subject/hexoaqtx.html