标签: intersection-observer

IntersectionObserver iOS和Safari

我的目标是如果用户进一步滚动到视频元素,则将位置更改为视频元素。我使用的是Intersection Observer API,因为我需要处理AdForm Banner / iFrame中的页面滚动。

这是我的代码:

function createObserver() {
  var observer;
  var options = {
    root: null,
    rootMargin: "0px",
    threshold: buildThresholdList()
  }; 
  observer = new IntersectionObserver(handleIntersect, options); 
  observer.observe(boxElement);
}
Run Code Online (Sandbox Code Playgroud)

这是handleIntersect函数:

function handleIntersect(entries, observer) { 
  entries.forEach(function(entry) {
    if (entry.intersectionRatio > prevRatio) {
      console.log("VIDEO IN");
      p.style.position = "relative";
    } else if(entry.intersectionRatio === 0 && scrolled === 1 ) {
      console.log("VIDEO OUT");
      p.style.position = "fixed"; 
    }
  });
}
Run Code Online (Sandbox Code Playgroud)

这是我的代码笔:https ://codepen.io/alex18min/pen/gXXYJb

它可以在Chrome / Firefox / Edge和Android设备上完美运行,但通常不能在iOS和Safari上运行,似乎未检测到监听器。

有人能帮我吗?先感谢您。

html javascript scroll banner intersection-observer

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

删除元素时是否应断开IntersectionObserver的连接

在单页应用程序中,通常会删除和替换元素。在从DOM中删除的元素上,可能有一个IntersectionObserver(或任何其他种类)

对于事件,我从不打扰,因为它们是绑定在目标上并触发的,因此保留它们应该相当无害。对于IntersectionObserver,我有点担心在任何视图更改时都会检查所有实例。

考虑一下我的Lazy.ts的以下部分

setIntersectionObserver(config:LazyConfig)
{
  let intersectionObserver = new IntersectionObserver((entries:Array<IntersectionObserverEntry>) => {
    for (let entry of entries) {
      if (entry.isIntersecting) {
        this.lazyLoad(config);
        intersectionObserver.disconnect();
        mutationOberserver.disconnect();
      }
    }
  }, {
    threshold: 0,
    rootMargin: `${config.offset}px`,
  });
  intersectionObserver.observe(config.element);

  let mutationOberserver = new MutationObserver((entries:Array<MutationRecord>) => {
    if (
      entries[0].removedNodes &&
      document.body.contains(config.element) === false
    ) {
      intersectionObserver.disconnect();
      mutationOberserver.disconnect();
    }
  });

  mutationOberserver.observe(document.body, {
    childList: true,
    subtree: true
  });
}
Run Code Online (Sandbox Code Playgroud)

底部(mutationOberserver)是否无效?由于进行了许多检查,甚至可能损害性能document.body

通常,我只是假定垃圾收集会很好地完成其工作,但是脚本保留了对所有Attached元素的引用数组。而且该数组不会被清除(没有观察者也无法清除)

- 编辑 -

它没有得到“删除”(或至少不会在10秒内)https://jsfiddle.net/c1sgdcrd/所以,问题仍然有效羯羊,最好只保留在内存中或积极利用MutationObserver和断开。

javascript performance dom mutation-observers intersection-observer

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

如何在Vue cli 3中使用相交观察器polyfill?

如何使用:https//github.com/w3c/IntersectionObserver/tree/master/polyfill

我应该将其加载到webpack配置-vue.config.js中还是应该使用导入将其加载到.vue模板中?

vue.js intersection-observer

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

使用 querySelectorAll 的 Intersection Observer 会抛出 TypeError

我陷入了十字路口观察者问题。使用document.querySelectorAll('.entry')会抛出 TypeError:“未捕获 TypeError:无法在 'IntersectionObserver' 上执行 'observe':参数 1 不是 'Element' 类型。”

改变document.querySelectorAll('.entry');document.querySelector('.entry');解决问题并且有效。

我究竟做错了什么?

基本的 HTML 结构:

<html>
<body>
  <div id="content-container">
    <div class="content">
      <div class="entry">Some content here on each entry</div>
      <div class="entry"></div>
      <div class="entry"></div>
      <div class="entry"></div>
      <div class="entry"></div>
      <div class="entry"></div>
    </div>
</div>
</body
</html>
Run Code Online (Sandbox Code Playgroud)

JavaScript:

const blog = document.querySelectorAll('.entry');
const options = {
  root: null,
  rootMargin: '0px',
};

const observer = new IntersectionObserver(function(entries, observer) {
  entries.forEach((entry) => {
    if (!entry.isIntersecting) {
      return;
    } 

    else {
      console.log(entry); …
Run Code Online (Sandbox Code Playgroud)

html javascript intersection-observer

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

元素居中时的 IntersectionObserver

我想在元素完全居中时修复它的位置。目前,当它完全可见时,它正在被修复,因此会捕捉到中心。- 我可以以某种方式观察元素何时居中吗?

const box = document.querySelector(".box");

const obs = new IntersectionObserver(entries => {
  if (entries[0].isIntersecting) {
    box.style.position = "fixed";
    box.style.top = "50%";
    box.style.transform = "translateY(-50%)"
  }
}, {threshold: 1})

obs.observe(box);
Run Code Online (Sandbox Code Playgroud)
.v-detail__video {
  width: 100vw;
  height: 300vh;
  display: flex;
  padding-top: 70vh;
  justify-content: center;
}

.box {
  background-color: black;
  width: 50vw;
  height: 200px;
}
Run Code Online (Sandbox Code Playgroud)
<div class="v-detail__video">
  <div class="box"></div>          
</div>
Run Code Online (Sandbox Code Playgroud)

html javascript css intersection-observer

5
推荐指数
0
解决办法
395
查看次数

如何延迟路口观察器 API

情况

我在页面顶部有一个固定的导航栏。当您向下滚动页面的不同部分时,导航栏会动态更新(下划线和突出显示)。您还可以单击导航栏上的某个部分,它将向下滚动到该部分。

这是使用交集观察器 API 来检测它所在的部分并使用scrollIntoView 滚动到每个部分来完成的。

问题

假设您位于第 1 部分,单击最后一个部分 5,页面就会向下滚动到中间的所有其他部分。滚动速度很快,并且当滚动时,交叉点观察器会检测到所有部分,因此导航会更新。当每个导航项经过每个相应部分时,您最终会得到导航快速变化的效果。

目标

如果该部分仅在帧中持续一毫秒,如何延迟交叉口观察器触发菜单更改?快速滚动时,导航栏仅应在滚动停止在某个部分后更新。

代码设置

const sectionItemOptions = {
  threshold: 0.7,
};

const sectionItemObserver = new IntersectionObserver((entries, observer) => {
  entries.forEach((entry) => {

    if (entry.isIntersecting) {
      // select navigation link corresponding to section

    } else {
      // deselect navigation link corresponding to section

    }
  });
}, sectionItemOptions);

// start observing all sections on page
sections.forEach((section) => {
  sectionItemObserver.observe(section);
});
Run Code Online (Sandbox Code Playgroud)

想法

我的第一个想法是设置一个 setTimeout,以便导航在超时完成之前不会更改,然后如果该部分在超时完成之前离开屏幕,则取消超时。但由于超时是在 forEach 循环中,所以这不起作用。

const sectionItemObserver = new IntersectionObserver((entries, observer) => …
Run Code Online (Sandbox Code Playgroud)

javascript settimeout intersection-observer

5
推荐指数
2
解决办法
8617
查看次数

当从顶部或底部滚动到视图时,使用 Intersection Observer 向元素添加不同的类

我有一段 jQuery 代码,当元素滚动到视口中时,它会向元素添加一个 css 类;当元素滚动出视口时,会删除该类。

到目前为止,代码的工作原理如下:

  • 当元素滚动到视口中时,会添加“inview”类。
  • 当元素滚动出视口时,“inview”类将被删除。

到目前为止,一切都很好。但我想要实现的是:

滚动到视图中:

  • 当元素从页面底部滚动到视口时,会添加“inview-bottom”类。
  • 当元素从页面顶部滚动到视口时,会添加“inview-top”类。

滚动到视图之外:

  • 当元素从页面底部滚动出视口时,会添加“outview-bottom”类。
  • 当元素从页面顶部滚动出视口时,会添加“outview-top”类。

打扫干净:

  • 当元素从页面顶部或底部滚动到视口中时,应删除所有“outview-*”类。
  • 当元素从页面顶部或底部滚动出视口时,应删除所有“inview-*”类。

评论中建议使用Intersection Observer API,在阅读更多相关内容后,我相信它提供了满足要求的最佳方法。

这是我的代码(以整页打开 - 预览效果不佳)。您还可以在 jsFiddle 上找到相同的代码

function inView(opt) {
  if (opt.selector === undefined) {
    console.log('Valid selector required for inView');
    return false;
  }
  var elems = [].slice.call(document.querySelectorAll(opt.selector)),
    once = opt.once === undefined ? true : opt.once,
    offsetTop = opt.offsetTop === undefined ? 0 : opt.offsetTop,
    offsetBot = opt.offsetBot === undefined ? 0 : opt.offsetBot,
    count = elems.length, …
Run Code Online (Sandbox Code Playgroud)

javascript css jquery intersection-observer

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

视图中元素的 CSS 选择器

是否有针对view 中的内容(即在视口中可见的内容)的 CSS 选择器?

css css-selectors intersection-observer

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

使用 window.scrollTo 时避免处理 IntersectionObserver 且行为平滑

我正在使用 nuxt 创建一个登陆页面,我使用哈希来指示页面上的每个路线,为此我使用scrollBehavior来处理路线上的哈希并滚动到平滑的部分:

  router: {
    scrollBehavior: async (to, from, savedPosition) => {
      console.log(to, from, savedPosition);
      if (savedPosition) {
        return savedPosition;
      }

      const findEl = async (hash, x) => {
        return (
          document.querySelector(hash) ||
          new Promise((resolve, reject) => {
            if (x > 50) {
              return resolve();
            }
            setTimeout(() => {
              resolve(findEl(hash, ++x || 1));
            }, 100);
          })
        );
      };

      console.log("to.hash", to.hash);
      if (to.hash) {
        let el = await findEl(to.hash);
        console.log("el", el);
        if ("scrollBehavior" in document.documentElement.style) {
          return window.scrollTo({ top: …
Run Code Online (Sandbox Code Playgroud)

javascript vue.js vue-router nuxt.js intersection-observer

5
推荐指数
0
解决办法
541
查看次数

Typescript 中的 Intersection Observer 在 useRef 中抛出错误

我这里有一个运行完美的文本动画。我现在要添加的是一个 Intersection Observer,这样动画只有在我向下滚动到 Box 时才开始。

所以我为实现这一目标所做的是:我使用了 React hookuseRef作为对我想要观察的元素的引用,并将其应用到我的 Box 中ref={containerRef}。然后声明一个回调函数,该函数接收 IntersectionObserverEntries 数组作为参数,在该函数内,我获取第一个也是唯一一个条目,并检查它是否与视口相交,如果是,则使用 E​​ntry.isIntersecting 的值调用 setIsVisible (真假)。之后,我添加了反应钩子 useEffect 并使用回调函数和我之前创建的选项创建了一个观察者构造函数。我在一个新的钩子中实现了这个逻辑,我称之为useElementOnscreen

但是 Typescript 告诉我一个错误containerRef?.current

Argument of type 'IntersectionObserver' is not assignable to parameter of type 'Element'.
  Type 'IntersectionObserver' is missing the following properties from type 'Element': attributes, classList, className, clientHeight, and 160 more.
Run Code Online (Sandbox Code Playgroud)

而且我不知道如何解决这个错误。ref={containerRef}我认为这也是我抛出错误的原因

The expected type comes from property 'ref' which is declared here on type 'IntrinsicAttributes & { component: ElementType<any>; } & …
Run Code Online (Sandbox Code Playgroud)

javascript css typescript reactjs intersection-observer

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