惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Stack Overflow Blog
Stack Overflow Blog
J
Java Code Geeks
Last Week in AI
Last Week in AI
人人都是产品经理
人人都是产品经理
博客园 - 【当耐特】
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
C
Check Point Blog
月光博客
月光博客
腾讯CDC
Engineering at Meta
Engineering at Meta
博客园 - Franky
Vercel News
Vercel News
D
Docker
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
F
Fortinet All Blogs
Microsoft Security Blog
Microsoft Security Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
雷峰网
雷峰网
Google DeepMind News
Google DeepMind News
Martin Fowler
Martin Fowler
GbyAI
GbyAI
B
Blog
Hugging Face - Blog
Hugging Face - Blog
T
Tailwind CSS Blog

愆伏

vue feedback 指令开发 通过webpack对css压缩后所引起的重名问题 NPM 撤回已发布的版本 昆虫有趋光性吗 数组转成字符串(css 属性) 关于grid布局的一些思考 阿里云和腾讯云网站字体族对比 Vue组件抛事件和Function prop的差别 Vue 事件参数传递 Vue Data里面下划线命名无效并报错 使用sublime中的正则处理数据格式 通过nodejs创建目录与文件 macOS 下npm run dev 无法局域网访问 mac 下使用ssh访问非22端口的gitlab 世界是平的,在科学上网之后 使用sublime text3和Markdown来写博客 如果非要给一个标题,那就是2014年非工作总结 不专业呢,就别捣乱 对知乎大号怒撤事件的一点看法 拒绝SB思维 嘀嘀与快的的商业博弈 关于收藏夹功能的思考 你居然都不用微信 一个英语培训机构的外呼电话 智商是硬伤就无解了 扁鹊三兄弟 竖子不足与谋 美丽说、蘑菇街今天一定开了好几个小时的会 个人独立博客会死掉吗? iPad作画
如何用 javascript 获取布局中的文本尺寸和坐标
tortorse · 2022-11-21 · via 愆伏

今年早些时候碰到了一个需求:获取一个页面中所有的元素的坐标信息,除此之外还需要获取页面中的所有文本的坐标和尺寸。

前半部分的需求比较常规,可以通过遍历整个文档来获取所有的元素,再通过元素的 getBoundingClientRect() 方法即可取得。后半部分的文本的获取则有些困难,因为文本本身是通过: <tag>text<tag> 的方式存在的,而文本自身则不是一个 DOM 元素。

text-in-paragraph

假设我们有一个元素 p,其中放置了一段文本,如果通过 p 元素的 getBoundingClientRect() 方法则只能获取 p 元素的坐标和尺寸,并且这个尺寸还会受到 CSS 属性的影响,比如 widthheightpadding 等等。

至此,问题就分成了两个部分:

  1. 如何从元素中找到文本
  2. 如何获取文本的尺寸和坐标

突然灵光一闪,依稀记得元素中似乎有个 childNodes 属性,打印出来一看果然没错,文本确实就在 childNodes 里,体现为一个文本 node,并且文本类型是特殊的,表现为 nodeType3。这个思路有了之后,第一个问题基本解决。

既然已经得到了文本 node,那么是不是直接使用 getBoundingClientRect() 就可以得到文本的尺寸和坐标了呢?答案是否定的。查了一下 MDN 中关于 getBoundingClientRect() 的解释,发现只有 RangeElement 可以使用,但文本 node 既不是 Element 也不是 Range。别急,Range?那我为这个文本 node 创建一个 Range 可不可以?我按照这个思路继续尝试。

先创建一个 Range

1
const range = document.createRange()

然后让这个 Range 选中已经找到的文本 node

1
range.selectNode(node)

这个时候再通过 rangegetBoundingClientRect() 获取坐标和尺寸

1
range.getBoundingClientRect() 

不出所料,果然获取到了文本的坐标和尺寸。

测试的页面看起来是这样:

text-in-page

实际获取的所有文本结果:

measure-result

可以访问 DEMO 查看实际运行结果,查看页面源代码即可了解实现方法。