如何自定义右键弹框并实现位置自适应?

一、问题

右键显示弹框,但是靠近浏览器边缘的部分会被隐藏,需要实现弹框位置自适应

二、 问题分析

如果想要最终弹框的宽高不超过屏幕视口,就等于屏幕视口的总宽/高减去弹框打开时的起点坐标,剩下的部分大于等于弹框的宽/高,简单来说,可以套用以下公式:

1.1 屏幕视口宽(clientWidth) - 鼠标点击的x轴(pageX) >= 弹框宽

1.2 屏幕视口高(clientHeight) - 鼠标点击y轴(pageY) >= 弹框高

三、实现步骤(vue3+ts)

1.首先获取屏幕视口的宽高

	const windowWidth = ref(document.documentElement.clientWidth);const windowHeight = ref(document.documentElement.clientHeight);

2.获取弹框打开时的起点,也就是当前鼠标点击的位置

宽 :e.pageX

高:e.pageY

3.获取弹框的宽高

在此我给的是固定宽500px高300px,如果是动态宽高请自行获取

4.给弹框设置固定定位,对应的left和top值如下:

left: windowWidth - e.pageX >= 500 ? e.pageX : windowWidth - 500, 

top: windowHeight - e.pageY >= 300 ? e.pageY : windowHeight - 300,

 

四、完整代码

1.自定义的弹框组件

<!--* @Description: 自定义右键弹框组件* @FilePath: \Vue3-demo\src\myComponents\rightClickPopUpBox\index.vue
-->
<template><divclass="container":style="{left: state.positionStyle.left + 'px',top: state.positionStyle.top + 'px',}"v-if="state.visible"><div class="content">{{ state.title }}</div><div class="footer"><el-button size="default" type="success">保存</el-button><el-button size="default" type="primary" @click="closeDialog">取消</el-button></div></div>
</template>
<script setup lang="ts" name="popUpBox">
import { reactive, ref } from 'vue';const state: any = reactive({visible: false, // 是否显示title: '',positionStyle: {},
});const openDialog = (data: any) => {state.title = '按钮' + data.item + '的内容区域';state.visible = true;// 获取屏幕视口大小const windowWidth = ref(document.documentElement.clientWidth);const windowHeight = ref(document.documentElement.clientHeight);state.positionStyle = {// 这种方案不好,因为鼠标点击位置可能超出屏幕视口// top: data.e.pageY,// left: data.e.pageX,left: windowWidth.value - data.e.pageX >= 500 ? data.e.pageX : windowWidth.value - 500,top: windowHeight.value - data.e.pageY >= 300 ? data.e.pageY : windowHeight.value - 300,};
};const closeDialog = () => {state.visible = false;
};defineExpose({openDialog,closeDialog,
});
</script>
<style lang="scss" scoped>
.container {position: fixed;width: 500px;height: 300px;border: 1px solid #000;padding: 15px;background-color: #bbc1ff;.content {width: 100%;height: 80%;display: flex;justify-content: center;align-items: center;background-color: #fff;font-weight: bold;font-size: 20px;}.footer {flex: 1;display: flex;justify-content: center;margin-top: 20px;}
}
</style>

 2.组件展示

<!--* @Description: 我的组件-自定义右键弹框* @FilePath: \Vue3-demo\src\views\showMyComponents\rightClickPopUpBox\index.vue
-->
<template><div class="layout-container layout-padding" @click="cancelPop($event)"><div class="boxList"><el-button size="large" type="primary" v-for="item in 10" :key="item" @contextmenu.prevent="handleContextMenu($event, item)">{{'按钮' + item + ' : 请点击右键'}}</el-button></div><PopUpBox ref="popUpBoxRef" class="popUpBox" /></div>
</template>
<script setup lang="ts" name="rightClickPopUpBox">
import { ref } from 'vue';
import PopUpBox from '/@/myComponents/rightClickPopUpBox/index.vue';
const popUpBoxRef = ref();// 右键事件-打开弹框
const handleContextMenu = (e: MouseEvent, item: any) => {console.log(e, '右键坐标');const data = { e, item };popUpBoxRef.value.openDialog(data);
};// 点击弹框以外的地方关闭弹框
const cancelPop = (event: any) => {const box = document.querySelector('.popUpBox');if (box) {if (!box.contains(event.target)) {popUpBoxRef.value.closeDialog();}}
};
</script>
<style lang="scss" scoped>
.boxList {display: flex;flex-direction: row;justify-content: space-between;width: 100px;height: 50px;
}
</style>

五、补充

1.clientX、clientY

点击位置距离当前body可视区域的x,y坐标

2.pageX、pageY

对于整个页面来说,包括了被卷去的body部分的长度

3.screenX、screenY

对于整个屏幕来说(点击位置距离当前电脑屏幕的x,y坐标),包括了被卷去的body部分的长度

4.offsetX、offsetY

对于当前元素来说(相对于带有定位的父盒子的x,y坐标),包括了被卷去的body部分的长度

5.x、y

对于当前元素来说,不包括被卷去的body部分的长度

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

商家如何进行商业模式开发,助力产品更好的销售模式?

商家如何进行商业模式开发&#xff0c;助力产品更好的销售模式&#xff1f; 随着各类电商平台的疯狂崛起&#xff0c;越来越多的商家对其中带来的高额回报率产生心动&#xff0c;毕竟对于线上的场景来说&#xff0c;即省去了房租、水电、仓储以及其他各种费用&#xff0c;用电商…

vue3 + TypeScript使用国际化

vue3 TypeScript使用国际化 本文使用了 Vite 构建工具创建的vue3项目Vite 支持使用特殊的 import.meta.glob 函数从文件系统导入多个模块Vite 官方中文文档当然如果你的vue3项目未使用vite,你也可以为你的旧项目提提速&#xff0c;安装vite &#xff0c;安装方法在上一个博客…

【华为数据之道学习笔记】6-5数据地图的核心价值

数据供应者与消费者之间往往存在一种矛盾&#xff1a;供应者做了大量的数据治理工作、提供了大量的数据&#xff0c;但数据消费者却仍然不满意&#xff0c;他们始终认为在使用数据之前存在两个重大困难。 1&#xff09;找数难 企业的数据分散存储在上千个数据库、上百万张物理表…

汽车行业一些知识

一、汽车术语集合 1、 轴距(mm)&#xff1a;汽车前轴中心至后轴中心的距离。 2、转弯半径(mm)&#xff1a;汽车转向时&#xff0c;汽车外侧转向轮的中心平面在车辆支撑平面上的轨迹圆半径。转向盘转到极限位置时的转弯半径为最小转弯半径。 3、最大总质量(kg)&#xff1a;汽…

C# Assembly(加载反射)获取对象属性及执行

参考官网&#xff1a;Assembly 类 (System.Reflection) | Microsoft Learn 使用类&#xff1a;Assembly 命名空间&#xff1a;System.Reflection Type类中包含Assembly typeof(Serilog日志保存).Assembly.GetExportedTypes(); Assembly加载反射 Assembly.GetExportedType…

springboot(ssm老年一站式服务平台 老人服务系统Java系统

springboot(ssm老年一站式服务平台 老人服务系统Java系统 开发语言&#xff1a;Java 框架&#xff1a;ssm/springboot vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&#xff1a;mysql 5.7&#xff08;或8.0&#xff09; …

动态数组的实现

定义 1. 在计算机科学中&#xff0c;数组是由一组元素&#xff08;值或变量&#xff09;组成的数据结构&#xff0c;每个元素有至少一个索引或键来标识。 2. 因为数组内的元素是连续存储的&#xff0c;所以数组中元素的地址&#xff0c;可以通过其索引计算出来。 3. 知道了数…

计算机网络-网络层

计算机网络-网络层 以下笔记整理为哔哩哔哩湖科大教书匠的《计算机网络微课堂》的教学视频。 链接&#xff1a;计算机网络微课堂 1. 网络层概述 1.1 网络层的主要任务是实现网络互联&#xff0c;进而实现数据包在各网络之间的传输。 1.2 要实现网络层任务&#xff0c;需要解决…

【飞凌 OK113i-C 全志T113-i开发板】一些有用的常用的命令测试

一些有用的常用的命令测试 一、系统信息查询 可以查询板子的内核信息、CPU处理器信息、环境变量等 二、CPU频率 从上面的系统信息查询到&#xff0c;这是一颗具有两个ARMv7结构A7内核的处理器&#xff0c;主频最高1.2GHz 可以通过命令查看当前支持的频率以及目前所使用主频 …

Spring IoCDI

文章目录 前言什么是Spring1. 什么是 IoC 容器1.1 什么是容器1.2 什么是 IoC 2. 什么是DI IoC & DI 的使用IoC详解Bean的存储Controller注解如何获取Bean1. 根据Bean的名称获取Bean2. 根据Bean类型获取Bean3. 根据Bean名和Bean类型获取Bean Service注解Repository注解Compo…

Android Framework一些问题思考

一&#xff0c;zygote通信为什么用socket&#xff0c;而不是binder? 1&#xff0c;binder通信依赖Servicemanager&#xff0c;socket通信不依赖用户空间进程。zygote与servicemanager, surfaceflinger等都是通过各自init.rc被init创建&#xff0c;时序上无法保证zygote启动时…

使用Docker一键部署Uptime Kuma,并将监控服务映射至公网访问

文章目录 **主要功能**一、前期准备本教程环境为&#xff1a;Centos7&#xff0c;可以跑Docker的系统都可以使用本教程安装。本教程使用Docker部署服务&#xff0c;如何安装Docker详见&#xff1a; 二、Docker部署Uptime Kuma三、实现公网查看网站监控四、使用固定公网地址访问…

go语言初体验1--使用go install

当安装后go语言后。 尝试编写go程序。 当使用 go install 命令&#xff0c;报错。 go: go install requires a version when current directory is not in a moduleTry go install jvmgo\ch01latest to install the latest version通过查找资料。 用命令&#xff1a; go env …

【Qt之Quick模块】4. QML语法格式及命名规范

概述 QML&#xff08;Qt Meta-Object Language&#xff09;是一种声明式语言&#xff0c;用于设计用户界面。它是由Qt框架提供的一种描述界面组件的语言&#xff0c;可以与C代码结合使用&#xff0c;用于创建跨平台的应用程序。 QML具有以下特点&#xff1a; 声明式&#xff…

混合精度训练(MAP)

一、介绍 使用精度低于32位浮点数的数字格式有很多好处。首先&#xff0c;它们需要更少的内存&#xff0c;可以训练和部署更大的神经网络。其次&#xff0c;它们需要更少的内存带宽&#xff0c;这加快了数据传输操作。第三&#xff0c;数学运算在降低精度的情况下运行得更快&a…

YOLOv5算法改进(23)— 更换主干网络GhostNet + 添加CA注意力机制 + 引入GhostConv

前言:Hello大家好,我是小哥谈。本节课就让我们结合论文来对YOLOv5进行组合改进(更换主干网络GhostNet + 添加CA注意力机制 + 引入GhostConv),希望同学们学完本节课可以有所启迪,并且后期可以自行进行YOLOv5算法的改进!🌈 前期回顾: YOLOv5算法改进(1)— 如何去…

C++类与对象(中)第一篇

目录 前言&#xff1a; 类的六个默认成员函数 构造函数 析构函数 拷贝构造函数 拷贝场景一&#xff1a;函数参数类型为类类型对象 拷贝场景二&#xff1a;利用已存在的对象创建新对象 拷贝场景三&#xff1a;函数返回值类型为类类型对象 前言&#xff1a; 编译器编译类…

推箱子地图库1-49关

推箱子地图库1-49关 49关 local WALL1--{"墙","墙 "}4 10287 local DEST2--{"目的地",""}1 4001100 10157 local BOX3--{"箱子","&#xffe5;"} 2 2000801 local PLAYER4--{"玩家","&&a…

python依赖包管理

在Python项目中&#xff0c;通常会有一个名为 requirements.txt 的文件&#xff0c;其中列出了项目所需的所有依赖包及其版本。 1. 使用freeze 如果你的项目中没有 requirements.txt 文件&#xff0c;你可以通过下面的命令创建一个当前项目所在环境下已安装的包及其版本的 re…

vue中的生命周期和VueComponent实例对象

生命周期 关于VueComponent 生命周期又叫生命周期钩子&#xff0c;生命周期函数 生命周期是&#xff0c;Vue在关键的时刻帮我们调用的一些特殊名字的函数 生命周期的this指向vm或者组件实例对象 mounted会将初始化的Dom挂载到页面上 <template><div class"he…