可移动框 弹窗 可拖拽的组件

电脑端:

<template>
  <div
    v-if="show"
    ref="infoBox"
    @mousedown.stop="mouseDownHandler"
    class="info-box"
    :style="styleObject"
  >
    <slot></slot>
  </div>
</template>
<script>
export default {
  name: "InfoBox",
  props: {
    width: {
      type: String,
      required: false,
      default: "29.9rem"
    },
    height: {
      type: String,
      required: false,
      default: "20.8rem"
    },
    show: {
      type: Boolean,
      // required: false,
      default: false
    }
  },
  data() {
    return {
      styleObject: {
        width: "400px",
        height: "300px"
      },
      // show: true,
      isMove: false
    };
  },
  mounted() {
    this.styleObject = {
      height: this.$props.height,
      width: this.$props.width
    };
  },
  methods: {
    mouseDownHandler(e) {
      const currentPosition = {
        x: this.$refs.infoBox.offsetLeft,
        y: this.$refs.infoBox.offsetTop
      };
      const startPosition = { x: e.clientX, y: e.clientY }; //获取当前点击位置
      console.log(currentPosition, startPosition);
      this.isMove = true;
      //注册鼠标移动事件
      document.addEventListener("mousemove", event_move => {
        if (!this.isMove) return;
        const offsetX = event_move.clientX - startPosition.x,
          offsetY = event_move.clientY - startPosition.y;
        // console.log(offsetX, offsetY);
        //修改弹框位置
        this.$refs.infoBox.style.left = `${currentPosition.x + offsetX}px`;
        this.$refs.infoBox.style.top = `${currentPosition.y + offsetY}px`;
      });
      //注册鼠标抬起事件
      document.addEventListener("mouseup", () => {
        this.isMove = false;
      });
    },
    mousemoveHandler() {},
    mouseUpHandler() {}
  }
};
</script>
<style lang="scss" scoped>
.info-box {
  // .box-size(400px,300px);
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  // background: red;
  // border: 1px solid #3374ac;
  z-index: 999999;
  .nav {
    padding: 5px 10px;
    height: 35px;
    justify-content: space-between;
    .title {
      user-select: none; //禁止选中标题文字
      padding: 0px 5px;
      font-family: "AliMaMa";
      font-style: italic;
      font-size: 18px;
      color: #cee9f5;
      background-image: linear-gradient(to top, #00c6ff, #8affd2);
      /* 线性渐变背景,方向向上 */
      -webkit-background-clip: text;
      /* 背景被裁剪成文字的前景色 */
      -webkit-text-fill-color: transparent;
      /* 文字填充颜色变透明 */
    }

    .close {
      font-size: 20px;
      cursor: pointer;

      &:hover {
        color: rgb(0, 201, 252);
      }
    }
  }
}
</style>

移动端:

<template>
  <div
    ref="drawable"
    :style="{left: left, top: top}"
    class="draggable-box"
    @touchstart="touchstart"
    @touchend="touchend"
    @touchmove="mousemove"
  >
    <slot />
    <!-- <div style="width:30px;height:30px;border:1px solid red;background:red">11111111111111111111</div> -->
  </div>
</template>
<script>
export default {
  name: "DrawableBox",
  props: {
    top: String,
    left: String,
    isOnlyLeft: Boolean,
    isOnlyRight: Boolean
  },
  data() {
    return {
      flag: false
    };
  },
  methods: {
    touchstart() {
      this.flag = true;
      // 禁用页面滚动条
      document.getElementById("app").style = "overflow: hidden;";
      this.$refs.drawable.style.transition = "none";
    },

    touchend() {
      this.flag = false;
      this.$refs.drawable.style.transition = "all 0.2s";
      document.getElementById("app").style = "overflow: auto;";
      let left = this.$refs.drawable.offsetLeft;
      let screenWidth = window.screen.width;
      let oWidth = this.$refs.drawable.offsetWidth;
      // 判断是回到左边还是右边
      // if (left + oWidth / 2 <= screenWidth / 2) {
      //   this.$refs.drawable.style.left = "0px";
      // } else {
      //   this.$refs.drawable.style.left = screenWidth - oWidth + "px";
      // }
    },

    mousemove(e) {
      // 禁止默认行为,防止在微信上打开和下拉冲突
      e.preventDefault();
      if (this.flag) {
        let clientY = e.targetTouches[0].clientY;
        let clientX = e.targetTouches[0].clientX;
        let offsetHeight = this.$refs.drawable.offsetHeight;
        let offsetWidth = this.$refs.drawable.offsetWidth;
        let top = clientY - offsetHeight / 2;
        let left = clientX - offsetWidth / 2;
        // 屏幕得宽度
        let screenWidth = window.screen.width;
        let screenHeight = window.screen.height;
        let maxTop = screenHeight - offsetHeight;
        let maxLeft = 0;
        const halfWidth = screenWidth / 2;
        if (this.isOnlyLeft) {
          maxLeft = halfWidth - offsetWidth / 2;
        } else {
          maxLeft = screenWidth - offsetWidth;
        }
        if (top <= 0) {
          top = 0;
        }
        if (top > maxTop) {
          top = maxTop;
        }
        if (this.isOnlyRight) {
          if (left <= halfWidth) {
            left = halfWidth;
          }
        } else {
          if (left <= 0) {
            left = 0;
          }
        }

        console.log(left, "left");
        console.log(maxLeft, "maxLeft maxLeft");

        left = left > maxLeft ? maxLeft : left;

        console.log(left, "left 后");
        this.$refs.drawable.style.top = top + "px";
        this.$refs.drawable.style.left = left + "px";
      }
    }
  }
};
</script>
<style lang="scss" scoped>
.draggable-box {
  position: fixed;
  z-index: 3000;
}
</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值