标签: intersection-observer

我如何知道IntersectionObserver滚动方向?

那么,当触发事件时,如何知道滚动方向?

在返回的对象中,我看到的最接近的可能性是与boundingClientRect保存最后滚动位置的类型进行交互,但我不知道处理boundingClientRect是否会最终导致性能问题.

是否可以使用交集事件来确定滚动方向(向上/向下)?

我添加了这个基本代码段,所以如果有人可以帮助我.
我会非常感激的.

这是片段:

var options = {
  rootMargin: '0px',
  threshold: 1.0
}

function callback(entries, observer) { 
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      console.log('entry', entry);
    }
  });
};

var elementToObserve = document.querySelector('#element');
var observer = new IntersectionObserver(callback, options);

observer.observe(elementToObserve);
Run Code Online (Sandbox Code Playgroud)
#element {
  margin: 1500px auto;
  width: 150px;
  height: 150px;
  background: #ccc;
  color: white;
  font-family: sans-serif;
  font-weight: 100;
  font-size: 25px;
  text-align: center;
  line-height: 150px;
}
Run Code Online (Sandbox Code Playgroud)
<div id="element">Observed</div>
Run Code Online (Sandbox Code Playgroud)

我想知道这一点,所以我可以在固定标题菜单上应用它来显示/隐藏它

html javascript css intersection-observer

26
推荐指数
3
解决办法
8795
查看次数

强制 IntersectionObserver 更新

有没有办法强制更新/运行IntersectionObserver实例?当视口发生变化时,回调将默认执行。但是我正在寻找一种在其他事件发生时执行它的方法,比如元素的变化。

一个例子:

初始化时一切正常。但是当你改变#red元素的位置时,什么也没有发生。

// elements
let green = document.querySelector('#green');
let red = document.querySelector('#red');

// observer callback
let callback = entries => {
  entries.forEach(entry => {
    let isInside = entry.intersectionRatio >= 1 ? "fully" : "NOT";
    console.log("#" + entry.target.id + " is " + isInside + " inside #container");
  });
};

// start observer
let options = {root: document.querySelector('#container')};
let observer = new IntersectionObserver(callback, options);
observer.observe(green);
observer.observe(red);

// button action
document.querySelector('button').addEventListener('click', () => {
  red.style.right = red.style.right …
Run Code Online (Sandbox Code Playgroud)

javascript intersection-observer

21
推荐指数
1
解决办法
1788
查看次数

当我快速滚动时,Intersection Observer 有时会失败

我对 Intersection Observer API 有一个小问题,它对我很有用,但是。

当我在网页上快速(非常快)滚动时,Intersection Observer API 有时无法检测到视口中元素的伪装。

当我缓慢/正常滚动时,它适用于所有元素

观察者选项:

RootMargin: 0px 0px -40px 0px,
threshold: 0.7,
root: null
Run Code Online (Sandbox Code Playgroud)

元素高度:介于100px和之间200px

有谁知道为什么?

javascript intersection-observer

15
推荐指数
1
解决办法
2619
查看次数

JS - 测试使用IntersectionObserver的代码

我已(书面相当差)一个JavaScript组件在我的应用程序来处理无限滚动分页,我试图重写它使用的IntersectionObserver,如所描述这里,但是我遇到在测试它的问题.

有没有办法在QUnit测试中驱动观察者的行为,即用我的测试中描述的一些条目触发观察者回调?

我提出的一个可能的解决方案是在组件的原型中公开回调函数,并在我的测试中直接调用它,如下所示:

InfiniteScroll.prototype.observerCallback = function(entries) {
    //handle the infinite scroll
}

InfiniteScroll.prototype.initObserver = function() {
    var io = new IntersectionObserver(this.observerCallback);
    io.observe(someElements);
}

//In my test
var component = new InfiniteScroll();
component.observerCallback(someEntries);
//Do some assertions about the state after the callback has been executed
Run Code Online (Sandbox Code Playgroud)

我真的不喜欢这种方法,因为它暴露了组件IntersectionObserver内部使用的事实,这是我认为客户端代码不应该看到的实现细节,所以有没有更好的方法来测试它?

奖金喜欢不使用jQuery的解决方案:)

javascript unit-testing qunit intersection-observer

12
推荐指数
4
解决办法
2809
查看次数

参考错误:找不到变量:IntersectionObserver

我正在尝试在 ios 13 上运行的 cordova 8.0.0 应用程序中使用 IntersectionObserver。当我通过 safari 检查我的应用程序时,我看到初始化错误:

ReferenceError: Can't find variable: IntersectionObserver

这表明 IntersectionObserver 不可用,我应该使用 polyfill。但!我读过很多文章声称 iOS safari 12+ 原生支持 IntersectionObserver。我有点假设,cordova 将运行本机可用的 WKWebView,所以它应该可以在没有 polyfill 的情况下工作,对吧?

我发现我在 safari 实验功能中启用了 IntersectionObserver,所以也许我也可以使用一个选项/标志来强制在我的应用程序中启用此功能?如果可能的话,我真的很想避免使用polyfill。

感谢任何建议

intersection-observer cordova-8.0.0 ios13

12
推荐指数
3
解决办法
1万
查看次数

IntersectionObserver 不拦截具有显示内容的元素

看起来 IntersectionObserver 从不考虑display: contents视口中的元素。

这种行为对于 来说是有道理的display: none,但我发现它对于 来说是违反直觉的display: contents

拥有一个干净的包装器的用例,仅在视口交集上获取和渲染其内容对我来说似乎是有效的。

例子

function callback(entries, observer) {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      document.getElementById('content').style.display = 'block';
      document.getElementById('loader').style.display = 'none';
    }
  });
};

const observer = new IntersectionObserver(callback);

const target = document.getElementById('wrapper');

observer.observe(target);
Run Code Online (Sandbox Code Playgroud)
#wrapper {
  display: contents;
}

#content {
  display: none;
}
Run Code Online (Sandbox Code Playgroud)
<div id="wrapper">
  <div id="loader">Loading...</div>
  <div id="content">Shown on viewport intersection</div>
</div>
Run Code Online (Sandbox Code Playgroud)

查看Mozilla 文档我可以看到:

这些元素本身不会产生特定的盒子

但我仍然希望IntersectionObserver能够检测到它。

所以猜测这是一个由两部分组成的问题:

  • 这确实是预期的行为还是不需要的副作用?
  • 如果这是预期的行为 - 正确的用例是什么display-contents …

html javascript css intersection-observer

12
推荐指数
0
解决办法
782
查看次数

如何观察DOM元素位置变化

我需要观察 DOM 元素的位置,因为我需要显示一个相对于它的弹出面板(但不在同一个容器中),并且面板应该跟随元素。我应该如何实现这样的逻辑?

这是一个片段,您可以在其中看到外部和嵌套弹出面板的打开,但它们不遵循水平滚动。我希望他们都遵循它并继续显示在相应的图标附近(它应该是一种适用于任何地方的通用方法)。您可能会忽略嵌套弹出窗口未与外部关闭在一起 - 这只是为了使代码片段更简单。我希望除了showPopup功能之外没有任何变化。本例中特别简化了标记;不要试图改变它——我需要它。

~function handlePopups() {
  function showPopup(src, popup, popupContainer) {
    var bounds = popupContainer.getBoundingClientRect()
    var bb = src.getBoundingClientRect()

    popup.style.left = bb.right - bounds.left - 1 + 'px'
    popup.style.top = bb.bottom - bounds.top - 1 + 'px'

    return () => {
      // fucntion to cleanup handlers when closed
    }
  }

  var opened = new Map()

  document.addEventListener('click', e => {
    if (e.target.tagName === 'I') {
      var wasActive = e.target.classList.contains('active')
      var popup = document.querySelector(`.popup[data-popup="${e.target.dataset.popup}"]`)

      var old = …
Run Code Online (Sandbox Code Playgroud)

javascript performance scroll requestanimationframe intersection-observer

11
推荐指数
1
解决办法
4041
查看次数

IntersectionObserver回调在页面加载时立即触发

我是IntersectionObserver API的新手,并且一直在尝试以下代码:

let target = document.querySelector('.lazy-load');

let options = {
    root: null,
    rootMargin: '0px',
    threshold: 0
}

let observer = new IntersectionObserver(callback, options);

observer.observe(target);

function callback() {
    console.log('observer triggered.');
}
Run Code Online (Sandbox Code Playgroud)

这似乎可以正常工作,并callback().lazy-load元素进入视口时调用,但是callback()在页面最初加载时也会触发一次,从而触发“ console.log('观察者被触发”)。

页面加载时是否有触发此回调的原因?还是我执行此方法有误?

编辑:将代码更改为以下内容仍会在页面加载时触发回调。

let target = document.querySelector('.lazy-load');

let options = {
    root: null,
    rootMargin: '0px',
    threshold: 0
}

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

        console.log('observer triggered.');

    });
};

let observer = new IntersectionObserver(callback, options);

observer.observe(target);
Run Code Online (Sandbox Code Playgroud)

javascript lazy-loading intersection-observer

10
推荐指数
1
解决办法
2181
查看次数

Intersection Observer API:观察视口的中心

我试图观察视口中心的交点,我尝试在 rootMargin 中传递负值

rootMargin: '-45% 10% -45%'
Run Code Online (Sandbox Code Playgroud)

但它似乎不能正常工作。

我的要求是当我的元素到达屏幕中心时观察交叉点。

javascript dom web intersection-observer

10
推荐指数
1
解决办法
845
查看次数

一个intersectionObserver观察多个元素或一个intersectionObserver每个元素

我们的页面中有一些 CustomElements,其中一些有一个 IntersectionObserver 相对于观察它们的视口。随着设计师似乎喜欢交叉动画,这个数字可能会增加。

这会导致性能问题吗?有一个观察所有元素的 IntersectionObserver 还是多个只观察一个元素的 IntersectionObserver 更好?

javascript performance intersection-observer

10
推荐指数
1
解决办法
1875
查看次数