【问题标题】:How to detect current elements in viewport while user scrolls with optimal performance?如何在用户以最佳性能滚动时检测视口中的当前元素?
【发布时间】:2020-03-08 16:34:10
【问题描述】:

我拥有的是一个包含大约 30 张卡片的 div。我想要实现的是:每次用户滚动时,我都会在当前视口中检索卡片并将它们视为“已访问”。例如,在第一次滚动后,视口中的当前卡片是 id = 1,2,3,4 的卡片,我将在第一次滚动后将它们标记为已访问。如何以最佳性能实现这一目标?

<div id="search-results">
   <div class="search-card" id="card-1"></div>
   <div class="search-card" id="card-2"></div>
   <!-- 30 elements with class = "search-card" -->
</div>

我尝试按照建议使用 Intersection Observer API,但我认为我做错了什么?它没有观察到......它只在页面加载时触发。我应该添加滚动事件还是什么?

var options = {
    root: document.querySelector('#search-results'),
    rootMargin: '0px',
    threshold: 1.0
};

var callback = function(entries, observer) {
    entries.forEach(function(entry) {

        if (entry.isIntersecting) {
            console.log(entry.target)
        }
        else {
            console.log('not intersecting')
        }
    });
};

const observer = new IntersectionObserver(callback, options);

var targets = document.querySelectorAll('.search-card');

targets.forEach(function(target) {
    observer.observe(target)
});

【问题讨论】:

  • 谢谢你的建议,我试过了,但我觉得我做错了什么......你能检查一下编辑吗?

标签: javascript html css angularjs


【解决方案1】:

root 属性设置为null。这意味着文档的根 (&lt;html&gt;) 将用于检查该元素是否在根的视口中可见。由于您的网站可能会在根元素中滚动,它会检查观察到的元素是否相对于根元素可见,根元素会溢出屏幕之外。所以它会检查元素是否在溢出的范围内。

当使用没有溢出的搜索容器时,它将检查元素是否在 #search-results 容器的上下文中可见,它们总是如此,因为没有元素超出容器的约束.

还可以为threshold 属性使用带有数字(整数或浮点数)的数组。 0 表示被观察元素的单个像素必须在视野内,而1 表示必须 100% 的元素必须在视野内,才能触发回调函数。

看看下面的例子。

var options = {
    root: null,
    rootMargin: '0px',
    threshold: [0]
};

var callback = function(entries, observer) {
    entries.forEach(function(entry) {

        if (entry.isIntersecting) {
            entry.target.classList.add('is-seen');
            observer.unobserve(entry.target);
        }
    });
};

const observer = new IntersectionObserver(callback, options);

var targets = document.querySelectorAll('.search-card');

targets.forEach(function(target) {
    observer.observe(target)
});
#search-results {
  background: #f7f7f7;
  padding: 15px;
}

.search-card {
  display: block;
  height: 200px;
  width: 100%;
  background: #ffffff;
  border: 1px solid #d0d0d0;
  border-radius: 5px;
  margin-bottom: 15px;
  transition: background-color 150ms 500ms ease-in-out;
}

.search-card.is-seen {
  background: #d0d0d0;
}
<div id="search-results">
   <div class="search-card" id="card-1"></div>
   <div class="search-card" id="card-2"></div>
   <div class="search-card" id="card-3"></div>
   <div class="search-card" id="card-4"></div>
   <div class="search-card" id="card-5"></div>
   <div class="search-card" id="card-6"></div>
   <div class="search-card" id="card-7"></div>
   <div class="search-card" id="card-8"></div>
   <div class="search-card" id="card-9"></div>
   <div class="search-card" id="card-10"></div>
   <div class="search-card" id="card-11"></div>
   <div class="search-card" id="card-12"></div>
</div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-13
    • 2015-06-20
    • 1970-01-01
    • 2016-02-18
    • 2021-08-22
    • 1970-01-01
    • 2012-04-07
    • 1970-01-01
    相关资源
    最近更新 更多