【问题标题】:How to get elements in order that are placed via translate3d如何按顺序获取通过 translate3d 放置的元素
【发布时间】:2022-01-16 15:03:56
【问题描述】:

我正在构建一个 Chrome 扩展程序,它与我的 Youtube 后端屏幕上可见的 Youtube cmets 交互。我希望扩展能够遍历 cmets 列表并像这样一一突出显示它们:

我通过以下方式在屏幕上获取 cmets:

return document.querySelectorAll(".ytcp-comment-thread .style-scope.ytcp-comments-section #comment")[currentIndex]

然后维护currentIndex 以了解我目前在哪个元素。

这适用于前几个 cmets,但随后会开始突出显示错误的注释。检查页面后,我注意到评论 divs 的顺序并不完全代表屏幕上 cmets 的顺序。相反,它们似乎是由一个名为 translate3d 的属性放置的:

如何才能准确地遍历屏幕上的所有这些 cmets?

编辑:以下是 Youtube 如何将页面的最后一个 cmets(延迟加载)放在 HTML 元素顶部的示例:

作为代码:

<div class="ytcp-comment-thread style-scope ytcp-comments-section" style="transform: translate3d(0px, 11596px, 0px);">

<div class="ytcp-comment-thread style-scope ytcp-comments-section" style="transform: translate3d(0px, 11800px, 0px);">

<div class="ytcp-comment-thread style-scope ytcp-comments-section" style="transform: translate3d(0px, 12004px, 0px);">

<div class="style-scope ytcp-comments-section" style="transform: translate3d(0px, 12208px, 0px);">

<div class="ytcp-comment-thread style-scope ytcp-comments-section" style="transform: translate3d(0px, 980px, 0px);">

<div class="ytcp-comment-thread style-scope ytcp-comments-section" style="transform: translate3d(0px, 1184px, 0px);">

【问题讨论】:

  • 您能否提供一个您收到的 HTML 的(简短)示例,比如只有六个 cmets,但其中一些“顺序错误” - 这可能有助于解决问题。
  • @AHaworth 我认为 HTML 太大,无法在此处粘贴,但我添加了显示问题的屏幕截图。
  • 你能粘贴说前 7 个吗 - 我可以从图像中看到它是什么,但不想输入它:)
  • @AHaworth 我添加了一些代码!

标签: javascript html css google-chrome-extension frontend


【解决方案1】:

使用给定的代码(这只是较长列表的一部分,因此布局中存在间隙),我们可以根据元素的 y 平移对元素进行排序。

排序后的数组具有 [i, y] 形式的条目,其中 i 是#items 的子项集合中的索引,y 是翻译的 px 值。

为了说明排序产生了 cmets 突出显示的顺序,setTimeout 函数依次突出显示它们。这不太可能是您想要做的 - 它只是一个简单的演示:

const items = document.querySelector('#items').children;
let arr = [];
for (let i = 0; i < items.length; i++) {
  arr.push([i, Number(items[i].style.transform.split('translate3d(0px, ')[1].split('px')[0])]);
}
let sortedArr = arr.sort(function(a, b) {
  return a[1] - b[1];
});
let next = 0;
setInterval(function() {
  if (next > 0) {
    items[sortedArr[next - 1][0]].classList.remove('hilite');
  }
  items[sortedArr[next][0]].classList.add('hilite');
  if (next < (arr.length - 1)) next++;
}, 5000);
.hilite {
  background-color: yellow;
}
<div id="items">
  <div class="ytcp-comment-thread style-scope ytcp-comments-section" style="transform: translate3d(0px, 11596px, 0px);">content 11596</div>

  <div class="ytcp-comment-thread style-scope ytcp-comments-section" style="transform: translate3d(0px, 11800px, 0px);">content 11800</div>

  <div class="ytcp-comment-thread style-scope ytcp-comments-section" style="transform: translate3d(0px, 12004px, 0px);">content 12004</div>

  <div class="style-scope ytcp-comments-section" style="transform: translate3d(0px, 12208px, 0px);">content 12208</div>

  <div class="ytcp-comment-thread style-scope ytcp-comments-section" style="transform: translate3d(0px, 980px, 0px);">content 980</div>

  <div class="ytcp-comment-thread style-scope ytcp-comments-section" style="transform: translate3d(0px, 1184px, 0px);">content 1184</div>
</div>

不要忘记向下滚动(相当不错的方式)以查看突出显示的情况。

【讨论】:

  • 感谢您的回答!我收到Cannot read properties of undefined (reading 'split')
  • 如果我从 i = 1 开始而不是循环的 0 似乎可以工作。我仍在尝试弄清楚如何使用返回值来获取正确的 HTML 元素。
  • 您是在运行上面的 sn-p 时看到该错误,还是在运行您自己的代码时看到该错误?
  • 我不敢说实话,因为代码预览的元素之间有很大的差距,而且窗口很小,所以我真的看不出发生了什么。但它似乎有效!
  • 不幸的是,它在几个 cmets 后仍然停止工作。我可能在 HMTL 结构中遗漏了一些奇怪的怪癖。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-29
  • 1970-01-01
  • 1970-01-01
  • 2010-12-18
  • 2011-04-18
  • 2015-10-09
  • 1970-01-01
相关资源
最近更新 更多