标签: intersection-observer

如何将动态生成的元素绑定到 Intersection Observer?

这是我正在使用的代码:

var ob = new IntersectionObserver(entries => {
    for(var entry of entries){
        console.log('works');
    }
});

document.querySelectorAll('dynamicElement').forEach(elem => ob.observe(elem));
Run Code Online (Sandbox Code Playgroud)

这适用于页面上的元素,但不适用于稍后动态创建的元素。如何绑定稍后插入页面的元素?

我知道使用 jquery 可以绑定它$(document).on('event', 'element', 'func');,但是我如何使用观察者来绑定它?

javascript intersection-observer

6
推荐指数
1
解决办法
963
查看次数

如何使用 Intersection Observer 为不同的目标调用不同的函数?

我正在网站上使用 Intersection Observer API。对于使用它的每个实例,我都使用相同的配置(主视口)。我的问题是,当回调被触发时,我需要发生不同的事情。对于某些人来说,我想延迟加载图像。对于某些人来说,我想初始化轮播等。

有没有办法为所有这些不同的应用程序使用相同的观察者,或者我是否必须为每个唯一的回调使用不同的观察者?

html javascript dom intersection-observer

6
推荐指数
1
解决办法
3755
查看次数

IntersectionObserver是否支持水平滚动观察?

我制作了几个垂直滚动 IntersectionObserver 模块,但我对水平滚动感兴趣(根将是 div,观察目标将是 img)。我想观察当 img 放大但 div 保持视口宽度时的变化。我什至不确定移动 Safari 是否会将缩放后的图片报告为宽度发生变化,这是一个实验。回到问题上来,我还没有找到任何信息。回复:观察水平交叉点,所以我不确定是否支持?

javascript intersection-observer

6
推荐指数
1
解决办法
6440
查看次数

如何使用 IntersectionObserver 使 React 组件在滚动时淡入淡出,但只有一次?

当用户滚动时,我试图在 React 中为组件提供淡入效果,但我希望淡入效果仅在元素第一次移动到视口时发生。

目前,每次元素移动到视口时,我使用的代码都会导致淡入,因此它们不断地淡入淡出。

这是我的淡入组件:

import React, {useState, useRef, useEffect} from 'react';
import './styles/FadeInSection.css';

export default function FadeInSection(props) {
  const [isVisible, setVisible] = useState(true);

  const domRef = React.useRef();

  useEffect(() => {
    const observer = new IntersectionObserver(entries => {
      entries.forEach(entry => setVisible(entry.isIntersecting));
    });

    observer.observe(domRef.current);

    return () => observer.unobserve(domRef.current);
  }, []);

  return (
    <div ref={ domRef } className={ `fade-in-section ${ isVisible ? 'is-visible' : '' }` }>
      { props.children }
    </div>
  )
}
Run Code Online (Sandbox Code Playgroud)

这些是我正在使用的样式:

.fade-in-section {
  opacity: 0;
  transform: translateY(20vh);
  isibility: hidden; …
Run Code Online (Sandbox Code Playgroud)

javascript scroll fadein reactjs intersection-observer

6
推荐指数
1
解决办法
7287
查看次数

如果完全在视图中(大于视口),intersectionObserver 的比率为 1

我有一个页面分为多个部分。现在,在滚动时,我尝试使用导航项下边框的宽度来显示进度(视图中有多少部分)。在下面您将找到我如何实现它的示例。

现在,如您所见,如果某个部分高于视口,则 intersectionRatio 将永远不会达到 1(这反过来也不会绘制全宽边框)。我可以使用任何选项或替代方案来真正实现全宽度吗?

(function() {
    var sections = [],
        links = {},
        thresholdSet = [[]],
        observerOptions = {
            root: null,
            rootMargin: "0px",
            threshold: _buildThresholdList()
        };

    function _init() {
        if (!'IntersectionObserver' in window) {
            return;
        }

        sections = document.getElementsByClassName('section');

        for(var i = 0; i < sections.length; i++) {
            var observer = new IntersectionObserver(_intersectionCallback, observerOptions),
                section = sections[i],
                link = document.getElementById('js-' + section.id);

            links[section.id] = {
                node: link,
                initialWidth: link.offsetWidth
            };

            observer.observe(section);
        }
    }

    function _buildThresholdList() {
        for(var i = …
Run Code Online (Sandbox Code Playgroud)

javascript intersection-observer

6
推荐指数
1
解决办法
3376
查看次数

如何使 IntersectionObserver 与变换翻译动画一起使用?

我想为具有以下属性的元素创建动画:

  • 当元素进入视口时它会对其进行动画处理
  • 如果元素离开视口然后再次进入它应该再次动画
  • 根据滚动方向/相交侧(从顶部或底部),动画应该不同

为此,我使用了一个IntersectionObserver并且我接近了预期的结果。
我面临的唯一问题是,当我在动画期间沿滚动方向(在本例中)平移元素时transform: translateY。这将导致IntersectionObserver触发多次甚至无限次。

在此输入图像描述

function isIntersectingFromTop(entry){
  return entry.boundingClientRect.bottom != entry.intersectionRect.bottom;
} 

function isIntersectingFromBottom(entry){
  return entry.boundingClientRect.top != entry.intersectionRect.top;
}

var count = 0;

function incrementCounter(entry){
  document.querySelector(".counter").textContent += "intersectionRation (" + count + "): " + entry.intersectionRatio + "\n";
  count++;
}

let observer = new IntersectionObserver(
function (entries, observer) { 
  entries.forEach(function(entry){
    incrementCounter(entry)
    if (entry.isIntersecting) {
       if(isIntersectingFromTop(entry)){
         entry.target.classList.add("animated--up-in");
       } else if(isIntersectingFromBottom(entry)) {
         entry.target.classList.add("animated--down-in")
       }
    } else { 
      /** element is …
Run Code Online (Sandbox Code Playgroud)

html javascript css intersection-observer

6
推荐指数
1
解决办法
2765
查看次数

玩笑和打字稿中交叉观察者的模拟

如果我们将 jest 与 typescript 一起使用,其中使用了相交观察器,则相交观察器的模拟将变得困难。到目前为止我处于:


beforeEach(() => {
  // IntersectionObserver isn't available in test environment
  const mockIntersectionObserver = class {
    observe() {
      console.log(this);
    }

    unobserve() {
      console.log(this);
    }

    disconnect() {
      console.log(this);
    }

    root = null

    rootMargin = '0'

    thresholds=[1]

    takeRecords=() => ([{
      isIntersecting: true,
      boundingClientRect: true,
      intersectionRatio: true,
      intersectionRect: true,
      rootBounds: true,
      target: true,
       time: true,
    }])
  };
  window.IntersectionObserver = mockIntersectionObserver;
});
Run Code Online (Sandbox Code Playgroud)

但这仍然会引发错误,例如:

Type 'typeof mockIntersectionObserver' is not assignable to type '{ new (callback: IntersectionObserverCallback, options?: IntersectionObserverInit | undefined): IntersectionObserver; …
Run Code Online (Sandbox Code Playgroud)

mocking typescript jestjs intersection-observer react-testing-library

6
推荐指数
2
解决办法
9887
查看次数

使用 Intersection Observer 检查元素在浏览器视口中是否完全可见

页面加载后,我\xe2\x80\x99d 喜欢使用 Intersection Observer API 来观察元素 (addonCard),以了解该元素是否完全可见。如果该元素不可见或部分可见,我希望该元素滚动到完全可见。如果 it\xe2\x80\x99s 已经完全可见,我希望该元素停止被观察。根据我的理解,您可以通过将阈值属性设置为 1 来检查完全可见性。但是,下面的我的实现不起作用(无论元素是否完全可见,它都会滚动):

\n
let addonCard = this.querySelector(`[addon-id="${param}"]`);\nlet observer = new IntersectionObserver(\n  (entries, observer) => {\n    entries.forEach(entry => {\n      if (entry.intersectionRatio != 1) {\n        let stickyHeaderHeight = document.querySelector(\n          "#page-header > .sticky-container"\n        ).offsetHeight;\n        let topOfTarget = entry.target.offsetTop - stickyHeaderHeight;\n        window.scrollTo({\n          top: topOfTarget,\n          behavior: "smooth"\n        });\n      } else {\n        observer.unobserve(entry.target);\n      }\n    });\n  }, {\n    threshold: 1,\n  }\n);\nobserver.observe(addonCard);\n
Run Code Online (Sandbox Code Playgroud)\n

有人可以解释为什么这个实现不起作用以及我如何让它起作用吗?为什么entry.intersectionRatio从0开始永远不会改变?

\n

预期行为:如果不完全可见,addonCard 应滚动到完全可见。如果它已经完全可见,则不应进行滚动。

\n

实际行为:无论 addonCard 是否完全可见,都会发生滚动。

\n

javascript intersection-observer js-scrollto

6
推荐指数
0
解决办法
1793
查看次数

来自 Jest 中 Intersection Observer 的模拟“isIntersecting”

我有一个使用相交观察器的组件,并且想开玩笑地测试元素相交时的效果。我已经成功地模拟了交叉口观察者,就像这个答案一样:/sf/answers/4105615461/

现在我想在特定元素上“假回调” isIntersecting 触发器。可以在测试中模拟这个吗?

 const observe = jest.fn();
 const disconnect = jest.fn();
 setupIntersectionObserverMock({ observe: observe, disconnect: disconnect });
 const page = await newSpecPage({
   components: [TestComponent],
   html: `<div></div>`, // This is the element I want to trigger an "isIntersecting" on 
 });

export const setupIntersectionObserverMock = ({
  root = null,
  rootMargin = '',
  thresholds = [],
  disconnect = () => null,
  observe = () => null,
  takeRecords = () => null,
  unobserve = () => null,
} = {}): void => …
Run Code Online (Sandbox Code Playgroud)

jestjs intersection-observer

5
推荐指数
1
解决办法
2338
查看次数

&lt;img&gt; - 加载='lazy' 与 Intersection Observer?

我正在构建一个 React 应用程序,它的图像非常重,全部来自 API 调用。我已经完成了loading='lazy'所有这些,但这让我想知道是否可以做更多的事情?我知道您可以使用交叉观察器获得类似的结果,并且仅在视图中渲染它们。

我的问题是更好/实施交叉观察员是否有任何进一步的好处,还是会浪费时间,因为loading='lazy'已经足够了?

谢谢!

javascript image reactjs intersection-observer

5
推荐指数
1
解决办法
885
查看次数