通过MutationObserver监听DOM元素,做一个位置随指定元素位置变化而变化的气泡 | ResizeObserver监听元素大小
一个 通过 元素 指定 大小 位置 监听 变化
2023-09-11 14:19:39 时间
-
最近需要把时间轴修改成自己想要的样子,需要在时间轴的当前时间条上设置一个气泡,但是没有这个api,于是想到一个办法,通过监听 时间条dom元素,获取时间条的位置,然后创建一个元素当做气泡,这个气泡的位置会随着时间条的位置变化而变化;
1、需要用到MutationObserver 来监听时间条dom元素,
2、用DOM.getBoundingClientRect()方法监听dom相对于窗口的位置;
3、根据时间条的位置,给创建的气泡元素设置位置,从而达到给时间条加气泡的效果;
4、为了简化一些,我用了一个div当做时间条,设置一个定时器让它持续移动。可以模拟出来拖动时间条的场景。
上代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>observer</title> <style> .wrap{ width:400px; height:400px; position: relative; margin-left:200px; } .box{ width: 300px; height:300px; position: absolute; top:0; left:0; background:cadetblue; clip-path: polygon(15px 0, calc(100% - 15px) 0, 100% 15px, 100% calc(100% - 15px), calc(100% - 15px) 100%, 15px 100%, 0 calc(100% - 15px), 0 15px) } .pop{ position: fixed; border:1px solid black; border-radius:4px; padding: 4px; box-shadow: 0px 0px 4px 2px black inset; user-select: none; } </style> </head> <body> <div class="wrap"> <div class="box"></div> </div> <script> let box = document.querySelector(".box"); let add = 1; setInterval(() => { let left = parseInt(getComputedStyle(box).left); console.log(left); if(left > 300 ){ add = -1; } if (left < 0){ add = 1; } box.style.left = `${left + add}px` }, 1000); // 观察者的选项(要观察哪些突变) var config = { attributes: true, childList: false, subtree: false };// 只监听属性发生变化 // 当观察到突变时执行的回调函数 var callback = function(mutationsList) { console.log(mutationsList, 'mutationsList'); mutationsList.forEach(function(item,index){ if (item.type == 'childList') { console.log('有节点发生改变'); } else if (item.type == 'attributes') { let targetleft = item.target.getBoundingClientRect().left; console.log(targetleft,'targetleft'); let date = new Date(); changePop(item.target, ` <div>${date.getYear()}年${date.getMonth() + 1}月${date.getDay()}</div> <span>${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}</span> `) } else if (item.type == 'subtree') { console.log('subtree有变化'); } }); }; // 创建一个链接到回调函数的观察者实例 var observer = new MutationObserver(callback); // 开始观察已配置突变的目标节点 observer.observe(box, config); // 停止观察 //observer.disconnect(); function changePop(parent,innerHTML){ let pop = null; if(!document.querySelector('.pop')){ pop = document.createElement('div'); pop.classList.add('pop') document.body.appendChild(pop); } else { pop = document.querySelector('.pop'); } let position = parent.getBoundingClientRect(); pop.style.left = `${position.left}px`; pop.style.top = `${position.bottom}px`; pop.innerHTML = innerHTML; } </script> </body> </html>
效果:气泡位置会跟着时间条的位置变化而变化
下面简单说一下ResizeObserver API的使用,这个方法是监听元素的大小改变,不用通过window.resize来监听窗口改变来达到目的,有些时候只监听window.resize也是达不到目的的,因为我们可能用js来改变某一个元素的宽高,所以用ResizeObserver方法来监听会更加方便,不过这个API目前是实验阶段,在chrome浏览器已经支持
文档地址:https://developer.mozilla.org/zh-CN/docs/Web/API/ResizeObserver
<textarea id="main"></textarea> <script> // javascript let mainEl = document.querySelector('#main') const resizeObserver = new ResizeObserver(entries => { console.log(entries, 'entries'); for (let entry of entries) { console.log(entry.contentRect, 'contentRect'); entry.target.style.borderRadius = Math.max(0, 250 - entry.contentRect.width) + 'px'; } }); resizeObserver.observe(mainEl); // 取消某个元素监听 //resizeObserver.unobserve(mainEl) // 取消全部元素监听 //resizeObserver.disconnect()
拖动富文本框,监听到实时的大小。
-
相关文章
- hdu2066一个人的旅行(disjkstra)
- FreeRTOS 时间片,外部中断,任务优先级的一个疑问
- 将活动窗口从一个屏幕移动到另一个屏幕
- wireshark 抓包整理———— 从一个小案例开始 [一]
- 用Python输出一个杨辉三角的例子
- 如何通过一个SAPGUI屏幕反查这个屏幕对应的事务码
- [1] JSP里的一个最简单的过滤器(filter)的例子
- SAP云平台CloudFoundry上部署了一个应用的技术明细
- 如何通过 Impex 在 SAP Commerce Cloud 创建一个新的 Component
- 一个让开发人员仅通过声明式代码的方式实现智能数据结构的Java框架
- Android 儿子Activity在启动过程中的流程组件 && 儿子Activity在一个新的进程组件启动过程
- 通过调用约定解决一个常见问题
- 【SQL开发实战技巧】系列(二十七):数仓报表场景☞通过对移动范围进行聚集来详解分析函数开窗原理以及如何一个SQL打印九九乘法表
- PySpark 的背后原理--在Driver端,通过Py4j实现在Python中调用Java的方法.pyspark.executor 端一个Executor上同时运行多少个Task,就会有多少个对应的pyspark.worker进程。
- 薅羊毛——促销优惠,所有优惠都被一个“人“独占!!!羊毛党却利用规则漏洞,通过黑产手段,以低成本的方式,模拟出成千上万虚拟用户领取活动福利,积少成多
- 下面的那一个不属于MVC模式中的对象?
- Log4J是Apache组织的开源一个开源项目,通过Log4J,可以指定日志信息输出的目的地,如console、file等。Log4J采用日志级别机制,请按照输出级别由低到高的顺序写出日志输出级别。
- 用字符数组存放一个字符串
- 【前端】一个好看的前端页面