浮动菜单可移动

原创
2020/06/20 15:49
阅读数 249

 浮动菜单可移动

<template>
  <transition>
    <div
      v-if="isFloatball"
      ref="dragIcon"
      :style="{left: left + 'px',top: top + 'px',width: itemWidth + 'px',height: itemHeight + 'px'}"
      class="dragIcon"
      @click="goHome"
      @touchstart.stop="handleTouchStart"
      @touchmove.prevent.stop="handleTouchMove($event)"
      @touchend.stop="handleTouchEnd"
    >
      <div class="iconCont">
        <van-icon name="contact" color="#fff" size="20px"/>
        <span>我的</span>
      </div>
    </div>
  </transition>
</template>

<script>
export default {
  props: {
    id: {
      type: Number,
      default: null
    },
    itemWidth: {
      type: Number,
      default: 50
    },
    itemHeight: {
      type: Number,
      default: 50
    }
  },
  data() {
    return {
      left: 0,
      top: 0,
      startToMove: false,
      isFloatball: true,
      timer: null,
      currentTop: null,
      clientW: document.documentElement.clientWidth, // 视口宽
      clientH: document.documentElement.clientHeight // 视口高
    }
  },
  created() {
    this.type = JSON.parse(localStorage.getItem('type'))
    if (this.type === 1) {
      this.isFloatball = false
    } else {
      this.isFloatball = true
    }
    var left = JSON.parse(localStorage.getItem('left'))
    var top = JSON.parse(localStorage.getItem('top'))
    if (left) {
      this.left = left
      this.top = top
    } else {
      this.left = (this.clientW - this.itemWidth - 30)
      this.top = (this.clientH / 2 - this.itemHeight / 2) + 160
    }
  },
  mounted() {
    this.bindScrollEvent()
  },
  beforeDestroy() {
    // 记得销毁一些全局的的事件
    this.removeScrollEvent()
  },
  methods: {
    goHome() {
      // 点击Icon要跳转的路径,
      this.$router.push({
        path: '/mine',
        query: {
          id: this.id
        }
      })
    },
    handleTouchStart() {
      this.startToMove = true
      this.$refs.dragIcon.style.transition = 'none'
    },
    handleTouchMove(e) {
      const clientX = e.targetTouches[0].clientX// 手指相对视口的x
      const clientY = e.targetTouches[0].clientY// 手指相对视口的y
      const isInScreen = clientX <= this.clientW && clientX >= 0 && clientY <= this.clientH && clientY >= 0
      if (this.startToMove && e.targetTouches.length === 1) {
        if (isInScreen) {
          this.left = clientX - this.itemWidth / 2
          this.top = clientY - this.itemHeight / 2
        }
      }
    },
    handleTouchEnd() {
      if (this.left < (this.clientW / 2)) {
        this.left = 30// 不让贴边 所以设置30没设置0
        this.handleIconY()
      } else {
        this.left = this.clientW - this.itemWidth - 30// 不让贴边 所以减30
        this.handleIconY()
      }
      this.$refs.dragIcon.style.transition = 'all .3s'
      localStorage.setItem('left', JSON.stringify(this.left))
    },
    handleIconY() {
      if (this.top < 0) {
        this.top = 30// 不上帖上边所以设置为30 没设置0
      } else if (this.top + this.itemHeight > this.clientH) {
        this.top = this.clientH - this.itemHeight - 30// 不让帖下边所以减30
      }
      localStorage.setItem('top', JSON.stringify(this.top))
    },
    bindScrollEvent() {
      window.addEventListener('scroll', this.handleScrollStart)
    },
    removeScrollEvent() {
      window.removeEventListener('scroll', this.handleScrollStart)
    },
    handleScrollStart() {
      // this.isShow = false
      this.timer && clearTimeout(this.timer)
      this.timer = setTimeout(() => {
        this.handleScrollEnd()
      }, 300)
      this.currentTop = document.documentElement.scrollTop || document.body.scrollTop
    },
    handleScrollEnd() {
      this.scrollTop = document.documentElement.scrollTop || document.body.scrollTop
      // 判断是否停止滚动的条件
      if (this.scrollTop === this.currentTop) {
        this.isShow = true
      }
    }
  }
}
</script>

<style scoped lang="less">
.dragIcon {
    position: fixed;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: #ea5520;
    text-align: center;
    color: #fff;
    z-index: 98;
    box-shadow: 0px 1px 2px 0px rgba(248, 84, 25, 0.938);
    opacity: .9;
    .iconCont{
      padding: 5px;
      display: flex;
      justify-content: center;
      align-items: center;
      flex-wrap: wrap;
      span{
      font-size: 12px;
      }
    }
}
.v-enter {
  opacity: 1;
}
.v-leave-to {
  opacity: 0;
}
.v-enter-active,
.v-leave-active {
  transition: opacity 0.3s;
}
</style>

 

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
0 收藏
0
分享
返回顶部
顶部