ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

交互简历案例(48)

2021-10-24 19:00:12  阅读:185  来源: 互联网

标签:简历 48 img zf transform let rem 交互 png


<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>珠峰培训</title>
    <!--IMPORT CSS-->
    <link rel="stylesheet" href="css/swiper-3.4.2.min.css">
    <link rel="stylesheet" href="css/index.min.css">

    <!--PRE-FIX-FREE:设置前缀的插件-->
    <script src="js/prefixfree.min.js"></script>

    <!--REM-->
    <script>
        //=>根据当前设备的宽度,动态计算出REM的换算比例,实现页面中元素的等比缩放
        ~function anonymous(window) {
            let computedREM = function computedREM() {
                let winW = document.documentElement.clientWidth,
                    desW = 640;
                if (winW >= 640) {
                    document.documentElement.style.fontSize = '100px';
                    return;
                }
                document.documentElement.style.fontSize = winW / desW * 100 + 'px';
            };
            computedREM();
            window.addEventListener('resize', computedREM);
        }(window);
    </script>
</head>
<body>
<!--外面套一层MAIN-BOX:控制当前页面的最大宽度,防止把做好的页面在PC端预览的时候满屏展示,这样字体和盒子大小等被肆意拉伸-->
<main class="mainBox">
    <!--LOADING-->
    <section class="loadingBox">
        <div class="title">
            <h1>珠峰培训</h1>
            <h2>H5场景交互型简历</h2>
        </div>
        <div class="progress">
            <div class="current"></div>
        </div>
    </section>

    <!--PHONE-->
    <section class="phoneBox">
        <h2>
            <img src="img/zf_phoneLogo.png" alt="">
            <span>00:00</span>
        </h2>
        <div class="answer">
            <div class="markMove"></div>
            <a href="javascript:;" class="markLink"></a>
        </div>
        <div class="hang">
            <a href="javascript:;" class="markLink"></a>
        </div>
        <!--AUDIO-->
        <audio src="audio/bell.mp3" loop preload="none" id="answerBell"></audio>
        <audio src="audio/say.mp3" preload="none" id="introduction"></audio>
    </section>

    <!--MESSAGE-->
    <section class="messageBox">
        <ul class="wrapper clearfix">
            <li class="self">
                <i class="arrow"></i>
                <img src="img/zf_messageStudent.png" alt="" class="pic">
                面试官您好,我叫周啸天,来自于河北承德,2019年毕业于XXX院校,学习的是XXX专业,到目前位置工作9年,先后担任高级软件工程师、总经理助理、技术经理和总监等职务
            </li>
            <li class="inter">
                <i class="arrow"></i>
                <img src="img/zf_messageLogo.png" alt="" class="pic">
                哇塞!好牛X啊!介绍一下自己的专业技能吧!
            </li>
            <!--后期会手动在这个位置增加一条新的记录-->
            <li class="self">
                <i class="arrow"></i>
                <img src="img/zf_messageStudent.png" alt="" class="pic">
                本人擅长:原生JS、ES6、Promise等设计模式、组件和插件封装,看过JQ源码,可以开发各种Hybrid混合APP...
            </li>
            <li class="inter">
                <i class="arrow"></i>
                <img src="img/zf_messageLogo.png" alt="" class="pic">
                框架会吗?我们公司现在使用的是VUE和REACT
            </li>
            <li class="self">
                <i class="arrow"></i>
                <img src="img/zf_messageStudent.png" alt="" class="pic">
                之前的公司使用的是REACT开发,个人对于REACT渲染原理、MVC模式、SPA单页面应用、DIFF差异渲染机制以及REDUX原理等都有研究,掌握的很熟练,对于VUE之前也做过,如果公司需要可以快速入手
            </li>
            <li class="inter">
                <i class="arrow"></i>
                <img src="img/zf_messageLogo.png" alt="" class="pic">
                webpack会吗?
            </li>
            <li class="self">
                <i class="arrow"></i>
                <img src="img/zf_messageStudent.png" alt="" class="pic">
                之前项目都是基于脚手架完成的,自己偶尔去修改一些webpack配置项
            </li>
            <li class="self">
                <i class="arrow"></i>
                <img src="img/zf_messageStudent.png" alt="" class="pic">
                不过目前正在深入研究,可以搭建简单的脚手架
            </li>
            <li class="self">
                <i class="arrow"></i>
                <img src="img/zf_messageStudent.png" alt="" class="pic">
                同时对于NODE/EXPRESS等后台开发也有所涉猎,只是没有应用到项目实战中,目前也正在研究,对这个比较感兴趣
            </li>
            <li class="inter">
                <i class="arrow"></i>
                <img src="img/zf_messageLogo.png" alt="" class="pic">
                你认为你的优点在于哪?和其他人对比,公司为啥要录用你!
            </li>
            <li class="self">
                <i class="arrow"></i>
                <img src="img/zf_messageStudent.png" alt="" class="pic">
                肯吃苦、肯加班、能力高、要钱少...这些够吗?
            </li>
            <li class="inter">
                <i class="arrow"></i>
                <img src="img/zf_messageLogo.png" alt="" class="pic">
                就是你啦,明天来上班!
            </li>
        </ul>

        <div class="keyBoard">
            <span></span><!--好的,马上介绍!-->
            <a href="javascript:;" class="submit"></a>
        </div>

        <audio src="audio/music.mp3" preload="none" loop id="demonMusic"></audio>
    </section>

    <!--CUBE-->
    <section class="cubeBox">
        <ul class="cube">
            <li><img src="img/zf_cube1.png" alt=""></li>
            <li><img src="img/zf_cube2.png" alt=""></li>
            <li><img src="img/zf_cube3.png" alt=""></li>
            <li><img src="img/zf_cube4.png" alt=""></li>
            <li><img src="img/zf_cube5.png" alt=""></li>
            <li><img src="img/zf_cube6.png" alt=""></li>
        </ul>
        <img src="img/zf_cubeTip.png" alt="" class="tip">
    </section>

    <!--DETAIL-->
    <section class="detailBox">
        <div class="swiper-container">
            <div class="swiper-wrapper">
                <!--PAGE1-->
                <div class="swiper-slide page1">
                    <dl>
                        <dt>课程大纲</dt>
                        <dd>
                            <em>01</em>
                            <a href="#">HTML(5)+CSS(3)+移动端响应式布局开发及相关插件的使用</a>
                        </dd>
                        <dd>
                            <em>02</em>
                            <a href="#">JS中的闭包及堆栈内存以及THIS的处理</a>
                        </dd>
                        <dd>
                            <em>03</em>
                            <a href="#">JS中的面向对象编程,可以基于面向对象封装组件和插件等</a>
                        </dd>
                        <dd>
                            <em>04</em>
                            <a href="#">ES6中的新特性及数组对象里面的常用方法</a>
                        </dd>
                        <dd>
                            <em>05</em>
                            <a href="#">JS中的同步异步编程及Promise设计模式</a>
                        </dd>
                        <dd>
                            <em>06</em>
                            <a href="#">JS中的事件委托及事件池及发布订阅设计模式</a>
                        </dd>
                        <dd>
                            <em>07</em>
                            <a href="#">JS中的DOM操作以及重绘和回流的优化</a>
                        </dd>
                        <dd>
                            <em>08</em>
                            <a href="#">HTTP交互及AJAX库的封装以及跨域数据共享</a>
                        </dd>
                        <dd>
                            <em>09</em>
                            <a href="#">VUE:VUE-CLI/VUE-ROUTER/VUEX/VUE ELEMENT等全家桶</a>
                        </dd>
                        <dd>
                            <em>10</em>
                            <a href="#">REACT:REACT-ROUTER/REACT-REDUX/DVA/AXIOS/ANT等</a>
                        </dd>
                        <dd>
                            <em>11</em>
                            <a href="#">辅助技能:NODE/WEBPACK/GIT等</a>
                        </dd>
                    </dl>
                </div>

                <!--PAGE2-->
                <div class="swiper-slide page2">
                    <h2>课程体系</h2>
                    <img src="img/zf_course1.png" alt="">
                    <img src="img/zf_course2.png" alt="">
                    <img src="img/zf_course3.png" alt="">
                    <img src="img/zf_course4.png" alt="">
                    <img src="img/zf_course5.png" alt="">
                    <img src="img/zf_course6.png" alt="">
                    <img src="img/zf_course.png" alt="">
                </div>

                <div class="swiper-slide"></div>
                <div class="swiper-slide"></div>
                <div class="swiper-slide"></div>
                <div class="swiper-slide"></div>
            </div>
        </div>
    </section>
</main>

<!--IMPORT JS-->
<script src="js/zepto.min.js"></script>
<script src="js/swiper-3.4.2.jquery.min.js"></script>
<script src="js/makisu.min.js"></script>
<script src="js/index.js"></script>
</body>
</html>

/*
 * 虽然移动端(安卓&IOS)上的浏览器大部分都是WEBKIT内核的,但是由于很多手机操作系统版本过低(尤其是安卓手机),导致很多CSS3新特性不能有效识别,此时我们使用的大部分CSS3属性都要写两套才能兼容(加前缀的在前,不加的在后)
 *  -webkit-animation
 *  animation
 *
 * 太麻烦了,不过没关系,有JS插件可以帮我们搞定这件事情 (prefixfree.min.js), 导入插件后,它会帮我们把所有需要加前缀的都加上
 */
@import "reset.min.less";
@import (reference) "common";

html {
  font-size: 100px; /*640PX设计稿尺寸中:1REM=100PX*/
}

html, body {
  position: relative;
  z-index: -4;
  height: 100%;
  overflow: hidden;
  background: #F4F4F4;
  font-family: "Microsoft JhengHei";
}

.mainBox {
  position: relative;
  z-index: -3;
  margin: 0 auto;
  max-width: 640px;
  height: 100%;
  background: #FFF;
}

.loadingBox, .phoneBox, .messageBox, .cubeBox, .detailBox {
  display: none;
  position: relative;
  height: 100%;
  overflow: hidden;
}

/*LOADING*/
.loadingBox {
  background: #000;

  .title {
    position: absolute;
    left: 0;
    top: 50%;
    margin-top: -2.2rem; /* -0.7(正中间)+1.5(距离中间靠上的位移) */
    width: 100%;
    height: 1.4rem;
    color: #FFF;

    h1 {
      line-height: .75rem;
      font-size: .5rem;
      text-align: center;
    }

    h2 {
      margin-top: .2rem;
      line-height: .45rem;
      text-align: center;
      letter-spacing: .04rem;
    }
  }

  .progress {
    position: absolute;
    top: 50%;
    left: 50%;
    margin: .85rem 0 0 -2.3rem;
    width: 4.6rem;
    height: .3rem;
    background: #FFF;

    .current {
      position: absolute;
      top: 0;
      left: 0;
      width: 0;
      height: 100%;
      background: -webkit-linear-gradient(left bottom, #5CB85C 0%, #5CB85C 25%, #74C274 25%, #74C274 50%, #5CB85C 50%, #5CB85C 75%, #74C274 75%, #74C274 100%);
      background: linear-gradient(left bottom, #5CB85C 0%, #5CB85C 25%, #74C274 25%, #74C274 50%, #5CB85C 50%, #5CB85C 75%, #74C274 75%, #74C274 100%);
      background-size: .3rem .3rem;
      animation: loadingMove .5s linear 0s infinite both;

      /*给CURRENT设置一个过渡动画:当我们在JS中控制它的宽度在变化的时候,给其一个平稳的过渡动画效果(而不是生硬的改变)*/
      transition: .3s;
    }
  }
}

@keyframes loadingMove {
  0% {
    background-position: 0 0;
  }
  100% {
    background-position: 0 -.3rem;
  }
}

/*PHONE*/
.phoneBox {
  z-index: -2;
  background: url("../img/zf_phoneBg.jpg") no-repeat;
  background-size: cover;

  h2 {
    margin-top: .5rem;
    text-align: center;

    img {
      display: inline-block;
      width: 2.62rem;
      height: 1.25rem;
    }

    span {
      display: none;
      margin-top: .1rem;
      line-height: .3rem;
      font-size: .3rem;
      color: #FFF;
      letter-spacing: .05rem;
    }
  }

  .answer {
    position: absolute;
    bottom: .3rem;
    left: 50%;
    margin-left: -2.6rem;
    width: 5.2rem;
    height: 3.6rem;
    background: url("../img/zf_phoneListen.png") no-repeat;
    background-size: 100% 100%;

    .markMove {
      position: absolute;
      right: -.06rem;
      bottom: .48rem;
      z-index: -1;
      box-sizing: border-box;
      width: 1.6rem;
      height: 1.6rem;
      border-radius: 50%;
      border: .03rem solid #0F0;
      animation: answerMove 1s linear infinite both;
    }

    .markLink {
      .markMove; //=>把MARK-MOVE的样式继承过来使用
      z-index: 1;
      border: none;
      border-radius: 0;
      animation: none;
    }
  }

  .hang {
    position: absolute;
    bottom: .3rem;
    left: 50%;
    margin-left: -2.6rem;
    width: 5.2rem;
    height: 6.59rem;
    background: url('../img/zf_phoneDetail.png') no-repeat;
    background-size: 100% 100%;

    //=>初始位置是在PHONE的底部(看不见:溢出内容隐藏),当点击接听按钮后,控制它从底下出来即可(JS中改变样式) “我们可以基于TRANSFORM改变样式的尽量不要使用传统的样式属性,因为TRANSFORM操作开启了浏览器的硬件加速,性能更高一些”
    transform: translateY(6.89rem);
    transition: .3s;

    .markLink {
      position: absolute;
      bottom: .26rem;
      left: 50%;
      z-index: 1;
      margin-left: -.8rem;
      width: 1.6rem;
      height: 1.6rem;
    }
  }
}

@keyframes answerMove {
  from {
    transform: scale(1.2);
  }
  to {
    transform: scale(0);
  }
}

/*MESSAGE*/
.messageBox {
  background: #EAEAEA;

  .wrapper {
    position: absolute;
    top: .2rem;
    left: 0;
    width: 100%;
    transition: .3s;

    li {
      position: relative;
      max-width: 3.6rem;
      padding: .25rem;
      margin-bottom: .4rem;
      border-radius: .1rem;
      line-height: .4rem;
      font-size: .26rem;
      opacity: 0;

      &.active {
        animation: messageListMove .3s linear both;
      }

      .pic {
        position: absolute;
        top: 0;
        width: .82rem;
        height: .82rem;
        border-radius: 50%;
      }

      .arrow {
        position: absolute;
        top: .2rem;
        width: .1rem;
        height: .2rem;
      }

      &.self {
        float: left;
        margin-left: 1.25rem;
        background: #FFF;
        border: .02rem solid #CACACA;

        .pic {
          left: -1rem;
        }

        .arrow {
          left: -.1rem;
          background: url("../img/zf_messageArrow1.png") no-repeat;
          background-size: 100% 100%;
        }
      }

      &.inter {
        float: right;
        margin-right: 1.25rem;
        background: #A2E45C;
        border: .02rem solid #96B474;

        .pic {
          right: -1rem;
        }

        .arrow {
          right: -.1rem;
          background: url("../img/zf_messageArrow2.png") no-repeat;
          background-size: 100% 100%;
        }
      }
    }
  }

  .keyBoard {
    position: absolute;
    left: 0;
    bottom: -.5rem;
    box-sizing: border-box;
    width: 100%;
    height: 5.16rem;
    background: url("../img/zf_messageKeyboard.png") no-repeat;
    background-size: 100% 100%;

    /*初始位置*/
    transform: translateY(3.7rem);
    transition: .3s;

    span {
      position: absolute;
      left: .9rem;
      top: .35rem;
      width: 4rem;
      height: .4rem;
      line-height: .4rem;
      font-size: .25rem;
    }

    .submit {
      display: none;
      position: absolute;
      right: .1rem;
      bottom: .6rem;
      width: 1.47rem;
      height: .74rem;
      background: url("../img/zf_messageChat.png") no-repeat;
      background-size: 100% 100%;
    }
  }
}

@keyframes messageListMove {
  from {
    transform: translateY(1rem);
    opacity: 0;
  }
  to {
    transform: translateY(0rem);
    opacity: 1;
  }
}

/*CUBE*/
.cubeBox {
  background: url("../img/zf_cubeBg.jpg") no-repeat;
  background-size: cover;

  .cube {
    position: absolute;
    top: 50%;
    left: 50%;
    margin: -2.55rem 0 0 -2.55rem;
    width: 5.1rem;
    height: 5.1rem;

    li {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;

      img {
        display: block;
        width: 100%;
        height: 100%;
      }
    }
  }

  .tip {
    position: absolute;
    bottom: .5rem;
    left: 50%;
    margin-left: -1.97rem;
    width: 3.94rem;
    height: .44rem;
  }
}

//=>在二维平面中实现3D效果
.cubeBox {
  //1.给需要实现3D变形元素所在的舞台设置“视距”(1000~2000)
  perspective: 2000px;

  .cube {
    //2.给需要操作的元素设置3D变形效果
    transform-style: preserve-3d;

    //3.基于TRASFORM实现3D变形
    li {
      &:nth-child(1) {
        transform: translateZ(2.55rem);
      }

      &:nth-child(2) {
        transform: translateZ(-2.55rem) rotateY(180deg);
      }

      &:nth-child(3) {
        transform: translateX(2.55rem) rotateY(90deg);
      }

      &:nth-child(4) {
        transform: translateX(-2.55rem) rotateY(-90deg);
      }

      &:nth-child(5) {
        transform: translateY(-2.55rem) rotateX(90deg);
      }

      &:nth-child(6) {
        transform: translateY(2.55rem) rotateX(-90deg);
      }
    }

    //4.给魔方一个初始的旋转角度,让其可以看到3D的效果(旋转后太大了,把魔方缩小一点)
    transform: scale(0.6) rotateX(-35deg) rotateY(35deg);
    transition: .3s; //=>后期让魔方旋转的时候有一个平稳的过渡动画效果
  }
}

/*DETAIL*/
.detailBox {
  .swiper-container {
    height: 100%;
    overflow: hidden;

    .swiper-slide {
      position: relative; /*每一个页面中的元素相对于自己的页面定位*/
      width: 100%;
      height: 100%;
      overflow: hidden;

      &:nth-child(2) {
        background: #FFF9C1;
      }

      &:nth-child(3) {
        background: #E45454;
      }

      &:nth-child(4) {
        background: #FAC471;
      }

      &:nth-child(5) {
        background: #FBFFE8;
      }

      &:nth-child(6) {
        background: #5975FF;
      }
    }
  }

  //=>PAGE1
  .page1 {
    dl {
      position: absolute;
      left: 50%;
      top: 50%;
      margin: -3.6rem 0 0 -2.7rem;
      width: 5.4rem;
      height: 7.2rem;

      dt, dd {
        box-sizing: border-box;
        height: .6rem;
        line-height: .6rem;
        background: #8FBB4C;
      }

      dt {
        text-align: center;
        font-size: .4rem;
        color: yellow;
      }

      dd {
        position: relative;
        border-top: .02rem dashed rgba(255, 255, 255, .3);

        em {
          position: absolute;
          left: .15rem;
          top: 50%;
          margin-top: -.21rem;
          width: .36rem;
          height: .42rem;
          line-height: .42rem;
          text-align: center;
          font-style: normal;
          font-size: .2rem;
          color: #FFF;
          background: url("../img/zf_outline.png") no-repeat;
          background-size: 100% 100%;
        }

        a {
          position: relative;
          display: block;
          margin-left: .66rem;
          font-size: .28rem;
          color: #000;

          text-overflow: ellipsis;
          white-space: nowrap;
          overflow: hidden;
        }

        em, a {
          z-index: 1000; //=>基于MAKISU实现3D折叠,为了保证内容不被折叠创建的SPAN遮住,我们需要把内容的层级提高
        }
      }
    }
  }

  //=>PAGE2
  .page2 {
    h2 {
      margin-top: .8rem;
      line-height: .9rem;
      text-align: center;
      font-size: .6rem;
      font-weight: normal;
      opacity: 0;
    }

    img {
      position: absolute;
      top: 50%;
      left: 50%;
      margin: -.5rem 0 0 -.5rem;
      width: 1rem;
      height: 1rem;
      opacity: 0;
      transition: .5s; //=>从中心到四周的动画我们可以基于TRANSITION完成

      &:nth-last-of-type(1) {
        margin: -.85rem 0 0 -.66rem;
        width: 1.32rem;
        height: 1.7rem;
      }
    }
  }

  #page2 {
    //=>PAGE2中的动画都写在ID选择器中
    h2 {
      animation: bounceInLeft 1s both;
    }

    img {
      &:nth-last-of-type(1) {
        animation: shake 1s both;
      }

      &:not(:nth-last-of-type(1)) {
        opacity: 1;
        animation: tada 1s .5s infinite both;
      }

      &:nth-of-type(1) {
        margin-top: -2.9rem; /*-.5-2.4*/
      }

      &:nth-of-type(2) {
        margin-top: -1.7rem;
        margin-left: 1.5rem;
      }

      &:nth-of-type(3) {
        margin-top: .7rem;
        margin-left: 1.5rem;
      }

      &:nth-of-type(4) {
        margin-top: 1.9rem;
      }

      &:nth-of-type(5) {
        margin-top: .7rem;
        margin-left: -2.5rem;
      }

      &:nth-of-type(6) {
        margin-top: -1.7rem;
        margin-left: -2.5rem;
      }
    }
  }

  /*
   * 基于SWIPER实现切换到哪一个页卡,让哪一个页卡中的后代元素有动画效果
   *   1.除了编写正常的CSS样式(都写在.PAGE-X中),把需要实现动画的元素所对应的动画写在#PAGE-X中(IE选择器优先级高)
   *   2.在SWIPER插件的某些回调函数中(例如:onTransitionEnd...)获取当前展示SLIDE的索引,根据索引为其设置对应的ID值,当前展示的SLIDE有ID,其余的没有ID
   *   3.为了保证切换到这一页面的时候,元素是动画运动出来的(也就是开始啥都看不见),每个元素都是基于动画显示的(在初始样式中.PAGE? 把所有需要运动的元素透明度设置为零  加ID后执行动画效果,在动画的最后一帧位置让透明度为1即可)
   */
}

@keyframes bounceInLeft {
  from,
  60%,
  75%,
  90%,
  to {
    -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
    animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
  }

  0% {
    opacity: 0;
    -webkit-transform: translate3d(-3000px, 0, 0);
    transform: translate3d(-3000px, 0, 0);
  }

  60% {
    opacity: 1;
    -webkit-transform: translate3d(25px, 0, 0);
    transform: translate3d(25px, 0, 0);
  }

  75% {
    -webkit-transform: translate3d(-10px, 0, 0);
    transform: translate3d(-10px, 0, 0);
  }

  90% {
    -webkit-transform: translate3d(5px, 0, 0);
    transform: translate3d(5px, 0, 0);
  }

  to {
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
    opacity: 1;
  }
}

@keyframes shake {
  from,
  to {
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }

  0% {
    opacity: 0;
  }

  100% {
    opacity: 1;
  }

  10%,
  30%,
  50%,
  70%,
  90% {
    -webkit-transform: translate3d(-10px, 0, 0);
    transform: translate3d(-10px, 0, 0);
  }

  20%,
  40%,
  60%,
  80% {
    -webkit-transform: translate3d(10px, 0, 0);
    transform: translate3d(10px, 0, 0);
  }
}

@keyframes tada {
  from {
    -webkit-transform: scale3d(1, 1, 1);
    transform: scale3d(1, 1, 1);
  }

  10%,
  20% {
    -webkit-transform: scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg);
    transform: scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg);
  }

  30%,
  50%,
  70%,
  90% {
    -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);
    transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);
  }

  40%,
  60%,
  80% {
    -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);
    transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);
  }

  to {
    -webkit-transform: scale3d(1, 1, 1);
    transform: scale3d(1, 1, 1);
  }
}

/*
 * 关于AUDIO的一些常用属性
 *    [属性]
 *    duration:播放的总时间(S)
 *    currentTime:当前已经播放的时间(S)
 *    ended:是否已经播放完成
 *    paused:当前是否为暂停状态
 *    volume:控制音量 (0~1)
 *
 *    [方法]
 *    pause() 暂停
 *    play() 播放
 *
 *    [事件]
 *    canplay:可以正常播放(但是播放过程中可能出现卡顿)
 *    canplaythrough:资源加载完毕,可以顺畅的播放了
 *    ended:播放完成
 *    loadedmetadata:资源的基础信息已经加载完成
 *    loadeddata:整个资源都加载完成
 *    pause:触发了暂停
 *    play:触发了播放
 *    playing:正在播放中
 */

/*LOADING*/
let loadingRender = (function () {
    let $loadingBox = $('.loadingBox'),
        $current = $loadingBox.find('.current');

    let imgData = ["img/icon.png", "img/zf_concatAddress.png", "img/zf_concatInfo.png", "img/zf_concatPhone.png", "img/zf_course.png", "img/zf_course1.png", "img/zf_course2.png", "img/zf_course3.png", "img/zf_course4.png", "img/zf_course5.png", "img/zf_course6.png", "img/zf_cube1.png", "img/zf_cube2.png", "img/zf_cube3.png", "img/zf_cube4.png", "img/zf_cube5.png", "img/zf_cube6.png", "img/zf_cubeBg.jpg", "img/zf_cubeTip.png", "img/zf_emploment.png", "img/zf_messageArrow1.png", "img/zf_messageArrow2.png", "img/zf_messageChat.png", "img/zf_messageKeyboard.png", "img/zf_messageLogo.png", "img/zf_messageStudent.png", "img/zf_outline.png", "img/zf_phoneBg.jpg", "img/zf_phoneDetail.png", "img/zf_phoneListen.png", "img/zf_phoneLogo.png", "img/zf_return.png", "img/zf_style1.jpg", "img/zf_style2.jpg", "img/zf_style3.jpg", "img/zf_styleTip1.png", "img/zf_styleTip2.png", "img/zf_teacher1.png", "img/zf_teacher2.png", "img/zf_teacher3.jpg", "img/zf_teacher4.png", "img/zf_teacher5.png", "img/zf_teacher6.png", "img/zf_teacherTip.png"];

    //=>RUN:预加载图片的
    let n = 0,
        len = imgData.length;
    let run = function run(callback) {
        imgData.forEach(item => {
            let tempImg = new Image;
            tempImg.onload = () => {
                tempImg = null;
                $current.css('width', ((++n) / len) * 100 + '%');

                //=>加载完成:执行回调函数(让当前LOADING页面消失)
                if (n === len) {
                    clearTimeout(delayTimer);
                    callback && callback();
                }
            };
            tempImg.src = item;
        });
    };

    //=>MAX-DELAY:设置最长等待时间(假设10S,到达10S我们看加载多少了,如果已经达到了90%以上,我们可以正常访问内容了,如果不足这个比例,直接提示用户当前网络状况不佳,稍后重试)
    let delayTimer = null;
    let maxDelay = function maxDelay(callback) {
        delayTimer = setTimeout(() => {
            clearTimeout(delayTimer);
            if (n / len >= 0.9) {
                $current.css('width', '100%');
                callback && callback();
                return;
            }
            alert('非常遗憾,当前您的网络状况不佳,请稍后在试!');
            // window.location.href = 'http://www.qq.com';//=>此时我们不应该继续加载图片,而是让其关掉页面或者是跳转到其它页面
        }, 10000);
    };

    //=>DONE:完成
    let done = function done() {
        //=>停留一秒钟再移除进入下一环节
        let timer = setTimeout(() => {
            $loadingBox.remove();
            clearTimeout(timer);

            phoneRender.init();
        }, 1000);
    };

    return {
        init: function () {
            $loadingBox.css('display', 'block');
            run(done);
            maxDelay(done);
        }
    }
})();

/*PHONE*/
let phoneRender = (function () {
    let $phoneBox = $('.phoneBox'),
        $time = $phoneBox.find('span'),
        $answer = $phoneBox.find('.answer'),
        $answerMarkLink = $answer.find('.markLink'),
        $hang = $phoneBox.find('.hang'),
        $hangMarkLink = $hang.find('.markLink'),
        answerBell = $('#answerBell')[0],
        introduction = $('#introduction')[0];

    //=>点击ANSWER-MARK
    let answerMarkTouch = function answerMarkTouch() {
        //1.REMOVE ANSWER
        $answer.remove();
        answerBell.pause();
        $(answerBell).remove();//=>一定要先暂停播放然后再移除,否则即使移除了浏览器也会播放着这个声音

        //2.SHOW HANG
        $hang.css('transform', 'translateY(0rem)');
        $time.css('display', 'block');
        introduction.play();
        computedTime();
    };

    //=>计算播放时间
    let autoTimer = null;
    let computedTime = function computedTime() {
        //=>我们让AUDIO播放,首先会去加载资源,部分资源加载完成才会播放,才会计算出总时间DURATION等信息,所以我们可以把获取信息放到CAN-PLAY事件中
        /*let duration = 0;
        introduction.oncanplay = function () {
            duration = introduction.duration;
        };*/
        autoTimer = setInterval(() => {
            let val = introduction.currentTime,
                duration = introduction.duration;
            //=>播放完成
            if (val >= duration) {
                clearInterval(autoTimer);
                closePhone();
                return;
            }
            let minute = Math.floor(val / 60),
                second = Math.floor(val - minute * 60);
            minute = minute < 10 ? '0' + minute : minute;
            second = second < 10 ? '0' + second : second;
            $time.html(`${minute}:${second}`);
        }, 1000);
    };

    //=>关闭PHONE
    let closePhone = function closePhone() {
        clearInterval(autoTimer);
        introduction.pause();
        $(introduction).remove();
        $phoneBox.remove();

        messageRender.init();
    };

    return {
        init: function () {
            $phoneBox.css('display', 'block');

            //=>播放BELL
            answerBell.play();
            answerBell.volume = 0.3;

            $answerMarkLink.tap(answerMarkTouch);
            $hangMarkLink.tap(closePhone);
        }
    }
})();

/*MESSAGE*/
let messageRender = (function () {
    let $messageBox = $('.messageBox'),
        $wrapper = $messageBox.find('.wrapper'),
        $messageList = $wrapper.find('li'),
        $keyBoard = $messageBox.find('.keyBoard'),
        $textInp = $keyBoard.find('span'),
        $submit = $keyBoard.find('.submit'),
        demonMusic = $('#demonMusic')[0];

    let step = -1,//=>记录当前展示信息的索引
        total = $messageList.length + 1,//=>记录的是信息总条数(自己发一条所以加1)
        autoTimer = null,
        interval = 1500;//=>记录信息相继出现的间隔时间

    //=>展示信息
    let tt = 0;
    let showMessage = function showMessage() {
        ++step;
        if (step === 2) {
            //=>已经展示两条了:此时我们暂时结束自动信息发送,让键盘出来,开始执行手动发送
            clearInterval(autoTimer);
            handleSend();
            return;
        }
        let $cur = $messageList.eq(step);
        $cur.addClass('active');
        if (step >= 3) {
            //=>展示的条数已经是四条或者四条以上了,此时我们让WRAPPER向上移动(移动的距离是新展示这一条的高度)
            /*let curH = $cur[0].offsetHeight,
                wraT = parseFloat($wrapper.css('top'));
            $wrapper.css('top', wraT - curH);*/
            //=>JS中基于CSS获取TRANSFORM,得到的结果是一个矩阵
            let curH = $cur[0].offsetHeight;
            tt -= curH;
            $wrapper.css('transform', `translateY(${tt}px)`);
        }
        if (step >= total - 1) {
            //=>展示完了
            clearInterval(autoTimer);
            closeMessage();
        }
    };

    //=>手动发送
    let handleSend = function handleSend() {
        $keyBoard.css({
            transform: 'translateY(0)'
        }).one('transitionend', () => {
            //=>TRANSITION-END:监听当前元素TRASITION动画结束的事件(并且有几个样式属性改变,并且执行了过渡效果,事件就会被触发执行几次 =>用ONE方法做事件绑定,只会让其触发一次)
            let str = '好的,马上介绍!',
                n = -1,
                textTimer = null;
            textTimer = setInterval(() => {
                let orginHTML = $textInp.html();
                $textInp.html(orginHTML + str[++n]);
                if (n >= str.length - 1) {
                    //=>文字显示完成
                    clearInterval(textTimer);
                    $submit.css('display', 'block');
                }
            }, 100);
        });
    };

    //=>点击SUBMIT
    let handleSubmit = function handleSubmit() {
        //=>把新创建的LI增加到页面中第二个LI的后面
        $(`<li class="self">
            <i class="arrow"></i>
            <img src="img/zf_messageStudent.png" alt="" class="pic">
            ${$textInp.html()}
        </li>`).insertAfter($messageList.eq(1)).addClass('active');
        $messageList = $wrapper.find('li');//=>重要:把新的LI放到页面中,我们此时应该重新获取LI,让MESSAGE-LIST和页面中的LI正对应,方便后期根据索引展示对应的LI

        //=>该消失的消失
        $textInp.html('');
        $submit.css('display', 'none');
        $keyBoard.css('transform', 'translateY(3.7rem)');

        //=>继续向下展示剩余的消息
        autoTimer = setInterval(showMessage, interval);
    };

    //=>关掉MESSAGE区域
    let closeMessage = function closeMessage() {
        let delayTimer = setTimeout(() => {
            demonMusic.pause();
            $(demonMusic).remove();
            $messageBox.remove();
            clearTimeout(delayTimer);

            cubeRender.init();
        }, interval);
    };

    return {
        init: function () {
            $messageBox.css('display', 'block');

            //=>加载模块立即展示一条信息,后期间隔INTERVAL在发送一条信息
            showMessage();
            autoTimer = setInterval(showMessage, interval);

            //=>SUBMIT
            $submit.tap(handleSubmit);

            //=>MUSIC
            demonMusic.play();
            demonMusic.volume = 0.3;
        }
    }
})();

/*CUBE*/
let cubeRender = (function () {
    let $cubeBox = $('.cubeBox'),
        $cube = $('.cube'),
        $cubeList = $cube.find('li');

    //=>手指控住旋转
    let start = function start(ev) {
        //=>记录手指按在位置的起始坐标
        let point = ev.changedTouches[0];
        this.strX = point.clientX;
        this.strY = point.clientY;
        this.changeX = 0;
        this.changeY = 0;
    };
    let move = function move(ev) {
        //=>用最新手指的位置-起始的位置,记录X/Y轴的偏移
        let point = ev.changedTouches[0];
        this.changeX = point.clientX - this.strX;
        this.changeY = point.clientY - this.strY;
    };
    let end = function end(ev) {
        //=>获取CHANGE/ROTATE值
        let {changeX, changeY, rotateX, rotateY} = this,
            isMove = false;
        //=>验证是否发生移动(判断滑动误差)
        Math.abs(changeX) > 10 || Math.abs(changeY) > 10 ? isMove = true : null;
        //=>只有发生移动再处理
        if (isMove) {
            //1.左右滑=>CHANGE-X=>ROTATE-Y (正比:CHANGE越大ROTATE越大)
            //2.上下滑=>CHANGE-Y=>ROTATE-X (反比:CHANGE越大ROTATE越小)
            //3.为了让每一次操作旋转角度小一点,我们可以把移动距离的1/3作为旋转的角度即可
            rotateX = rotateX - changeY / 3;
            rotateY = rotateY + changeX / 3;
            //=>赋值给魔方盒子
            $(this).css('transform', `scale(0.6) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`);
            //=>让当前旋转的角度成为下一次起始的角度
            this.rotateX = rotateX;
            this.rotateY = rotateY;
        }
        //=>清空其它记录的自定义属性值
        ['strX', 'strY', 'changeX', 'changeY'].forEach(item => this[item] = null);
    };

    return {
        init: function () {
            $cubeBox.css('display', 'block');

            //=>手指操作CUBE,让CUBE跟着旋转
            let cube = $cube[0];
            cube.rotateX = -35;
            cube.rotateY = 35;//=>记录初始的旋转角度(存储到自定义属性上)
            $cube.on('touchstart', start)
                .on('touchmove', move)
                .on('touchend', end);

            //=>点击每一个面跳转到详情区域对应的页面
            $cubeList.tap(function () {
                $cubeBox.css('display', 'none');

                //=>跳转到详情区域,通过传递点击LI的索引,让其定位到具体的SLIDE
                let index = $(this).index();
                detailRender.init(index);
            });
        }
    }
})();

/*DETAIL*/
let detailRender = (function () {
    let $detailBox = $('.detailBox'),
        swiper = null,
        $dl = $('.page1>dl');

    let swiperInit = function swiperInit() {
        swiper = new Swiper('.swiper-container', {
            effect: 'coverflow',
            onInit: move,
            onTransitionEnd: move
        });
    };

    let move = function move(swiper) {
        //=>SWIPER:当前创建的实例
        //1.判断当前是否为第一个SLIDE:如果是让3D菜单展开,不是收起3D菜单
        let activeIn = swiper.activeIndex,
            slideAry = swiper.slides;
        if (activeIn === 0) {
            //=>PAGE1
            $dl.makisu({
                selector: 'dd',
                overlap: 0.6,
                speed: 0.8
            });
            $dl.makisu('open');
        } else {
            //=>OTHER PAGE
            $dl.makisu({
                selector: 'dd',
                speed: 0
            });
            $dl.makisu('close');
        }

        //2.滑动到哪一个页面,把当前页面设置对应的ID,其余页面移除ID即可
        slideAry.forEach((item, index) => {
            if (activeIn === index) {
                item.id = `page${index + 1}`;
                return;
            }
            item.id = null;
        });
    };

    return {
        init: function (index = 0) {
            $detailBox.css('display', 'block');
            if (!swiper) {
                //=>防止重复初始化
                swiperInit();
            }
            swiper.slideTo(index, 0);//=>直接运动到具体的SLIDE页面(第二个参数是切换的速度:0立即切换没有切换的动画效果)
        }
    }
})();

/*以后在真实的项目中,如果页面中有滑动的需求,我们一定要把DOCUMENT本身滑动的默认行为阻止掉(不阻止:浏览器中预览,会触发下拉刷新或者左右滑动切换页卡等功能)*/
$(document).on('touchstart touchmove touchend', (ev) => {
    ev.preventDefault();
});


/*HASH*/
let url = window.location.href,//=>获取当前页面的URL地址  location.href='xxx'这种写法是让其跳转到某一个页面
    well = url.indexOf('#'),
    hash = well === -1 ? null : url.substr(well + 1);
switch (hash) {
    case 'loading':
        loadingRender.init();
        break;
    case 'phone':
        phoneRender.init();
        break;
    case 'message':
        messageRender.init();
        break;
    case 'cube':
        cubeRender.init();
        break;
    case 'detail':
        detailRender.init();
        break;
    default:
        loadingRender.init();
}

 prefixfree.min.js

导入插件后,它会帮我们把所有需要加前缀的都加上

/**
 * StyleFix 1.0.3 & PrefixFree 1.0.7
 * @author Lea Verou
 * MIT license
 */
(function(){function m(a,b){return[].slice.call((b||document).querySelectorAll(a))}if(window.addEventListener){var e=window.StyleFix={link:function(a){var b=a.href||a.getAttribute("data-href");try{if(!b||"stylesheet"!==a.rel||a.hasAttribute("data-noprefix"))return}catch(p){return}var d=b.replace(/[^\/]+$/,""),f=(/^[a-z]{3,10}:/.exec(d)||[""])[0],h=(/^[a-z]{3,10}:\/\/[^\/]+/.exec(d)||[""])[0],k=/^([^?]*)\??/.exec(b)[1],g=a.parentNode,c=new XMLHttpRequest,l;c.onreadystatechange=function(){4===c.readyState&&
l()};l=function(){var b=c.responseText;if(b&&a.parentNode&&(!c.status||400>c.status||600<c.status)){if((b=e.fix(b,!0,a))&&d)var b=b.replace(/url\(\s*?((?:"|')?)(.+?)\1\s*?\)/gi,function(b,a,c){return/^([a-z]{3,10}:|#)/i.test(c)?b:/^\/\//.test(c)?'url("'+f+c+'")':/^\//.test(c)?'url("'+h+c+'")':/^\?/.test(c)?'url("'+k+c+'")':'url("'+d+c+'")'}),n=d.replace(/([\\\^\$*+[\]?{}.=!:(|)])/g,"\\$1"),b=b.replace(RegExp("\\b(behavior:\\s*?url\\('?\"?)"+n,"gi"),"$1");n=document.createElement("style");n.textContent=
"/*# sourceURL="+a.getAttribute("href")+" */\n/*@ sourceURL="+a.getAttribute("href")+" */\n"+b;n.media=a.media;n.disabled=a.disabled;n.setAttribute("data-href",a.getAttribute("href"));a.id&&(n.id=a.id);g.insertBefore(n,a);g.removeChild(a);n.media=a.media}};try{c.open("GET",b),c.send(null)}catch(p){"undefined"!=typeof XDomainRequest&&(c=new XDomainRequest,c.onerror=c.onprogress=function(){},c.onload=l,c.open("GET",b),c.send(null))}a.setAttribute("data-inprogress","")},styleElement:function(a){if(!a.hasAttribute("data-noprefix")){var b=
a.disabled;a.textContent=e.fix(a.textContent,!0,a);a.disabled=b}},styleAttribute:function(a){var b=a.getAttribute("style"),b=e.fix(b,!1,a);a.setAttribute("style",b)},process:function(){m('link[rel="stylesheet"]:not([data-inprogress])').forEach(StyleFix.link);m("style").forEach(StyleFix.styleElement);m("[style]").forEach(StyleFix.styleAttribute)},register:function(a,b){(e.fixers=e.fixers||[]).splice(void 0===b?e.fixers.length:b,0,a)},fix:function(a,b,d){if(e.fixers)for(var f=0;f<e.fixers.length;f++)a=
e.fixers[f](a,b,d)||a;return a},camelCase:function(a){return a.replace(/-([a-z])/g,function(b,a){return a.toUpperCase()}).replace("-","")},deCamelCase:function(a){return a.replace(/[A-Z]/g,function(b){return"-"+b.toLowerCase()})}};(function(){setTimeout(function(){m('link[rel="stylesheet"]').forEach(StyleFix.link)},10);document.addEventListener("DOMContentLoaded",StyleFix.process,!1)})()}})();
(function(m){function e(b,d,f,h,k){b=a[b];b.length&&(b=RegExp(d+"("+b.join("|")+")"+f,"gi"),k=k.replace(b,h));return k}if(window.StyleFix&&window.getComputedStyle){var a=window.PrefixFree={prefixCSS:function(b,d,f){var h=a.prefix;-1<a.functions.indexOf("linear-gradient")&&(b=b.replace(/(\s|:|,)(repeating-)?linear-gradient\(\s*(-?\d*\.?\d*)deg/ig,function(b,a,d,f){return a+(d||"")+"linear-gradient("+(90-f)+"deg"}));b=e("functions","(\\s|:|,)","\\s*\\(","$1"+h+"$2(",b);b=e("keywords","(\\s|:)","(\\s|;|\\}|$)",
"$1"+h+"$2$3",b);b=e("properties","(^|\\{|\\s|;)","\\s*:","$1"+h+"$2:",b);if(a.properties.length){var k=RegExp("\\b("+a.properties.join("|")+")(?!:)","gi");b=e("valueProperties","\\b",":(.+?);",function(a){return a.replace(k,h+"$1")},b)}d&&(b=e("selectors","","\\b",a.prefixSelector,b),b=e("atrules","@","\\b","@"+h+"$1",b));b=b.replace(RegExp("-"+h,"g"),"-");return b=b.replace(/-\*-(?=[a-z]+)/gi,a.prefix)},property:function(b){return(0<=a.properties.indexOf(b)?a.prefix:"")+b},value:function(b,d){b=
e("functions","(^|\\s|,)","\\s*\\(","$1"+a.prefix+"$2(",b);b=e("keywords","(^|\\s)","(\\s|$)","$1"+a.prefix+"$2$3",b);0<=a.valueProperties.indexOf(d)&&(b=e("properties","(^|\\s|,)","($|\\s|,)","$1"+a.prefix+"$2$3",b));return b},prefixSelector:function(b){return a.selectorMap[b]||b},prefixProperty:function(b,d){var f=a.prefix+b;return d?StyleFix.camelCase(f):f}};(function(){var b={},d=[],f=getComputedStyle(document.documentElement,null),h=document.createElement("div").style,k=function(a){if("-"===
a.charAt(0)){d.push(a);a=a.split("-");var c=a[1];for(b[c]=++b[c]||1;3<a.length;)a.pop(),c=a.join("-"),StyleFix.camelCase(c)in h&&-1===d.indexOf(c)&&d.push(c)}};if(f&&0<f.length)for(var g=0;g<f.length;g++)k(f[g]);else for(var c in f)k(StyleFix.deCamelCase(c));var g=0,e,p;for(p in b)f=b[p],g<f&&(e=p,g=f);a.prefix="-"+e+"-";a.Prefix=StyleFix.camelCase(a.prefix);a.properties=[];for(g=0;g<d.length;g++)c=d[g],0===c.indexOf(a.prefix)&&(e=c.slice(a.prefix.length),StyleFix.camelCase(e)in h||a.properties.push(e));
!("Ms"!=a.Prefix||"transform"in h||"MsTransform"in h)&&"msTransform"in h&&a.properties.push("transform","transform-origin");a.properties.sort()})();(function(){function b(a,b){e[b]="";e[b]=a;return!!e[b]}var d={"linear-gradient":{property:"backgroundImage",params:"red, teal"},calc:{property:"width",params:"1px + 5%"},element:{property:"backgroundImage",params:"#foo"},"cross-fade":{property:"backgroundImage",params:"url(a.png), url(b.png), 50%"},"image-set":{property:"backgroundImage",params:"url(a.png) 1x, url(b.png) 2x"}};
d["repeating-linear-gradient"]=d["repeating-radial-gradient"]=d["radial-gradient"]=d["linear-gradient"];var f={initial:"color",grab:"cursor",grabbing:"cursor","zoom-in":"cursor","zoom-out":"cursor",box:"display",flexbox:"display","inline-flexbox":"display",flex:"display","inline-flex":"display",grid:"display","inline-grid":"display","max-content":"width","min-content":"width","fit-content":"width","fill-available":"width","contain-floats":"width"};a.functions=[];a.keywords=[];var e=document.createElement("div").style,
k;for(k in d){var g=d[k],c=g.property,g=k+"("+g.params+")";!b(g,c)&&b(a.prefix+g,c)&&a.functions.push(k)}for(var l in f)c=f[l],!b(l,c)&&b(a.prefix+l,c)&&a.keywords.push(l)})();(function(){function b(a){h.textContent=a+"{}";return!!h.sheet.cssRules.length}var d={":any-link":null,"::backdrop":null,":fullscreen":null,":full-screen":":fullscreen","::placeholder":null,":placeholder":"::placeholder","::input-placeholder":"::placeholder",":input-placeholder":"::placeholder",":read-only":null,":read-write":null,
"::selection":null},e={keyframes:"name",viewport:null,document:'regexp(".")'};a.selectors=[];a.selectorMap={};a.atrules=[];var h=m.appendChild(document.createElement("style")),k;for(k in d){var g=d[k]||k,c=k.replace(/::?/,function(b){return b+a.prefix});!b(g)&&b(c)&&(a.selectors.push(g),a.selectorMap[g]=c)}for(var l in e)d=l+" "+(e[l]||""),!b("@"+d)&&b("@"+a.prefix+d)&&a.atrules.push(l);m.removeChild(h)})();a.valueProperties=["transition","transition-property","will-change"];m.className+=" "+a.prefix;
StyleFix.register(a.prefixCSS)}})(document.documentElement);

readImgList.js

读取当前img目录下的图片文件

let fs = require('fs');
let ary = fs.readdirSync('./');
let result = [];
ary.forEach(function (item) {
    if (/\.(PNG|GIF|JPG)/i.test(item)) {
        //=>图片
        result.push(`img/` + item);
    }
});
fs.writeFileSync('./result.txt', JSON.stringify(result), 'utf-8');

移动端事件

     * CLICK在移动端是单击事件行为,当触发点击操作,浏览器总会等待300MS,验证是否触发了第二次点击操作,没有触发才会执行CLICK对应的方法(CLICK在移动端的300MS延迟问题)

     *   1.不建议大家在移动端使用CLICK(如果非要使用也可以,最好导入一个插件 fastclick.min.js 就是解决300MS延迟的插件)

     *

     *   2.目前项目中移动端的点击操作等基本上都是基于第三方类库(事件库完成的)

     *     zepto:提供了移动端常用的事件操作

     *     touch.js

     *     hammer.js 

  * TouchEvent:手指事件对象

         *   changedTouches

         *   touches

         *   手指操作的信息集合,集合中记录了每一根操作的手指的相关信息(包含触发点的坐标位置),touches记录的信息只有手指在屏幕上才有,也就是手指离开屏幕的时候信息就消失了,changedTouches本意上记录的是改变的值,即使手指离开,信息值也在

let $box = $('.box');
    =>ZEPTO中提供的专门供移动端操作的事件方法
    $box.tap(ev => {
        //=>点击
    });
    $box.singleTap(ev => {
        //=>单击
    });
    $box.doubleTap(ev => {
        //=>双击
    });
    $box.longTap(ev => {
        //=>长按
    });
    //=>滑动 swipe / swipeLeft / swipeRight / swipeUp / swipeDown...
    //=>缩放 pinchIn / pinchOut ...

    //=>ZEPTO VS JQ
    //1.ZEPTO没有考虑浏览器的兼容,专门为移动端开发的小型类库,也仅仅是把JQ中的一些常规方法实现
    //了,很多方法也没有实现(例如:slideDown/show...在ZEPTO中都没有) =>为了保证ZEPTO的体积足够小
    //2.ZEPTO中提供了移动端专门操作的事件方法(例如:tap等),这些方法都是基于移动端的TOUCH
    //和GESTURE事件模型封装好的方法,JQ中并没有提供这些方法 =>ZEPTO更适合移动端
    //...



let box = document.querySelector('.box');

    box.ontouchstart = function (ev) {
        //=>按下的时候记录手指的起始位置
        let point = ev.changedTouches[0];
        this.strX = point.clientX;
        this.strY = point.clientY;
        this.isMove = false;
    };
    box.ontouchmove = function (ev) {
        let point = ev.changedTouches[0];
        this.changeX = point.clientX - this.strX;
        this.changeY = point.clientY - this.strY;
        if (Math.abs(this.changeX) > 10 || Math.abs(this.changeY) > 10) {
            //=>10是操作误差值
            this.isMove = true;
        }
    };
    box.ontouchend = function (ev) {
        if (this.isMove) {
            //=>滑动
            return;
        }
        //=>点击
        console.log('我是点击操作');
    };

标签:简历,48,img,zf,transform,let,rem,交互,png
来源: https://blog.csdn.net/qq_45738592/article/details/120871173

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有