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

电脑端:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/195364.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

自媒体爆文采集工具,几个免费的网站让你每日爆文增加

随着自媒体的蓬勃发展&#xff0c;许多人憧憬着在这个领域获得成功和流行。然而&#xff0c;随着寒冷的冬天的降临&#xff0c;媒体从业者的日常生活并没有变得更加美好。在竞争激烈的环境中&#xff0c;为了生存&#xff0c;他们必须发布引人注目的内容&#xff0c;然而&#…

4个Python实战项目,让你瞬间读懂Python!

前言 Python 是一种极具可读性和通用性的编程语言。Python 这个名字的灵感来自于英国喜剧团体 Monty Python&#xff0c;它的开发团队有一个重要的基础目标&#xff0c;就是使语言使用起来很有趣。Python 易于设置&#xff0c;并且是用相对直接的风格来编写&#xff0c;对错误…

从裸机启动开始运行一个C++程序(十五)

前序文章请看&#xff1a; 从裸机启动开始运行一个C程序&#xff08;十四&#xff09; 从裸机启动开始运行一个C程序&#xff08;十三&#xff09; 从裸机启动开始运行一个C程序&#xff08;十二&#xff09; 从裸机启动开始运行一个C程序&#xff08;十一&#xff09; 从裸机启…

lightdb-ignore_row_on_dupkey_index

LightDB 支持 ignore_row_on_dupkey_index hint LightDB 从23.4 开始支持oracle的 ignore_row_on_dupkey_index hint&#xff0c; 这个hint是用来忽略唯一键冲突的。类似与mysql的 insert ignore。 语法如下&#xff1a; 在LightDB中ignore_row_on_dupkey_index的效果等同于o…

大坝安全监测的内容及作用

大坝安全监测是指对大坝水雨情沉降、倾斜、渗压以及大坝形状特征有效地进行监测&#xff0c;及时发现潜在的安全隐患和异常情况&#xff0c;以便大坝管理人员能够做出科学决策&#xff0c;以确保大坝安全稳定运行。 大坝安全监测的主要内容 1.表面位移监测&#xff1a;监测大坝…

Vue基础入门(三):Vue3的使用

Vue3的使用 一、首页案例修改 修改首页的信息&#xff1a;是在之前介绍的HelloWorld.vue文件中进行内容的修改。 页面展示效果&#xff1a; 此时就看到了我们新添加的文字了&#xff01; 同样的我们开发代码的时候只需要修改了项目中的内容然后保存就会自动刷新的浏览器&…

接口测试:Jmeter和Postman测试方法对比

前阶段做了一个小调查&#xff0c;发现软件测试行业做功能测试和接口测试的人相对比较多。在测试工作中&#xff0c;有高手&#xff0c;自然也会有小白&#xff0c;但有一点我们无法否认&#xff0c;就是每一个高手都是从小白开始的&#xff0c;所以今天我们就来谈谈一大部分人…

OpenSearch向量检索和大模型方案深度解读

大家好&#xff0c;我叫邢少敏&#xff0c;目前负责阿里云开放搜索OpenSearch的研发&#xff0c;很高兴在此跟大家分享OpenSearch在向量检索和大模型方面做的一些工作。 基于向量检索的分布式智能搜索引擎 通常&#xff0c;数据大致可以分为结构化数据和非结构化数据两种类型…

“2024上海智博会、2024北京智博会”双展联动,3月上海,6月北京

“2024上海智博会、2024北京智博会”双展联动&#xff0c;将分别于3月和6月在上海和北京举办。这两个展会旨在充分展示智慧城市、人工智能、物联网、大数据、软件等新兴行业的最新产品和技术。 作为中国最具影响力和创新力的智能科技展会&#xff0c;上海智博会和北京智博会吸引…

ArkTS-属性动画和显式动画

属性动画 组件的某些通用属性变化时&#xff0c;可以通过属性动画实现渐变过渡效果&#xff0c;提升用户体验。支持的属性包括width、height、backgroundColor、opacity、scale、rotate、translate等。 名称参数类型必填描述durationnumber否设置动画时长。默认值&#xff1a;1…

ArkUI 如何将$r(’app.string.xxx‘) 转成string字符串

一、正常引用字符串资源文件内容 在 ArkUI 中&#xff0c;string.json 中的字符串资源正常情况下使用如下方式引用&#xff1a; Entry Component struct LoginPage {build() {Column() {Text($r(app.string.title))}}}二、资源转string类型 上面的代码没问题是因为 Text(con…

探究Kafka原理-7.exactly once semantics 和 性能测试

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理&#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44…

盖茨表示GPT-5不会比GPT-4有太大改进;Intro to Large Language Models

&#x1f989; AI新闻 &#x1f680; 盖茨表示GPT-5不会比GPT-4有太大改进 摘要&#xff1a;比尔盖茨在与德国《商报》的采访中透露&#xff0c;虽然OpenAI内部有人相信GPT-5会优于GPT-4&#xff0c;但他认为目前的生成式人工智能已经达到极限。盖茨对GPT-5未来的发展并不乐观…

Vue基础入门(四):Vue3快速开发模板

快速开发Vue的解决方案 ​ Vue 的开发需要的 node 环境&#xff0c;其实上在开发的过程中会遇到一些你想不到的问题&#xff0c;比如 npm工具的版本和 node 环境不匹配&#xff08;你把其他项目导入到自己的环境&#xff09; ​ vue-element-admin&#xff08;是一个官方提供…

Ubuntu系统CLion安装

Ubuntu系统CLion安装 pycharm 同理。 参考官网安装过程&#xff1a;官网安装过程 下载linux tar.gz包 # 解压 sudo tar -xzvf CLion-*.tar.gz -C /opt/ sh /opt/clion-*/bin/clion.sh其中第二个命令是启动CLion命令 clion安装完以后&#xff0c;不会在桌面或者菜单栏建立图…

Containerd Container管理功能解析

Containerd Container管理功能解析 container是containerd的一个核心功能&#xff0c;用于创建和管理容器的基本信息。 本篇containerd版本为v1.7.9。 更多文章访问 https://www.cyisme.top 本文从ctr c create命令出发&#xff0c;分析containerd的容器及镜像管理相关功能。 …

[英语学习][3][Word Power Made Easy]的精读与翻译优化

[序言] 这次翻译校验, 难度有点大, 原版中英翻译已出现了严重地偏差. 昨晚11点开始阅读如下段落, 花费了1个小时也没有理解原作者的核心表达, 索性睡觉了. 今早学习完朗文单词之后, 9点半开始继续揣摩. 竟然弄到了中午11点30, 终于明白原作者要表达的意思了. 废话不多说&#x…

Selenium 学习(0.14)——软件测试之测试用例设计方法——因果图法2【基本步骤及案例】

1、因果图法的基本步骤 2、案例分析 1&#xff09;分析原因和结果 2&#xff09;关联原因和结果 投入1元5角或2元&#xff0c;按下“可乐”&#xff0c;送出“可乐”【暂时忽略找零】 投入2元&#xff0c;按下“可乐”或“雪碧”。找零5角&#xff0c;送出“可乐”或“雪…

大量用户弃用5G网络,四大运营商血亏? 喜闻乐见

家人们&#xff0c;老百姓讨厌5G网络&#xff0c;不是一天两天的事情了&#xff0c;有人认为5G网络是个坑&#xff0c;我们就应该永远用4G网络才对&#xff0c;国家为何要折腾这事&#xff1f;肯定是闲的。 正是这种思维的蔓延&#xff0c;导致了大量用户弃用5G网络。这事对四大…

搭建Angular并引入NG-ZORRO组件库

作者&#xff1a;baekpcyyy&#x1f41f; 1.安装node.js 注&#xff1a;安装 16.0 或更高版本的 Node.js node官网&#xff1a;https://nodejs.org/en 2.进入angular官网 https://angular.cn/guide/setup-local 新建一个文件夹 vsc打开 打开终端 1.首先安装angular手脚架…