position定位 响应式_使用 Vue3 实现双盒子定位 Overlay

之前说过,使用  可以很优雅的把某个组件渲染到根节点之外的节点,同时使其渲染的内容不丧失响应式和对应的生命周期函数调用。那么基于此,用  实现相对于某一元素的 Overlay 。

实际上,这篇文章跟 Vue3 的关系不大,只是通过 Vue3 讲解一类 Overlay 的设计方法。

原理

要实现相对于某一元素的 Overlay 需要依靠两个元素,Origin 和 Panel,Origin 表示相对于的元素,而 Panel 表示 Overlay 本身,实现方法主要有两种。

1.基于 position 的absolute 和 relative 特性,将 Origin 和 Panel 形成相互依赖的关系。2.Overlay 基于 Origin 做固定偏移的双盒子定位法,也就是本文需要讲解的方法。

实现

首先,通过,能够建立顶层 Overlay,也就是在根节点创建一个新的节点。

setup(_, ctx) {  const originRef = ref();  const panelRef = ref();  const panelStyle = ref({ position: 'absolute' });  // ...  return () => (    <>      
ref={originRef}>origin
"#cdk-overlay-anchor">
'fixed', top: 0, left: 0, right: 0, bottom: 0, height: '100vh', width: '100vw' pointerEvents: 'none'}}>
ref={panelRef} style={panelStyle.value}>
'100px', width: '100px' border: '1px solid black'}} />
> );}

拿到这两者的 dom ref 后,需要通过实时计算 Origin 的盒子的大小和位置,来获得 Panel 的相对偏移。在 Vue 中,元素只有在 mounted 后才能获取得到,所以可以通过 composition-api 的 onMouted 来获取具体元素。然后再在 生命周期中 进行计算。

计算两个盒子的相对位置

如何计算 Origin 的大小和位置,以及获取其变化后的监听。Origin 的大小和位置,通过 getBoundingClientRect 这一 API 来获取,这一就可以开始计算 Overlay 的相对位置。假设我们要把Overlay放在Origin的正下方,计算函数应该是这样的。

const panelStyle = ref({ position: 'absolute' });onMounted(() => {  const origin = originRef.value;  const panel = panelRef.value;  if (!origin || !panel) {    return ;  }  const calculate = () => {    const rect = origin.getBoundingClientRect();    // 原点为 origin 元素的底边中央正下方    const originX = rect.left + (rect.width / 2);    const originY = rect.bottom;    // panel的坐标为到原点的偏移    const panelRect = panel.getBoundingClientRect();    const panelX = originX - panelRect.width / 2;    const panelY = originY;    // 设置 panel 数据,触发节点变更    panelStyle.value.left = `${panelX}px`;    panelStyle.value.top = `${panelY}px`;  };});

当然,你还可以计算各个不同方向的 Panel 坐标(比如,正左、正上、正下等),排列组合一下,一共有81种不同的情况(每个点依赖于两个变量 X 和 Y,每个变量有三种不同的情况,左、中、右,或者,上、中、下)。

监听盒子的变化

在这里,我们将使用浏览器自带的API 来对他们进行监听。通过 MutationObserver 和 ResizeObserver,可以很轻松的监听 Origin 和 Panel 的大小和位置变化。

首先是监听 Origin 的大小和位置变化,这里采用的是 MutationObserver,因为导致位置变化的原因只能是 style,所以只需要监听 style 的变化即可。

const origin$ = new MutationObserver(calculate);origin$.observe(origin, {  // 只需要拿到 attribute 的 style 的变化即可  attributeFilter: ['style'],});

Panel 只需要监听其大小的变化,大小变化有一个更加完美的API, ResizeObserver。

const panel$ = new ResizeObserver(calculate);panel$.observe(panel);

然后,需要在dom销毁前取消监听。

// dom销毁前取消监听onBeforeUnmount(() => {  origin$.disconnect();  panel$.disconnect();});

监听窗口事件

为了能够正确的获取变化,我们需要监听两个事件:resize 和 scroll.

// 为了能够在滚动事件捕获前进行计算,带有滚动条的子元素也会因此触发计算window.addEventListener('scroll', calculate, true);window.addEventListener('resize', calculate);

最后,仍然要在销毁前取消事件。

// dom销毁前取消监听onBeforeUnmount(() => {  window.removeEventListener('scroll', calculate, true);  window.removeEventListener('resize', calculate);});

至此,已经完成基本的双盒子定位法的 Overlay 的设计。

小结

通过双盒子定位来构建的 Overlay 能够有效规避 CSS 带来的问题 zindex 等一系列相关的问题,只用通过计算盒子之间的相对偏移,就能让 Panel 附着于 Origin 上,这样,实现类似下拉或者 Tooltip 等功能的时候,就会非常有用。同时,附上一个简单例子71202456bb83431359d19a96463c13dd.pnghttp://zcating.gitee.io/testhub/#/overlay),希望能带来一些启发。

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

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

相关文章

模型化的SAP系统权限管理

IDS Scheer中国副总裁 王磊 SAP系统刚上线时&#xff0c;系统内的权限管理往往并不引起重视。大家关注 更多的是系统能否顺畅运行、数据是否准确&#xff0c;财务帐是否能对得上等等。事实上&#xff0c;此时为了确保系统迅速转起来&#xff0c;给很多用户的权限往往是放大的。…

月薪5 千~1万的兼职你要不要?不限学历,不限男女!

全世界只有3.14 % 的人关注了爆炸吧知识你想拥有一份月薪过万的兼职吗&#xff1f;窝在家里就行的那种&#xff1f;这就有一份看起来高大上、实则难度系数并不高的英语翻译&#xff01;兼职英语翻译到底有多赚钱&#xff1f;水平一般的英语笔译员一周7天每天拿出2小时翻译&…

电子商务时代企业统计的发展方向

摘要&#xff1a;电子商务的出现,对现代企业产生了巨大的影响。它从多个方面影响着现代企业的发展,其中即有机遇也有挑战。文章将从企业统计面临的理论、职能、组织等方面的困境,阐述电子商务的影响。 一、企业统计工作面临时代困境 1.企业统计理论困境 任何企业统计理论总是建…

c语言课程设计加密程序,C语言课程设计文件加密解密.doc

C语言课程设计文件加密解密C语言程序设计 课程设计学 院 计算机工程 班 级 计算1313姓 名 学 号 201321121089成 绩 指导老师2014年6月26日计算1313班C语言程序设计课程设计大纲一、设计目的&#xff1a;通过课程设计&#xff0c;学会把相关的理论知识和实际应用相结合&#xf…

【分享】154页微软WPF官方手册(含.NETCore和.NET Framwork双版本)

物联网IOT多场景概念落地&#xff0c;带火了WPF招聘&#xff0c;像阿里影视、百度地图、小米小鹏特斯拉都在高薪抢WPF人才了。机智的.NET开发者去关注学习WPF的时候却发现&#xff0c;市面上真的太缺WPF优秀的教程了&#xff0c;还好这里有最权威最详尽的微软官方pdf教程&#…

ln -s 的一个坑

为什么80%的码农都做不了架构师&#xff1f;>>> 事情是这样的&#xff0c;今天在ssh到iphone上将一个应用内目录软链接配置到用户目录下时&#xff0c;执行了如下命令&#xff1a; cd /var/mobile/Applications/9E13D9B8-63E0-49A5-82CE-6DB914495EC1/Documentsmkd…

python 空指针_Python&CType空指针错误

我正在从Python访问C共享库。 C共享库管理信号分析器&#xff0c;并且在没有源代码的情况下分发。Python&#xff06;CType空指针错误 其中一个功能需要一个结构被传递到函数调用&#xff0c;我不知道我正在使用ctypes正确地做它。 在头文件中的结构定义是&#xff1a; typedef…

unity重定向_unity3D游戏开发之动画混合与动画重定向

Unity3D游戏开发之动画混合与动画重定向动画混合状态机之中的状态不仅可以是单个剪辑&#xff0c;也可以是一个混合树。构建和编辑复杂的状态机和混合树&#xff0c;以便完全控制的角色如何运动。Unity编辑器提供强大的工具&#xff0c;用于分割、创建循环和从导入的动画文件中…

python中dict和lambda结合的小例子

python的dict用起来很方便&#xff0c;可以自定义key值&#xff0c;并通过下标访问&#xff0c;示例如下&#xff1a; >>> d {key1:value1,... key2:value2,... key3:value3}>>> print d[key2]value2>>>lambda表达式也是很实用的东东&#xff0c;示…

c语言50行左右程序,谁有50行和300行左右又简单的程序,急需

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼/*拼图(数字型)通过1&#xff0c;2&#xff0c;3&#xff0c;4控制空白位置移动&#xff0c;使1--8顺序排列*//*有很多可改进之处&#xff0c;你自己再改改吧*/#include#include#includevoid screen(short *);/*屏幕显示*/int judg…

知乎高赞:这个开挂神器简直了!

全世界只有3.14 % 的人关注了爆炸吧知识对于工作学习中常要用到PPT的人来说&#xff0c;每当谈起PPT&#xff0c;是否都会出现以下印象&#xff1a;[买模板]→[改PPT]→[粘贴复制]→[应付领导][操作繁琐]→[体力劳动]→[熬夜]→[加班]从什么时候开始&#xff0c;PPT从一个 表达…

jQuery常用方法一览

Attribute&#xff1a;$(”p”).addClass(css中定义的样式类型); 给某个元素添加样式$(”img”).attr({src:”test.jpg”,alt:”test Image”}); 给某个元素添加属性/值&#xff0c;参数是map$(”img”).attr(”src”,”test.jpg”); 给某个元素添加属性/值$(”img”).attr(”t…

Aspnetpage ie10下 __dopost方法未找到 不能翻页的问题

1.问题分析&#xff1a; 没有__dopost 的原因是因为没有 ie10下 页面里 没有这个 方法&#xff0c;和 2个 input 标签&#xff0c;ie10 没有解析出来&#xff0c;所以就不能翻页了。 2.解决办法&#xff1a;&#xff08;缺什么补什么&#xff0c;将这个 方法 和 input 标签手动…

性能再提升70%?大咖前瞻带你揭开.NET6的神秘面纱!

本月初微软官宣 .NET6 的RC1即将在11月正式发布&#xff0c;这意味着 .NET6 正式版跟我们见面的时间又近了一步。在之前的 .NET6 预览版本中&#xff0c;微软加入了大量新功能特性&#xff0c;而在最终版本中将不再额外加入新的内容&#xff0c;只对现在的内容进行进一步性能优…

python删除列表中的重复值_如何从 Python 列表中删除重复项

例子解释 创建一个以 List 作为参数的函数。 创建函数 def my_function(x): return list(dict.fromkeys(x)) mylist my_function(["a", "b", "a", "c", "c"]) print(mylist) 使用此 List 项作为键创建字典。 创建字典 def …

confluencejira集成_Jira Service Desk使用教程之如何将Jira Cloud与Confluence集成?

什么是汇合&#xff1f;Confluence是一个内容创建和协作平台&#xff0c;它将团队与他们需要更快地完成工作的内容&#xff0c;知识和同事联系起来。Confluence空间非常适合使用Confluence页面创建和组织与Jira项目相关的丰富内容-会议记录&#xff0c;项目计划&#xff0c;需求…

学生成绩……

Description 有N个学生&#xff0c;每个学生的数据包括学号、姓名、3门课的成绩&#xff0c;从键盘输入N个学生的数据&#xff0c;要求打印出3门课的总平均成绩(取整数)&#xff0c;以及总分最高的学生的信息&#xff08;包括学号、姓名、3门课成绩&#xff0c;如果有多个最高分…

JMS : Java Message Service (Java消息服务)之一 [转]

为什么80%的码农都做不了架构师&#xff1f;>>> 1 引言1.1 编写目的本文作为B2bi项目中开源产品JORAM的使用指导文档&#xff0c;旨在帮助项目组人员方便明了的进行JMS模块的详细设计和开发工作。本文档主要包含建设银行EAI平台B2Bi子系统中使用的开源JMS产品??J…

在床上玩手机,千万不能把手机放下!

1 当你在床上玩手机时▼2 据说兔子都是大长腿▼3 真是凭实力单的身▼后续▼4 这不是怕你不信嘛▼5 不看监控真不知道他咋上去的▼6 听说&#xff0c;他们已经没有暑假了▼7 感觉有被冒犯到▼你点的每个赞&#xff0c;我都认真当成了喜欢

python浪漫代码_五行Python代码实现批量抠图

你是否曾经想将某张照片中的人物抠出来&#xff0c;然后拼接到其他图片上去&#xff0c;从而可以即使你在天涯海角&#xff0c;我也可以到此一游&#xff1f;专业点的人使用 PhotoShop 的“魔棒”工具可以抠图&#xff0c;非专业人士可以使用各种美图 APP 来实现&#xff0c;但…