我正在使用Intersection Observer API来跟踪网页上多个元素的可见性。当一个元素变得可见时,callback()应该执行一个函数。限制:对于每个元素,该函数只能执行一次。
这是我当前的网络分析项目实现:
const elements = document.querySelectorAll('[data-observable]');
const callback = str => { console.log(str); };
const observer = new IntersectionObserver(handleIntersection);
elements.forEach(obs => {
observer.observe(obs);
});
function handleIntersection(entries, observer){
entries.forEach(entry => {
if (entry.intersectionRatio > 0) {
// Call this function only once per element, without modifying entry object
callback('observer-' + entry.target.getAttribute('data-observable'));
}
});
}
Run Code Online (Sandbox Code Playgroud)
我正在努力寻找不修改现有元素 IntersectionObserver 或 IntersectionObserverEntries 的解决方案。
通常我会使用闭包来确保一个函数只执行一次:
function once(func) {
let executed = false;
return function() {
if (!executed) {
executed = …Run Code Online (Sandbox Code Playgroud) 我正在尝试使某些文本项目停止与深色背景重叠,当用户滚动时,它们将逐一改变颜色。所有的文本项都是position: fixed
编辑:MDN 文档说(强调我的):
Intersection Observer API 提供了一种异步观察目标元素与祖先 元素交集变化的方法
我认为这意味着没有办法解决我的问题,因为我要监视重叠的元素不是root我在选项对象中指定的元素的子元素。
如果重叠元素不是另一个元素的子元素,有没有办法检测重叠?
if ('IntersectionObserver' in window) {
const options = {
root: document.getElementById('flow-landing'),
rootMargin: '0px',
threshold: 0
}
var callback = function(entries, observer) {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.style.color = "white";
}
else {
entry.target.style.color = null;
}
});
};
const observer = new IntersectionObserver(callback, options);
var targets = [Array.from(document.querySelectorAll('.social-item')), Array.from(document.querySelectorAll('.additional-item'))].flat();
targets.forEach(target =>
observer.observe(target));
}
Run Code Online (Sandbox Code Playgroud)
没有任何控制台错误,但代码没有做任何事情。
我正在使用在IntersectionObserver元素进入视口时添加和删除元素的类。
我不想说“当元素的 X% 可见时 - 添加此类”,而是说“当元素的 X% 可见时或当视口的 X% 被元素覆盖时 - 添加此类”。
我认为这是不可能的?如果是这样,我认为这有点缺陷,IntersectionObserver因为如果你有一个比视口高 10 倍的元素,它永远不会被视为可见,除非你将阈值设置为 10% 或更低。当您有可变高度元素时,尤其是在响应式设计中,您必须将阈值设置为 0.1% 之类的值才能“确定”该元素将接收该类(但您永远无法真正确定)。
编辑:回应摩西的答复。
Edit2:更新了几个阈值以强制它更频繁地计算percentOfViewport。还是不理想。
var observer = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
var entryBCR = entry.target.getBoundingClientRect();
var percentOfViewport = ((entryBCR.width * entryBCR.height) * entry.intersectionRatio) / ((window.innerWidth * window.innerHeight) / 100);
console.log(entry.target.id + ' covers ' + percentOfViewport + '% of the viewport and is ' + (entry.intersectionRatio * 100) + '% visible');
if (entry.intersectionRatio > …Run Code Online (Sandbox Code Playgroud)我试图通过交集观察者调用回调.
我想要的target是style: "position: fixed",并通过移动它
style.top.
我还指定了根元素,它是目标的祖先style: "position: relative".
但是当目标和观察者相交时,不会触发回调函数.
我错过了一些限制吗?
这是我输入的内容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>IO</title>
</head>
<body>
<div style="height: 200px;width: 100%;background: violet" class="upper">aaa</div>
<div style="position:relative;height: 200px;width: 100%;background: blueviolet" id="middle">bbb
<div id="target" style="position:fixed;top: 0px;width: 50px;height: 50px;background: firebrick">ccc</div>
</div>
<script>
let options = {
root: document.getElementById("middle"),
rootMargin: '0px',
threshold: 0
};
let observer = new IntersectionObserver(entry => {
console.log("observer's acting.")
}, options);
let target = document.getElementById("target");
observer.observe(target);
let stepping = 0; …Run Code Online (Sandbox Code Playgroud) 在IntersectionObserver被触发时的元件是在视口中一定量(0-100%)可见。这意味着,当元素在视口中已经 100% 时,它不再触发,因为阈值没有变化。
我有一个高度为 的元素,当我滚动到该元素时200vh,我希望IntersectionObserver触发。所以元素总是 100% 在视口内。
有没有办法在滚动元素时触发观察者?
我不能使用滚动事件,因为我使用的是 CSS scroll-snap,这会导致浏览器吞下事件,然后 JS 才能检测到它。
有没有一种方法可以使用“相交观察器”来检测元素是否离开视口?例如,我在屏幕上有一个元素,当元素的顶部碰到视口的顶部时,我想触发一个回调。从MDN:
Intersection Observer API使代码可以注册一个回调函数,该回调函数将在他们希望监视的元素进入或退出另一个元素(或视口)时,或者当两个相交的量改变请求的量时执行。-(https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)
因此,如果我做下面的事情,我会以为元素的顶部也到达视口的顶部时会触发回调?
var options = {
root: document.querySelector('#element'),
rootMargin: '0px',
threshold: 0
}
var observer = new IntersectionObserver(callback, options);
Run Code Online (Sandbox Code Playgroud)
但是,只有当元素的顶部滚动并击中视口的底部时,才会触发该事件,但不能同时触发两者。有想法吗?
仅当用户快速滚动条形图或强制滚动条停留在按钮上时,Intersection Observer 才会出现问题。
不幸的是,新数据到达了,但由于用户按住滚动条,ref 对象保留在视图上。
如果用户快速滚动或按住滚动条,则会发生此问题。虽然接收到新数据需要下推加载框,但用户手动保持。所以观察者不会检测到变化。
用户需要再次上下滚动才能再次加载。
无论如何,要向组件添加计时器,以查看 2 秒后加载框是否仍在视图中并调用端点?换句话说,我如何获得 IntersectionObserver 的当前状态。查看它当前是否可见?
我一直在一个网站上工作,因此决定向其添加暗模式功能,我使用darkmode.js库实现了该库,该库基于原理工作mix-blend-mode: difference。但是,当我使用IntersectionObserver向其中添加滚动动画并启用了暗模式时,应该显示的div变成白色,然后立即变成黑色。是的,看起来似乎很复杂,所以
这是我的代码
const targets = document.querySelectorAll('.animate');
const options = {
threshold: 0.7
}
const lazyLoad = target => {
const io = new IntersectionObserver((entries, observer) => {
console.log(entries)
entries.forEach(entry => {
console.log('');
if (entry.isIntersecting) {
const img = entry.target;
img.classList.add('fade');
observer.disconnect();
}
}, options)
}, options);
io.observe(target)
};
targets.forEach(lazyLoad);Run Code Online (Sandbox Code Playgroud)
.quotes-layout {
margin-top: 50px;
display: flex;
justify-content: center;
margin-left: 10%;
margin-right: 10%;
}
.quote {
flex: 1;
margin-right: 20px;
text-align: left;
background: #eee;
padding: 20px 20px;
}
.quote …Run Code Online (Sandbox Code Playgroud)javascript css difference mix-blend-mode intersection-observer
我正在尝试使用新的 Intersection Observer API,但我只能触发一次它的事件。我相信我使用它是正确的,因为我几乎是逐字逐句地使用MDN 示例。
https://jsfiddle.net/bukzor/epuwztn0/106/
function startObserver() {
// Almost verbatim from MDN docs:
// https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
let options = {
root: document.querySelector('#svg'),
rootMargin: '0px',
threshold: 0.50,
}
let observer = new IntersectionObserver(onIntersection, options);
let target = document.querySelector('circle');
observer.observe(target);
}
function onIntersection(entries, observer) {
// Simply log all intersectiono entries.
console.log(observer)
console.log("intersections:")
entries.forEach(function(entry) {
console.log(entry)
// This code is just a wild guess, but it still won't fire a second time.
observer.observe(entry.target)
})
}
Run Code Online (Sandbox Code Playgroud)
当我运行它时,我在控制台中只有一个条目,而没有其他条目。它提到的零大小矩形,isVisible: false似乎是其他症状,但我一直无法找到原因。 …
此脚本为活动部分发出活动类。最近注意到它在小屏幕上停止工作。即使在 chrome 的开发人员控制台中,我也会开始增加屏幕尺寸并且它会出现,一旦我开始缩小它就会立即停止工作(活动类消失)。但仅对于一个长部分,在较短的部分中一切正常。如何解决这个问题?
在代码片段中,我设置了一个较大的固定高度,因此投资组合链接不会接收活动类,在我的示例中,当部分宽度增加时,其高度会减小,因此在某些时候一切都会开始工作。
const links = document.querySelectorAll('.nav-link');
const sections = [... document.querySelectorAll('.forJS')];
const callback = (entries) => {
links.forEach((link) => link.classList.remove('active'));
const elem = entries.find((entry) => entry.isIntersecting);
if (elem) {
const index = sections.findIndex((section) => section === elem.target);
links[index].classList.add('active');
}
}
let observer = new IntersectionObserver(callback, {
rootMargin: '0px',
threshold: 0.5
});
sections.forEach((section) => observer.observe(section));Run Code Online (Sandbox Code Playgroud)
section {
height: 100vh;
scroll-y: auto;
}
.long{
height: 300vh;
}
.nav-link.active{
color: red;
}Run Code Online (Sandbox Code Playgroud)
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/js/bootstrap.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet"/>
<body>
<header class="fixed-top">
<nav …Run Code Online (Sandbox Code Playgroud)