Javascript 如何有效地返回视口中的所有元素ID?

Javascript 如何有效地返回视口中的所有元素ID?,javascript,html,Javascript,Html,我不确定如何获取视图中的所有元素ID,而不构建所有元素ID的数组并单独检查这些ID是否可见 有没有更有效的方法来实现这一点(理想情况下具有+80%的浏览器兼容性) 我想建立一个简单的内容脚本停留时间。 我还想用它来暂停看不见的视频(比如编码为MP4的“GIF”)。我认为现代浏览器已经做到了这一点,但还不能完全确定 我还没有任何代码,因为我不知道从哪里开始 我打算派观察员,并使用。但这将是非常脆弱的,没有我想要的那么优雅,因为我需要在动态加载网站的滚动页面上触发它。为此,您可能需要使用(几乎通用的

我不确定如何获取视图中的所有元素ID,而不构建所有元素ID的数组并单独检查这些ID是否可见

有没有更有效的方法来实现这一点(理想情况下具有+80%的浏览器兼容性)

我想建立一个简单的内容脚本停留时间。 我还想用它来暂停看不见的视频(比如编码为MP4的“GIF”)。我认为现代浏览器已经做到了这一点,但还不能完全确定

我还没有任何代码,因为我不知道从哪里开始


我打算派观察员,并使用。但这将是非常脆弱的,没有我想要的那么优雅,因为我需要在动态加载网站的滚动页面上触发它。

为此,您可能需要使用(几乎通用的支持)和(非ie支持)的组合。可以使用querySelectorAll获取视口中ID为的所有元素的列表:

const elemsWithIds=document.queryselectoral(“*[id]”);
和IntersectionObserver以查看什么东西何时进入/离开视口:

const observer=新的IntersectionObserver(elems=>{
//在此处运行代码以检测元素集合何时进入/离开
//视口。这将在调用“observer.observe”时触发,
//因此,您可以获得视图中元素的初始计数。
});
elemsWithIds.forEach(elem=>observer.observe(elem));
在这里,我使用两个API记录哪些元素正在进入视图,并将视图留给控制台:

//构造一些要观察的元素
for(设i=0;i<200;i++){
常量elem=document.createElement(“li”);
elem.setAttribute(“id”,item-${i}`);
elem.innerHTML=`I'm元素${I}`;
document.getElementById(“myList”).appendChild(elem);
}
//创建我们的观察者
const observer=新的IntersectionObserver(条目=>{
log(“视图中的项目已更改:”)
entries.forEach({target,isIntersecting})=>{
log(`I'm${isIntersecting?'in view':'out view'}:${target.getAttribute(“id”)}`,target);
});
});
//使用ID观察所有元素
const elemsWithIds=document.queryselectoral(“*[id]”);
elemsWithIds.forEach(elem=>observer.observe(elem))

      假设这是您的HTML代码,带id的DIVs:

      <div id="id1"></div>
      <div id="id2"></div>
      <div id="id3"></div>
      

      这是一种向后的方法,但您可以提前存储内容块的偏移量(对于进入页面或调整窗口大小的新内容,您需要对此进行更新),然后在滚动时过滤该数组,而不是每次重新查询dom并重新计算偏移量

      这需要改进,因为它在几分钟内就完成了,但希望它能给出该方法的总体思路

      const contentBlocks=[]/{elem,offset}
      //对于无限滚动,为页面中添加的每个新元素触发此命令
      函数storeElem(elem){
      contentBlocks.push({
      埃伦,
      偏移量:elem.getBoundingClientRect().top+window.scrollY
      })
      }
      //应该在window.load语句中
      设i=0
      Array.prototype.slice.call(document.queryselectoral('p'),0).forEach(elem=>{
      ++我
      elem.id=“id”+i
      storeElem(elem)
      })
      window.addEventListener('scroll',e=>{
      const min=window.scrollY,max=window.scrollY+window.innerHeight
      常量visibleElements=contentBlocks.filter(t=>{
      返回t.offset>min&t.offsett.elem.id))
      })
      span{display:block;}
      
      内容!
      内容!
      内容!
      内容!
      内容!
      内容!
      内容!
      内容!
      内容!
      内容!
      

      内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容!

      内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容!

      内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容!

      内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容!

      内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容!

      内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容!

      内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容!

      内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容!

      内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容!

      内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容!

      内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容!

      内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容! 内容!

      能否包含显示您目前拥有的内容的代码?除此之外,关于您正试图执行的操作的一些信息将是有益的--我想不出一个有效的理由,您希望返回视口中的所有元素,而不是特定的元素。为什么要一次操作每一个可见元素,而不是那些不可见的元素?首先需要定义“视图中”的含义。元素可以是
      可见性:隐藏的且仍在视口中。它可能溢出到祖先的外部,因此被剪裁并仍在视口中。它可能被其顶部绝对定位的元素遮挡,并且仍然在视口中。如果您的问题是哪些元素在视口中实际可见,那么除了检查页面上每个元素的rect之外,没有有效的方法来做到这一点,确保它和它的祖先具有明显的样式且没有溢出,并且没有任何元素位于其上。是的,我也在想这个问题,但对于无限滚动的网站,我认为这意味着我必须触发
      
      var ele = document.querySelectorAll('[id]');
      ele.forEach(element => {
        console.log(element.id)
      });