• jQuery火箭图标返回顶部代码


    首先来看一下网站效果,想写这个项目的读者可以自行下载哦,地址:https://github.com/Stray-Kite/Car

    在这个项目中,我们主要是为了学习语种切换,也就是右上角的 中文/English 功能的实现。

    首先看一下模拟的后台数据src/config/modules/lang.js 文件中:

    关键代码:

      1 export default {
      2   name: 'Homepage',
      3   components: {
      4     ScrollNumber
      5   },
      6   data () {
      7     return {
      8       lang: 'chinese',
      9       pageIndex: 0,
     10       stepIndex: 0
     11     }
     12   },
     13   ......其余代码 44   methods: {
     45     addClass (el, _class) {177     //切换语言
    178     toggleLang (lang) {
    179       this.lang = lang
    180       // this.animatePage()
    181     }
    182   },
    183   //以下几个computed是获取config文件夹里的数据
    184   computed: {
    185     langs () {
    186       return config.langs[this.lang]  //主要靠这里切换,这个切换的本质其实就是使用了另一套英文的数据(换了一套后台数据)
    187     },
    188     ......其余代码198   }
    199 }

     最后给大家一波儿带注解的代码,方便理解:

    Homepage.vue(CSS我就不给啦,因为这东西看着学一下就好):

      1 <template>
      2   <div class="container">
      3 
      4 
      5     <div class="rc-header">
      6       <!--首先这是两个切换语言的按钮(中文/English)-->
      7       <div class="rc-header-right">
      8         <a href="#" :class="{'is-active': this.lang === 'chinese'}" @click="toggleLang('chinese')">中文</a>&nbsp;/
      9         <a href="#" :class="{'is-active': this.lang === 'english'}" @click="toggleLang('english')">English</a>
     10       </div>
     11      <!--顶栏其他的元素,图片等...-->
     12       <div class="rc-header-left">
     13         <img class="rc-logo" :src="media.LOGO_PATH">
     14         <img class="rc-slogan" :src="media.SLOGAN_PATH">
     15       </div>
     16     </div>
     17 
     18     <!--下面就是整个内容页了,大的来说这四页就是一个大的竖着的轮播图,用了vue的swiper-->
     19     <div class="swiper-container rc-body">
     20       <div class="swiper-wrapper">
     21 
     22         <!--第一页-->
     23         <div class="swiper-slide">
     24           <div class="rc-page rc-page01">
     25             <!--星空和车-->
     26             <div class="rc-galaxy">
     27               <div class="rc-bg rc-layer-bg" ref="plbo"
     28                           :style="{backgroundImage: 'url(' + common.GALAXY_LAYER_BG + ')', top: layerEdge, bottom: layerEdge, left: layerEdge, right: layerEdge}">
     29             </div>
     30               <div class="rc-bg rc-layer-top" ref="plto"
     31                    :style="{backgroundImage: 'url(' + common.GALAXY_LAYER_TOP + ')'}">
     32               </div>
     33             </div>
     34 
     35             <div class="rc-content-wrapper">
     36               <!--若是第一页,即index=0,则显示,否则隐藏-->
     37               <div class="rc-text-wrapper" ref="ptwo"
     38                    :style="{visibility: pageIndex === 0 ? 'visible' : 'hidden'}" >
     39                 <h2>{{langs.PAGE_ONE_SLOGAN}}</h2>
     40                 <!--scroll-number是数字增加,引入widgets/ScrollNumber.vue的方法-->
     41                 <scroll-number :size="isMobile ? 18 : 24" ref="psno">
     42                   <span slot="suffix" style="color: #c3c3c3;">{{langs.PAGE_ONE_SUB_SLOGAN}}</span>
     43                 </scroll-number>
     44               </div>
     45               <button class="btn btn-success btn-try"
     46                       :style="{visibility: pageIndex === 0 ? 'visible' : 'hidden'}"
     47                       ref="pbro">{{langs.TRY_LABEL}}</button>
     48             </div>
     49 
     50             <!--下面这两个img不用管,已经隐藏啦-->
     51             <img :src="common.GALAXY_REAL_TOP" v-show="false">
     52             <img :src="common.GALAXY_REAL_BG" v-show="false">
     53           </div>
     54         </div>
     55 
     56         <!--第二页-->
     57         <div class="swiper-slide">
     58           <div class="rc-page rc-page02">
     59             <div class="rc-content-wrapper">
     60               <div
     61                 class="rc-text-wrapper"
     62                 :style="{visibility: pageIndex === 1 ? 'visible' : 'hidden'}"
     63                 ref="ptwt">
     64                 <h2>{{langs.PAGE_TWO_SLOGAN}}</h2>
     65               </div>
     66               <div class="rc-step-wrapper">
     67                 <div class="rc-step-stage">
     68                   <div class="swiper-container rc-step-container">
     69                     <div class="swiper-wrapper">
     70                       <div
     71                         v-for="(step, index) in langs.STEPS_PROFILE"
     72                         :key="index"
     73                         class="swiper-slide rc-step">
     74                         <div class="rc-step-content">
     75                           <h2 class="rc-step-title">{{langs.STEP_LABEL}} {{index + 1}}</h2>
     76                           <p class="rc-step-profile">{{step}}</p>
     77                           <button
     78                             class="btn"
     79                             ref="pbdt"
     80                             v-if="index === 0">{{langs.DOWNLOAD_LABEL}}</button>
     81                           <button
     82                             class="btn"
     83                             ref="pbat"
     84                             v-if="index === 1">{{langs.AUTH_LABEL}}</button>
     85                         </div>
     86                       </div>
     87                     </div>
     88                     <div class="swiper-scrollbar"></div>
     89                     <div class="swiper-button-next" v-if="!isMobile"></div>
     90                     <div class="swiper-button-prev" v-if="!isMobile"></div>
     91                   </div>
     92                 </div>
     93                 <!--步骤右面的图片-->
     94                 <div class="rc-step-scene" v-if="!isMobile">
     95                   <div
     96                     :style="{backgroundImage: 'url(' + media.STEPS_ACTOR_PATH[stepIndex] + ')'}"
     97                     class="rc-bg rc-step-actor"></div>
     98                 </div>
     99               </div>
    100             </div>
    101           </div>
    102         </div>
    103 
    104         <!--第三页-->
    105         <div class="swiper-slide">
    106           <div class="rc-page rc-page03">
    107             <div class="rc-content-wrapper">
    108               <div
    109                 class="rc-text-wrapper"
    110                 :style="{visibility: pageIndex === 2 ? 'visible' : 'hidden'}"
    111                 ref="ptwth">
    112                 <h2>{{langs.PAGE_THREE_SLOGAN}}</h2>
    113               </div>
    114               <div class="rc-cars-gallery">
    115                 <div
    116                   v-for="(car, index) in langs.CARS_PROFILE"
    117                   :key="index"
    118                   class="rc-car">
    119                   <div class="rc-car-card" :title="langs.CARS_TOOLTIP">
    120                     <div class="rc-car-media">
    121                       <div
    122                         :style="{backgroundImage: 'url(' + common.CARS_PATH[index] + ')'}"
    123                         class="rc-bg rc-bg-scale rc-car-snapshot"></div>
    124                     </div>
    125                     <div class="rc-car-profile">
    126                       <h4>{{car.NAME}}</h4>
    127                       <div>{{langs.OWNER_LABEL}}:&nbsp;{{car.OWNER}}</div>
    128                       <div>{{langs.DATE_LABEL}}:&nbsp;{{car.DATE}}</div>
    129                     </div>
    130                   </div>
    131                 </div>
    132               </div>
    133             </div>
    134           </div>
    135         </div>
    136 
    137         <!--第四页-->
    138         <div class="swiper-slide">
    139           <div class="rc-page rc-page04">
    140             <div
    141               class="rc-text-wrapper"
    142               :style="{visibility: pageIndex === 3 ? 'visible' : 'hidden'}"
    143               ref="ptwf">
    144               <h2>{{langs.PAGE_FOUR_SLOGAN}}</h2>
    145             </div>
    146             <div class="rc-content-wrapper">
    147               <div class="rc-bg rc-drive-stage">
    148                 <div
    149                   :style="{backgroundImage: 'url(' + common.DRIVE_STAGE_ACTOR + ')'}"
    150                   class="rc-bg rc-actor-car" ref="pdcf"></div>
    151               </div>
    152             </div>
    153           </div>
    154         </div>
    155       </div>
    156       <div class="swiper-pagination" v-show="!isMobile"></div>
    157     </div>
    158   </div>
    159 </template>
    160 
    161 <script>
    162   /* eslint-disable */
    163   import Swiper from 'swiper'
    164   import 'swiper/dist/css/swiper.min.css'
    165   import 'animate.css/animate.min.css'
    166   import config from '../config'
    167   import ScrollNumber from '@/widgets/ScrollNumber.vue'
    168   export default {
    169     name: 'Homepage',
    170     components: {
    171       ScrollNumber
    172     },
    173     data () {
    174       return {
    175         lang: 'chinese',
    176         pageIndex: 0,
    177         stepIndex: 0
    178       }
    179     },
    180     beforeCreate () {
    181       /**
    182        * 旋转星空
    183        *  step 3: 计算可视区域对角线, 根据对角线长度撑开容器
    184        */
    185       let w = document.body.clientWidth
    186       let h = document.body.clientHeight
    187       this.layerEdge = 'calc(50% - ' + Math.ceil(Math.sqrt(w * w + h * h) / 2) + 'px)'
    188     },
    189     mounted () {
    190       this.$nextTick(function () {
    191         let _self = this
    192         /* eslint-disable no-new */
    193         new Swiper('.rc-body', {
    194           speed: 800,
    195           direction: 'vertical',
    196           paginationClickable: true,
    197           mousewheel: true,
    198           pagination: {
    199             el: '.swiper-pagination'
    200           },
    201           on: {
    202             slideChangeTransitionEnd () {
    203               _self.pageIndex = this.activeIndex
    204               _self.animatePage()
    205             }
    206           }
    207         })
    208         this.initPage()
    209       })
    210     },
    211     methods: {
    212       addClass (el, _class) {
    213         let elClassArr = el.className.split(' ') //用单个空格分割
    214         let classArr = _class.split(' ')         //同上
    215         classArr.forEach(item => {
    216           // 如果elClassArr中没有这个元素(类型),那么添加进去
    217           if (elClassArr.indexOf(item) === -1) {
    218             elClassArr.push(String(item))
    219           }
    220         })
    221         //添加完后本属性后面要有一个空格隔开
    222         el.className = elClassArr.join(' ')
    223         return el
    224       },
    225       removeClass (el, _class) {
    226         let elClassArr = el.className.split(' ')
    227         let classArr = _class.split(' ')
    228         classArr.forEach(item => {
    229           let index = elClassArr.indexOf(item)
    230           if (index > -1) {
    231             elClassArr.splice(index, 1)
    232           }
    233         })
    234         el.className = elClassArr.join(' ')
    235         return el
    236       },
    237       bindAnimation (el, x) {
    238         let _self = this
    239         // 监听动画结束事件
    240         let events = [
    241           'webkitAnimationEnd',
    242           'mozAnimationEnd',
    243           'MSAnimationEnd',
    244           'oanimationend',
    245           'animationend'
    246         ]
    247         _self.addClass(el, x + ' animated')
    248         events.forEach(event => {
    249           let func = function () {
    250             events.forEach(item => {
    251               el.removeEventListener(item, func)
    252             })
    253             _self.removeClass(el, x + ' animated')
    254           }
    255           //增加事件监听,如果时间结束,那么再利用fun函数移除监听的事件和添加进来的新类(class属性)
    256           el.addEventListener(event, func)
    257         })
    258       },
    259       initPage01 () {
    260         setTimeout(() => {
    261           /**
    262            * 旋转星空
    263            *  step 4: 采用真实图片替换代理图片
    264            */
    265           this.$refs.plto.style.backgroundImage = 'url(' + this.common.GALAXY_REAL_TOP + ')'
    266           this.$refs.plbo.style.backgroundImage = 'url(' + this.common.GALAXY_REAL_BG + ')'
    267         }, 2000)
    268         this.animatePage01() //动画效果(数字上升)
    269       },
    270       //第二页
    271       initPage02 () {
    272         let _self = this
    273         let pbdt = this.$refs.pbdt[0]
    274         let pbat = this.$refs.pbat[0]
    275         let bindAnimation = this.bindAnimation
    276         new Swiper('.rc-step-container', {
    277           speed: 600,
    278           scrollbar: {
    279             el: '.swiper-scrollbar',
    280             draggable: true
    281           },
    282           navigation: {
    283             nextEl: '.swiper-button-next',
    284             prevEl: '.swiper-button-prev'
    285           },
    286           on: {
    287             slideChangeTransitionEnd () {
    288               if (this.activeIndex === 0) {
    289                 bindAnimation(pbdt, 'tada')
    290               } else if (this.activeIndex === 1) {
    291                 bindAnimation(pbat, 'tada')
    292               }
    293               _self.stepIndex = this.activeIndex
    294             }
    295           }
    296         })
    297       },
    298       initPage03 () {},
    299       initPage04 () {},
    300 
    301       //初始化四个界面方法
    302       initPage () {
    303         this.initPage01()
    304         this.initPage02()
    305         this.initPage03()
    306         this.initPage04()
    307       },
    308 
    309       animatePage01 () {
    310         this.bindAnimation(this.$refs.ptwo, 'fadeIn')
    311         this.bindAnimation(this.$refs.pbro, 'fadeIn')
    312         this.$refs.psno.$emit('start')
    313       },
    314       animatePage02 () {
    315         this.bindAnimation(this.$refs.ptwt, 'fadeInDown')
    316       },
    317       animatePage03 () {
    318         this.bindAnimation(this.$refs.ptwth, 'flipInY')
    319       },
    320       animatePage04 () {
    321         this.bindAnimation(this.$refs.ptwf, 'jackInTheBox')
    322         setTimeout(() => {
    323           this.bindAnimation(this.$refs.pdcf, 'rc-arrive')
    324         }, 600)
    325       },
    326       // QA: 函数本是对象
    327       animatePage (index) {
    328         [
    329           this.animatePage01,
    330           this.animatePage02,
    331           this.animatePage03,
    332           this.animatePage04
    333         ][index || this.pageIndex]()
    334       },
    335       //切换语言
    336       toggleLang (lang) {
    337         this.lang = lang
    338         // this.animatePage()
    339       }
    340     },
    341     //以下几个computed是获取config文件夹里的数据
    342     computed: {
    343       langs () {
    344         return config.langs[this.lang]
    345       },
    346       media () {
    347         return config.media[this.lang]
    348       },
    349       common () {
    350         return config.common
    351       },
    352       // 判断移动端,无需记住,会用就好,返回值为bool值
    353       isMobile () {
    354         return 这个就不给了,这个直接用就好了355       }
    356     }
    357   }
    358 </script>
    359 
    360 <style scoped>
    361 </style>

    widgets/ScrollNumber.vue(数字增长):

     1 <template>
     2   <div class="scroll-number" :style="{fontSize: size + 'px'}">
     3     <slot name="prefix"></slot>
     4     <span class="number">{{value}}</span>
     5     <slot name="suffix"></slot>
     6   </div>
     7 </template>
     8 
     9 <script>
    10 import TWEEN from 'tween.js'
    11 export default {
    12   name: 'ScrollNumber',
    13   data () {
    14     return {
    15       value: 0,
    16       animation: null
    17     }
    18   },
    19   props: {
    20     total: {
    21       type: Number,
    22       default: 15374
    23     },
    24     size: {
    25       type: Number,
    26       default: 24
    27     }
    28   },
    29   mounted () {
    30     this.$nextTick(function () {
    31       const animate = function (time) {
    32         requestAnimationFrame(animate)
    33         TWEEN.update(time)
    34       }
    35       requestAnimationFrame(animate)
    36       let _self = this
    37       // 增长起始值,从0开始
    38       let surface = {value: 0}
    39       // 增加从0增长到total动画1600为时间
    40       this.animation = new TWEEN.Tween(surface).to({value: _self.total}, 1600)
    41       this.animation.easing(TWEEN.Easing.Exponential.Out).onUpdate(() => {
    42         _self.value = Math.floor(surface.value)
    43       })
    44       // 监听父组件通讯事件
    45       this.$on('start', () => {
    46         surface.value = 0
    47         this.animation.start()
    48       })
    49     })
    50   }
    51 }
    52 </script>
    53 
    54 <style scoped>
    55   .number {
    56     display: inline-block;
    57     min-width: 40px;
    58     color: orangered;
    59     text-align: center;
    60     font-weight: 600;
    61   }
    62 </style>

    注:其中TWEEN的用法我找到了一篇比较不错的文章,地址:https://www.jianshu.com/p/164538a89939

  • 相关阅读:
    5.3二叉树的运算
    hadoop namenode切换
    org.apache.hadoop.security.AccessControlException
    Hive中的日志
    命令大全详解
    python深浅copy
    awk命令
    head&tail命令
    cut命令
    理解inode
  • 原文地址:https://www.cnblogs.com/Trojan00/p/11311544.html
Copyright © 2020-2023  润新知