<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>

Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐