vue移动端浮动导航组件实现方式

<template>
  <div class="float-page">
    <div v-if="listShow" @click="hide" class="float-mask"></div>
    <div
      :style="{top:yPum+'px',left:xPum+'px'}"
      ref="floatNav"
      @click="show"
      @mousedown="down"
      @touchstart="down"
      @mousemove="move"
      @touchmove="move"
      @mouseup="end"
      @touchend="end"
      class="float-box"
      id="moveDiv"
    >
      <div class="content">
        内容
      </div>
    </div>
  </div>
</template>
<script>
import axios from "axios";
import { isWxAli } from "@/common/common";
import { linkBaseUrl, baseUrl, qyyxUrl } from "../../config/index";
import vueCookie from "vue-cookie";
export default {
  props: {
    left: {
      type: String | Number,
      default: 270
    },
    top: {
      type: String | Number,
      default: 100
    }
  },
  data() {
    return {
      qyyxShow: false,
      qyyxFlag: "",
      userImg: "",
      topFlag: false,
      listHeight: 250,
      widthHeight: 115,
      listShow: false,
      distance: 10,
      innerHeight: 0,
      flags: false,
      position: { x: 0, y: 0 },
      nx: "", //x移动距离
      ny: "", //y移动距离
      dx: "",
      dy: "",
      xPum: this.left,
      yPum: this.top,
      screenHeight: window.screen.height,
      screenWidth: window.screen.width
    };
  },
  created() {
   
  },
  computed: {
    rightFlag() {
      return this.xPum <= this.widthHeight;
    }
  },
  mounted() {
    let _this = this;
    _this.innerHeight = _this.getInnerHeight();
    // console.log(this.$refs.floatNav,this.$refs.floatNav.offsetWidth,this.$refs.floatNav.offsetHeight)
    this.floatNavWidth = this.$refs.floatNav.offsetWidth;
    this.floatNavHeight = this.$refs.floatNav.offsetHeight;
    window.addEventListener("scroll", function() {
      _this.innerHeight = _this.getInnerHeight();
    });
  },
  methods: {
   
    
    
    hide() {
      this.listShow = false;
      this.topFlag = false;
    },
    show() {
      // console.log(this.xPum);
      // console.log(this.yPum);
      if (this.yPum <= this.innerHeight - this.listHeight) {
        // console.log("下弹");
        this.topFlag = false;
      } else {
        // console.log("上弹");
        this.topFlag = true;
      }
      // if (this.xPum <= this.widthHeight) {
      //   console.log("右弹");
      //   this.rightFlag = true;
      // } else {
      //   console.log("左弹");
      //   this.rightFlag = false;
      // }
      this.$nextTick(() => {
        this.listShow = !this.listShow;
        // this.topFlag = this.listShow;
      });
    },
    getInnerHeight() {
      if (window.innerHeight != undefined) {
        return window.innerHeight;
      } else {
        let B = document.body,
          D = document.documentElement;
        return Math.min(D.clientHeight, B.clientHeight);
      }
    },
    down(event) {
      this.flags = true;
      let touch;
      if (event.touches) {
        touch = event.touches[0];
      } else {
        touch = event;
      }
      // console.log(this.$refs.women,this.$refs.floatNav.offsetLeft,this.$refs.floatNav.offsetTop);
      this.position.x = touch.clientX || event.changedTouches[0].clientX;
      this.position.y = touch.clientY || event.changedTouches[0].clientY;
      this.dx = this.$refs.floatNav.offsetLeft;
      this.dy = this.$refs.floatNav.offsetTop;
    },
    move(event) {
      // console.log(event);
      if (this.flags && !this.listShow) {
        var touch;
        if (event.touches) {
          touch = event.touches[0];
        } else {
          touch = event;
        }
        this.nx = touch.clientX - this.position.x;
        this.ny = touch.clientY - this.position.y;
        this.xPum = this.dx + this.nx;
        this.yPum = this.dy + this.ny;
        event.preventDefault();
      }
    },
    end() {
      this.flags = false;
      if (this.xPum < 0) {
        this.xPum = this.distance;
      }
      if (this.yPum < 0) {
        this.yPum = this.distance;
      }
      if (this.xPum > this.screenWidth - this.floatNavWidth) {
        this.xPum = this.screenWidth - this.distance - this.floatNavWidth;
      }
      if (
        this.yPum >
        this.screenHeight -
          this.floatNavHeight -
          (this.screenHeight - this.innerHeight)
      ) {
        this.yPum =
          this.screenHeight -
          this.distance -
          this.floatNavHeight -
          (this.screenHeight - this.innerHeight);
      }
    }
  }
};
</script>

<style lang="scss" scoped>
.float-page {
  .float-mask {
    position: fixed;
    z-index: 998;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    background: rgba(255, 255, 255, 0.8);
  }
  .float-box {
    position: fixed;
    z-index: 999;
    .x-num {
      top: 0;
      left: -50px;
      position: absolute;
    }
    .y-num {
      left: 0;
      top: -50px;
      position: absolute;
    }
    .img-box {
      position: relative;
      // background-image: url();
      // background-size: 100% 100%;
      height: 57px;
      width: 87px;
      display: flex;
      align-items: center;
      .bg-img {
        height: 100%;
        width: 100%;
      }
      .default-logo {
        position: absolute;
        left: 16px;
        bottom: 6px;
        margin: 0 auto;
        height: 45px;
        width: 45px;
        border-radius: 50%;
        z-index: 101;
      }
      .default-icon {
        position: absolute;
        z-index: 102;
        left: 16px;
        bottom: 6px;
        height: 45px;
        width: 45px;
        border-radius: 50%;
        background: #f90;
        text-align: center;
        opacity: 0;
        transition: all 2s;
        -webkit-transition: all 0.5s; /* Safari */
        transform: scale(1) rotate(0deg);
        &.icon-open {
          opacity: 1;
          transform: scale(1) rotate(360deg);
        }
        i {
          font-size: 24px;
          line-height: 45px;
          color: #fff;
          font-weight: bold;
        }
      }
      .my-text {
        position: absolute;
        left: 16px;
        bottom: -6px;
        z-index: 300;
        height: 16px;
        line-height: 16px;
        font-size: 11px;
        color: #fff;
        background: #ffba00;
        width: 45px;
        text-align: center;
        border-radius: 8px;
        &.test {
          transform: translateX(100px);
        }
      }
      .list {
        list-style: none;
        .item {
          width: 115px;
          opacity: 0;
          position: absolute;
          right: 27px;
          top: 0;
          transition: all 0.5s;
          -webkit-transition: all 0.5s; /* Safari */
          .icon {
            margin-left: 5px;
            width: 45px;
            height: 45px;
            text-align: center;
            background: #f90;
            border-radius: 50%;
            i {
              font-size: 24px;
              line-height: 45px;
              color: #fff;
              font-weight: bold;
            }
          }
          .text {
            display: inline-block;
            height: 45px;
            line-height: 45px;
            font-size: 14px;
            color: #413838;
          }
        }
        &.open {
          .item {
            opacity: 1;
          }
          .item:nth-child(1) {
            transform: translateY(70px);
          }
          .item:nth-child(2) {
            transform: translateY(140px);
          }
          .item:nth-child(3) {
            transform: translateY(210px);
          }
          &.is-top {
            .item:nth-child(1) {
              transform: translateY(-70px);
            }
            .item:nth-child(2) {
              transform: translateY(-140px);
            }
            .item:nth-child(3) {
              transform: translateY(-210px);
            }
          }
        }
        &.is-right {
          .item {
            right: -38px;
            .icon {
              float: left;
              margin-right: 5px;
            }
            .text {
              float: left;
            }
          }
        }
      }
    }
  }
}
</style>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值