vue实现一个可以随意拖拽的悬浮按钮组件

本文介绍了如何使用Vue开发一个名为JHoverBtn的组件,它是一个可定制的悬浮按钮,包含背景色、尺寸、点击事件和自动隐藏功能。组件中涉及了uuid生成、驼峰命名转换、CSS样式设置以及鼠标事件的处理。
摘要由CSDN通过智能技术生成
<template>
  <div
    class="j-hover-btn"
    :style="getStyle()"
    :id="uid"
    @mousedown="itemClick"
  >
    {{ text }}
  </div>
</template>

<script>
 /**
 * 随机生成uuid
 * @return string 生成的uuid
 */
 function randomUUID() {
  let chats = '0123456789abcdef'
  return randomString(32, chats)
 }
 
  /**
 * @description 驼峰命名转换成'-'连接命名
 * @param {String} str 需要转换的字符串
 * @return {String} '-'连接形式字符串
 **/
 function camelTo_ = function (str) {
  let res = "";
  for (let i = 0; i < str.length; i++) {
    if (str[i] >= "A" && str[i] <= "Z") {
      if (i == 0) res += str[i].toLowerCase();
      else {
        res += "-" + str[i].toLowerCase();
      }
    } else {
      res += str[i];
    }
  }
  return res;
 };

  export default {
    name: "JHoverBtn",
    props: {
      bgColor: {
        type: String,
        default: "#011834",
      },
      autoHide: {
        type: Boolean,
        default: true,
      },
      clickDis: {
        type: Number,
        default: 10,
      },
      showWidth: {
        type: Number,
        default: 15,
      },
      width: {
        type: Number,
        default: 80,
      },
      height: {
        type: Number,
        default: 30,
      },
      radius: {
        type: String,
        default: "8%",
      },
      btnStyle: {
        type: Object,
        default: () => {},
      },
      text: {
        type: String,
        default: "悬浮按钮",
      },
      zIndex: {
        type: Number,
        default: 9999,
      },
    },
    data() {
      return {
        startX: "",
        startY: "",
        clickStatus: false,
        isClick: true,
        uid: "",
      };
    },
    created() {
      this.setId();
    },
    mounted() {
      this.preventEvent();
      window.addEventListener("mouseup", this.handleMouseup);
      window.addEventListener("mouseover", this.handleMouseover);
    },
    methods: {
      setId() {
        this.uid = randomUUID() + "j-hover-btn";
      },
      getStyle(res = "") {
        res += "background-color:" + this.bgColor + ";";
        res += "width:" + this.width + "px;";
        res += "height:" + this.height + "px;";
        res += "line-height:" + this.height + "px;";
        res += "z-index:" + this.zIndex + ";";
        res += "border-radius:" + this.radius + ";";
        let btnStyle = this.btnStyle;
        for (let k in btnStyle) {
          res += camelTo_(k) + ":" + btnStyle[k] + ";";
        }
        return res;
      },
      //阻止默认事件
      preventEvent() {
        document.getElementById(this.uid).ondragstart = function () {
          return false;
        };
        document.getElementById(this.uid).onselectstart = function () {
          return false;
        };
      },
      windowPreventEvent() {
        window.ondragstart = function () {
          return false;
        };
        window.onselectstart = function () {
          return false;
        };
      },
      windowPreventEventCancel() {
        window.ondragstart = null;
        window.onselectstart = null;
      },
      itemClick(event) {
        this.startX = event.pageX - window.scrollX;
        this.startY = event.pageY - window.scrollY;
        this.clickStatus = true;
        this.windowPreventEvent();
      },
      //鼠标抬起时
      handleMouseup(event) {
        if (this.clickStatus) {
          const endX = event.pageX - window.scrollX,
            endY = event.pageY - window.scrollY;
          if (this.isClick) {
            this.$emit("hoverBtnClick");
          } else {
            if (!this.autoHide) return;
            const width = document.body.offsetWidth;
            const height = document.body.offsetHeight;
            const dom = document.getElementById(this.uid);
            if (endX < this.width / 2) {
              dom.style.left = -(this.width - this.showWidth) + "px";
            } else if (endX > width - this.width / 2) {
              dom.style.left = width - this.showWidth + "px";
            }
          }
          this.clickStatus = false;
          this.isClick = true;
          this.windowPreventEventCancel();
        }
      },

      handleMouseover(event) {
        if (this.clickStatus) {
          const endX = event.pageX - window.scrollX,
            endY = event.pageY - window.scrollY;
          const dom = document.getElementById(this.uid);
          if (
            Math.abs(endX - this.startX) > this.clickDis ||
            Math.abs(endY - this.startY) > this.clickDis
          ) {
            this.isClick = false;
          }
          dom.style.left = endX - this.width / 2 + "px";
          dom.style.top = endY - this.height / 2 + "px";
        }
      },
    },
  };
</script>

<style lang="less" scoped>
  .j-hover-btn {
    text-align: center;
    cursor: pointer;
    position: fixed;
    color: #fff;
    box-shadow: 0 0 0 5px rgba(255, 255, 255,0.5);
  }
</style>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值