JS:获取元素的可见区域坐标

2023-12-26

我需要一个函数,可以计算当前在屏幕上可见的元素的可见区域,而无需隐藏部分overflow: scroll, position: absolute etc.

也就是这个函数的结果getVisiblePart(el)Visible Rect is: {x: 10, y: 20, height: 50, width: 700}

问题背景:需要这样的函数是由于 W3C 规范中与 webdriver 一起使用的一个特性:https://w3c.github.io/webdriver/webdriver-spec.html#element-interactability https://w3c.github.io/webdriver/webdriver-spec.html#element-interactability

元素的视图内中心点是视口内第一个 DOM 客户端矩形区域的中心点。

用于 e2e 测试的 selenoid/selenide 等框架使用 w3c 原理来计算可见元素的中心将光标移动到它 https://selenide.org/2019/12/12/advent-calendar-actions/,同时允许您指定偏移量。主要问题是找出元素此刻可见区域的实际大小,以便计算正确的偏移量,例如计算左上边框。

对于硒化物/硒化物,该问题的解决方案是:

Selenide.actions().moveToElement(el, getVisiblePart(el).width / -2, getVisiblePart(el).height / -2)

我读过很多类似的主题,例如:

  • 如何判断 DOM 元素在当前视口中是否可见? https://stackoverflow.com/q/123999/2051938(它只回答该元素是否已被看到的问题)
  • 如何检查元素滚动后是否可见? https://stackoverflow.com/q/487073/2051938 (same)
  • 是否可以通过编程方式确定是否使用 W3C 操作命令? https://stackoverflow.com/q/51974620/2051938(关闭但没有有效的答案)

所有答案要么给出元素是否可见的布尔值,要么没有考虑到元素可能部分隐藏overflow: scroll

带卷轴的真实示例(我需要找到可见的blue任意滚动位置的矩形位置):

.a {
  height: 250px;
  overflow: scroll;
  padding-top: 100px;
  background: yellow;
}
.b {
  height: 500px;
  overflow: scroll;
}
.c {
  height: 1000px;
  background: blue;
}
#target {
  border: 2px dashed red;
  position: absolute;
  pointer-events: none;
  transform: translate(-1px,-1px); /*because of border*/
}
<div class="a">
  <div class="b">
    <div class="c" />
  </div>
</div>
<div id="target" />

在回答这个问题时,我已经部分解决了这个问题,达到了我需要的结果路口观察器 API https://developer.mozilla.org/en/docs/Web/API/Intersection_Observer_API,但我不认为这个解决方案很好,至少因为它与函数调用时间不同步以及跨浏览器兼容性问题。


我的解决方法基于路口观察器 API https://developer.mozilla.org/ru/docs/Web/API/Intersection_Observer_API.

我不认为这个解决方案很好,至少因为它与调用函数时不同步以及在跨浏览器兼容性问题上。

这个例子完美地展示了我想要得到的最终版本。

var options = {
    // root: document.querySelector('#scrollArea'),
    // rootMargin: '0px',
    threshold: 1
}
var callback = function(entries, observer) {
    const r = entries[0].intersectionRect;
    document.getElementById('target').setAttribute('style', `top: ${r.top}px;left: ${r.left}px;height: ${r.height}px;width: ${r.width}px;`);
    observer.unobserve(c);
};

const c = document.querySelector('.c');
setInterval(() => {
  var observer = new IntersectionObserver(callback, options);
  observer.observe(c);
}, 200);
.a {
  height: 250px;
  overflow: scroll;
  padding-top: 100px;
  background: yellow;
}
.b {
  height: 500px;
  overflow: scroll;
}
.c {
  height: 1000px;
  background: blue;
}
#target {
  border: 2px dashed red;
  position: absolute;
  pointer-events: none;
  transform: translate(-1px,-1px); /*because of border*/
}
<div class="a">
  <div class="b">
    <div class="c" />
  </div>
</div>
<div id="target" />

说明:每200ms我们计算一次蓝色元素的可见面积并突出显示它。

我如何使用它的一个例子Selenide:

    val containerSelector = "div.testEl"
    val rect = executeAsyncJavaScript<String>(
        "var callback = arguments[arguments.length - 1];" +
                "var el = document.querySelector('" + containerSelector + "');" +
                "new IntersectionObserver(" +
                "    (entries, observer) => {" +
                "        observer.unobserve(el);" +
                "        var r = entries[0].intersectionRect;" +
                "        callback([r.x, r.y, r.height, r.width].map(v => Math.ceil(v)).join(','));" +
                "    }," +
                "    { threshold: 1 }" +
                ").observe(el);"
    )!!.split(',').toTypedArray();

    LEFT_TOP_X = rect[3].toInt() / -2 + 1 // +1 for Float tolerance
    LEFT_TOP_Y = rect[2].toInt() / -2 + 1 // +1 for Float tolerance

    // Move cursor to TOP LEFT
    Selenide.actions().moveToElement(el, LEFT_TOP_X, LEFT_TOP_Y)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JS:获取元素的可见区域坐标 的相关文章

  • 在 IE8 中使用 javascript __proto__

    你好 我在 javascript 中有这两个对象 var john firstname John lastname Smith var jane firstname Jane 这样做 jane proto john 我可以访问 Jane 的
  • 使用 WebDriver 单击新打开的选项卡中的链接

    有人可以在这种情况下帮助我吗 场景是 有一个网页 我仅在新选项卡中打开所有指定的链接 现在我尝试单击新打开的选项卡中的任何一个链接 在下面尝试过 但它仅单击主 第一个选项卡中的一个链接 而不是在新选项卡中 new Actions drive
  • 如何使用标准 JavaScript 在 CSS 转换结束后立即重新启动它?

    我构建了一种密码生成器 只要倒计时到期 它就会显示新密码 不幸的是 我只设法弄清楚如何运行我的代码一次 倒计时由一个简单的 CSS 过渡组成 我想保留它 因为它比我的其他尝试平滑得多 其中我尝试使用 JavaScript 重复更新宽度 va
  • 每n秒执行一次函数

    我制作了这个在 10 秒后点击链接的代码片段 function timeout window setTimeout function img left click 1000 setTimeout timeout 1000 timeout 我
  • 将 SVG 路径转换为绝对命令

    给定一个 SVG Path 元素 如何将所有路径命令转换为绝对坐标 例如 转换此路径
  • 有没有办法在 React 中自动播放音频而不使用 onClick 事件?

    我在尝试在 componentDidMount 中播放音频时收到此错误 未捕获 承诺中 DOMException play 失败 因为用户没有先与文档交互 componentDidMount document getElementById
  • Twitter Bootstrap - 下拉菜单 - 箭头键不适用于 Firefox 中的输入标签

    要求 我想在带有用户名和密码字段的下拉菜单中放置一个登录表单 我可以做到这一点 除了以下问题之外 一切正常 Issue 打字时我无法使用箭头键 上 下 firefox 当输入位于下拉代码之外时 这很有效 这适用于其他浏览器 例如 googl
  • jslint 配置 |传递全局变量

    我如何提醒 jshint 我有全局变量 即命名它们 我知道你可以做到这一点 但我不记得语法了 我在这里定义了一个全局的 function window glob1 local var 稍后像这样使用 不同的 IIFE function gl
  • 如何用 JavaScript 修复图像透视变形和旋转?

    我有一些用手机拍摄的图像 有没有可以拉直纸张照片并将其压平的 JavaScript 库 例如 我想创建一个矩形图像 该图像没有任何失真 换句话说我想知道如何用 JavaScript 修复透视变形和旋转 例如 我发现下面的示例图像来自this
  • 如何将本地文本文件上传到文本区域(网页内)

    我是一名新手程序员 需要一些帮助来弄清楚如何将本地文本文件上传到我正在构建的网站内的文本区域 我非常精通 HTML CSS 对 Javascript JQuery 有相当的了解 而且我刚刚学习 PHP 您能提供的任何帮助我将不胜感激 我有一
  • jquery 中可点击 div 中的按钮

    我有整个 div 您可以单击它来切换该 div 的主要部分 问题是我在该 div 中也有可点击的按钮 当我点击它时 它会执行它应该做的事情 但同时也会切换整个 div 我怎样才能禁用它 Use event stopPropagation 单
  • 使用 JavaScript 防止网页导航离开

    如何使用 JavaScript 防止网页导航离开 Using onunload允许您显示消息 但不会中断导航 因为为时已晚 然而 使用onbeforeunload将中断导航 window onbeforeunload function re
  • Angular 2 将字符串转换为 md5 哈希

    我找到了ts md5 https www npmjs com package ts md5包 但在示例中它有一个hashStr方法 但现在不行了 类型上不存在属性 hashStr Md5 使用该错误后 该错误会记录在我的控制台中 我怎样才能
  • 在 javascript 中实现固定位置会导致 Safari 滚动时出现抖动

    固定位置不适用于我的用例 因为它固定在浏览器窗口上 您可能会处于文本在屏幕右侧之外且无法到达的状态 无论如何 我尝试使用绝对定位 然后调整javascript中的 顶部 它在 Firefox 和 Chrome 中运行良好 但在 Safari
  • JavaScript 错误:MVC2 视图中的条件编译已关闭

    我试图在 MVC2 视图页面中单击时调用 JavaScript 函数 a href Select a JavaScript 函数 function SelectBenefit id code alert id alert code 这里 b
  • 为什么我的 D3 SVG 图上的轴不会更新?

    I have 简单的 D3 散点图 http www raxacoricofallapatorius com test scattertest html我在显示数据的几个不同属性之间切换 但是虽然我可以更改数据点 并按照我想要的方式进行转换
  • 什么时候可以使用Javascript,什么时候不可以?

    不使用太多 javascript jquery 是个好习惯吗 我们应该尽可能避免它 为了良好的可访问性 吗 什么时候可以使用 JavaScript 什么时候不能在网页设计和开发中使用 JavaScript 在什么场景 什么条件下 Updat
  • 在 Meteor 应用程序中实现 MongoDB 2.4 的全文搜索

    我正在考虑向 Meteor 应用程序添加全文搜索 我知道 MongoDB 现在支持此功能 但我对实现有一些疑问 启用文本搜索功能的最佳方法是什么 textSearchEnabled true 在 Meteor 应用程序中 有没有办法添加索引
  • ‘state’未定义 no-undef

    我使用教程来学习 React 但我很快就陷入困境 在教程中 他们使用以下代码 import React Component from react class Counter extends Component state count 0 r
  • 在 Firestore 文本字段中存储文本文件并删除换行符

    我正在尝试将 CSV 文件存储在 Cloud Firestore 内的文本字段中 然而 Firestore 正在删除所有换行符并将整个 CSV 文件存储为一行 这Firestore 数据类型文档 https firebase google

随机推荐