美文网首页
swiper 实现 带video的banner

swiper 实现 带video的banner

作者: 八妹sss | 来源:发表于2020-11-12 20:21 被阅读0次

    遇到的问题:

    1、swiper复制的节点点击事件失效问题
    2、多个视频同时播放的问题
    3、安卓手机上视频播放后轮播卡顿的问题

    解决问题2问题3的思路:

    页面展示用图片展示,点击播放视频时才显示video元素,当前换到下一个时,暂停上一个并隐藏video元素

    解决方法见代码

    <template>
      <div class="main">
        <div v-if="bannerList.length" class="banner-wrapper">
          <swiper :class="{single: bannerList.length === 1}" v-if='bannerList.length > 1' :options="swiperOption">
            <swiper-slide v-for='(banner, index) of bannerList' :key='"banner" + index'>
              <div class='banner-content'>
                <video
                  v-if="banner.bannerVideo"
                  :ref="`publicVideo${index}`"
                  style="width: 100%; height: 100%; object-fit: fill"
                  controls="controls"
                  webkit-playsinline
                  playsinline
                  x5-playsinline
                  :poster="banner.bannerImg"
                  :src='banner.bannerVideo'>
                  <source :src="banner.bannerVideo" type="video/mp4;"/>
                </video>
                <div v-if="banner.bannerVideo" class="play"></div>
                <img
                  class='banner-img'
                  :src="banner.bannerImg">
                <div class='banner-name'>{{banner.bannerName}}</div>
              </div>
            </swiper-slide>
          </swiper>
          <div class='banner-content' v-else>
            <video
              v-if="bannerList[0].type"
              :ref="`publicVideo${index}`"
              style="width: 100%; height: 100%; object-fit: fill"
              controls="controls"
              webkit-playsinline
              playsinline
              x5-playsinline
              :poster="bannerList[0].bannerImg"
              :src='bannerList[0].bannerImg'>
              <source :src="bannerList[0].bannerImg" type="video/mp4;"/>
            </video>
            <img
              v-else
              class='banner-img'
              :src="bannerList[0].bannerImg">
            <div v-if="bannerList[0].type" class="play"></div>
            <div class='banner-name'>{{bannerList[0].bannerName}}</div>
          </div>
        </div>
        <div class="mt-title">关于公司</div>
        <ul class="info-list">
          <li @click="onJump('companyIntroduce')" class="info-item">
            <div class="bg-right"></div>
            <div class="bg-tag">About Us</div>
            <div class="cont">
              <p class="title"></p>
              <p class="learn-more"><span>了解详情</span><span class="icon-arrow"></span></p>
            </div>
          </li>
          <li @click="onJump('listedProducts')" class="info-item">
            <div class="bg-right"></div>
            <div class="bg-tag">Product</div>
            <div class="cont">
              <p class="title"></p>
              <p class="learn-more"><span>了解详情</span><span class="icon-arrow"></span></p>
            </div>
          </li>
          <li @click="onJump('mainResearch')" class="info-item">
            <div class="bg-right"></div>
            <div class="bg-tag">Develop</div>
            <div class="cont">
              <p class="title"></p>
              <p class="learn-more"><span>了解详情</span><span class="icon-arrow"></span></p>
            </div>
          </li>
        </ul>
        <div class="contact-us">
          <div @click="onJump('contactWe')" class="cont">
            <p class="icon-contact"><img src="" alt=""></p>
            <p class="text">联系我们</p>
          </div>
        </div>
      </div>
    </template>
    <script>
    import { swiper, swiperSlide } from 'vue-awesome-swiper'
    import 'swiper/dist/css/swiper.css'
    let vm = null
    export default {
      components: {
        swiper,
        swiperSlide
      },
      data () {
        return {
          bannerList: [],
          swiperOption: {
            watchSlidesProgress: true,
            slidesPerView: 'auto',
            spaceBetween: 8,
            centeredSlides: true,
            observer: true,
            observeParents: true,
            loop: true,
            loopedSlides: 5,
            on: {
              // 解决复制的节点无法点击的问题
              click () {
                const realIndex = this.realIndex
                if (vm.bannerList[realIndex]) {
                  // 视频播放
                  if (vm.bannerList[realIndex].bannerVideo) {
                    vm.showControls()
                    // banner 跳转
                  } else if (vm.bannerList[realIndex].jumpLink) {
                    location.href = vm.bannerList[realIndex].jumpLink
                  }
                }
              },
              // 控制slid缩放
              slideChangeTransitionStart: function () {
                vm.watchPlay() // 隐藏所有视频元素
                vm.pauseAll(this.realIndex) // 暂停播放的视频
              }
            }
          }
        }
      },
      methods: {
        // 获取banner
        fetchBanner () {
          this.$_load.show()
          let url = `${this.SERVICE_PORTAL}/${localStorage.getItem('appid')}/banner`
          this.$get(url).then(res => {
            this.$_load.hide()
            if (res.code === 200) {
              let data = res.data
              if (data) {
                this.bannerList = data
                if (this.bannerList.length > 2) {
                  this.swiperOption.loop = true
                  this.swiperOption.loopedSlides = 5
                } else {
                  this.swiperOption.loop = false
                  this.swiperOption.loopedSlides = 0
                }
                this.$nextTick(() => {
                  this.watchPlay()
                })
              }
            }
          }).catch(() => {
            this.$_load.hide()
          })
        },
        // 点击蒙层播放视频
        showControls () {
          this.watchPlay()
          let dom = document.querySelector('.swiper-slide-active video')
          if (dom) {
            dom.style.display = 'block'
            document.querySelector('.swiper-slide-active .banner-img').style.display = 'none'
            document.querySelector('.swiper-slide-active .play').style.display = 'none'
            dom.controls = false
            dom.play()
            setTimeout(() => {
              dom.controls = true
            }, 0)
          }
        },
        // 监听所有视频的播放事件并暂停
        watchPlay () {
          // 隐藏所有的video标签
          let videoAllDom = document.querySelectorAll('video')
          let playAllDom = document.querySelectorAll('.play')
          let imgAllDom = document.querySelectorAll('.banner-img')
          let self = this
          for (let i = 0; i < imgAllDom.length; i++) {
            imgAllDom[i].style.display = 'block'
          }
          for (let i = 0; i < videoAllDom.length; i++) {
            (function () {
              var p = i
              videoAllDom[p].style.display = 'none'
              playAllDom[p].style.display = 'block'
              videoAllDom[p].addEventListener('play', () => {
                self.pauseAll(p)
              })
            })()
          }
        },
        // 暂停所有视频
        pauseAll (index) {
          let videoAllDom = document.querySelectorAll('video')
          for (var j = videoAllDom.length - 1; j >= 0; j--) {
            if (j !== index) videoAllDom[j].pause()
          }
        },
        onJump (routeName) {
          if (routeName === 'listedProducts') {
            this.linkTo(routeName, {}, { type: 'al' })
          } else {
            this.linkTo(routeName)
          }
        }
      },
      created () {
        vm = this
        this.fetchBanner()
      }
    }
    </script>
    <style lang="stylus" scoped>
    .main
      width 100%
      max-width 750px
      margin 0 auto
      min-height 100vh
      background #fff
      padding-bottom 40px
      box-sizing border-box
      .banner-wrapper
        width 100%
        padding 18px 0px 16px
        box-sizing border-box
        // 单张时
        .single
          >>> .swiper-container
            height auto
          >>> .swiper-slide
            width 100%
        >>> .swiper-container
          height 185px
        >>> .swiper-slide
          width 91%
          &.swiper-slide-active
            opacity 1 !important
          &.swiper-slide-next
          &.swiper-slide-prev
            opacity 0.8 !important
      .banner-content
        height 100%
        position relative
        border-radius 4px
        overflow hidden
        font-size 0
        video
          width 100%
          height 100%
          display none
        .banner-img
          display block
          width 100%
          height 100%
        .play
          width 100%
          height 100%
          background rgba(0, 0, 0, 0.06) url('~assets/img/home_ic_play@3x.png') no-repeat center / 45px
          border-radius 4px
          position absolute
          top 50%
          left 50%
          transform translate(-50%, -50%)
          z-index 1
        .banner-name
          position absolute
          bottom 6px
          left 0
          right 0
          background url('~assets/img/ic_biaoti@3x.png') no-repeat left center/ 292px 29px
          color #fff
          padding 0 36px 0 10px
          font-size 15px
          font-weight 500
          line-height 21px
          noWrap()
          z-index 2
      .mt-title
        width 100%
        padding 0 16px
        line-height 22px
        font-size 18px
        font-family 'PingFangSC-Semibold', 'PingFang SC'
        font-weight 700
        color #333333
        margin-top 13px
      .info-list
        width 100%
        padding 0 16px
        margin-top 13px
        .info-item
          width 100%
          height 96px
          border-radius 6px
          box-shadow 0px 0px 6px 0px rgba(0, 0, 0, 0.08)
          position relative
          & + .info-item
            margin-top 20px
          .bg-right
            width 90px
            height 90px
            position absolute
            right 25px
            top 50%
            transform translate(0, -50%)
          .bg-tag
            font-size 32px
            font-family 'PingFangSC-Semibold', 'PingFang SC'
            font-weight 700
            color #EAEAEA
            position absolute
            top 20px
            left 35px
            z-index 1
          .cont
            width 100%
            height 100%
            padding 30px 156px 0 34px
            box-sizing border-box
            position absolute
            top 50%
            left 50%
            transform translate(-50%, -50%)
            z-index 2
            .learn-more
              display flex
              align-items center
              font-size 14px
              font-family 'PingFangSC-Regular', 'PingFang SC'
              font-weight 400
              color #333333
              line-height 18px
              margin-top 5px
              .icon-arrow
                display inline-block
                width 11px
                height 11px
                background url('~assets/img/home_ic_more@3x.png') no-repeat center / 100%
                margin-left 3px
          &:nth-of-type(1)
            background #fff url('~assets/img/gongsijieshao@3x.png') no-repeat left center / 114px 96px
            .bg-right
              background url('~assets/img/home_ic_gongsijieshao@3x.png') no-repeat center / 90px
            .cont
              .title
                width 82px
                height 20px
                background url('~assets/img/tex_gongsi@3x.png') no-repeat center / 100%
          &:nth-of-type(2)
            background #fff url('~assets/img/chanpin@3x.png') no-repeat left center / 114px 96px
            .bg-right
              background url('~assets/img/home_ic_chanpin@3x.png') no-repeat center / 90px
            .bg-tag
              top 22px
            .cont
              padding 32px
              .title
                width 102px
                height 20px
                background url('~assets/img/tex_chanpin@3x.png') no-repeat center / 100%
          &:nth-of-type(3)
            background #fff url('~assets/img/zaiyanchanpin@3x.png') no-repeat left center / 114px 96px
            .bg-right
              background url('~assets/img/home_ic_zaiyanchanpin@3x.png') no-repeat center / 90px
            .bg-tag
              top 23px
            .cont
              padding-top 33px
              .title
                width 123px
                height 20px
                background url('~assets/img/tex_zaiyanchanpin@3x.png') no-repeat center / 100%
      .contact-us
        display flex
        justify-content flex-end
        padding-right 15px
        margin-top 28px
        .cont
          display flex
          flex-direction column
          align-items center
          .icon-contact
            width 54px
            height 54px
            background url('~assets/img/home_ic_lianxi@3x.png') no-repeat center / 100%
          .text
            line-height 16px
            font-size 12px
            font-family 'PingFangSC-Medium', 'PingFang SC'
            font-weight 500
            color #333333
    </style>
    

    相关文章

      网友评论

          本文标题:swiper 实现 带video的banner

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