我如何将额外的参数传递给 IntersectionObserver?我正在尝试为 Vue 创建一个延迟加载插件。它工作得很好,但我也希望能够调用提供的指令函数。
const lazyload = {
install(Vue) {
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.intersectionRatio > 0) {
console.log('In viewport');
}
});
});
Vue.directive('lazy', {
inserted(element) {
observer.observe(element);
}
});
}
};
Run Code Online (Sandbox Code Playgroud)
这意味着在插入的函数中我将设置binding为第二个参数。
inserted(element, binding)
Run Code Online (Sandbox Code Playgroud)
我将如何传递此绑定,以便我可以在 IntersectionObserver 回调中使用它?
最后它应该看起来像这样:
<div class="col-sm-6" v-lazy="fire">
Run Code Online (Sandbox Code Playgroud) javascript vue.js vue-component vuejs2 intersection-observer
我正在寻找一种方法来在菜单中向用户显示他在页面上的位置。每个菜单项都有指向另一个元素和 IntersectionObserver 的锚链接,IntersectionObserver 设置项目的背景宽度,以及项目是否从底部或顶部显示(背景上的左右)
let options = {
root: null,
rootMargin: "0px",
threshold: []
}
for (let i = 0; i <= 1.0; i += 0.01) {
options.threshold.push(i)
}
this.observer = new IntersectionObserver(entries => {
const item = entries[0]
if (item.isIntersecting) {
let visiblePct = Math.floor(item.intersectionRatio * 100)
this.pageProgressOpt.width =
(this.$el.getBoundingClientRect().width / 100) * visiblePct
this.pageProgressOpt.align =
item.boundingClientRect.top < 0 ? "right" : "left"
} else {
this.pageProgressOpt.width = 0
}
}, options)
Run Code Online (Sandbox Code Playgroud)
但是,当元素高度大于可见窗口的高度并且视图位于元素中间时,不会触发回调。这有点明显,因为达到了阈值 1.0。但我正在寻找继续观察元素的方法。我想在发生这种情况时附加到滚动条上,但无法说明是否发生这种情况。
我应该为此使用滚动事件还是有任何解决方法?
//编辑:这是我正在做的视频https://drive.google.com/file/d/1gPrIWgcLTJ3vhquyrUnyyh9IlTuZiDRJ/view
我想在实际看到图像时延迟加载图像。
所以,我使用了路口观察者 API。看起来效果很好
但overflow : hidden似乎不适用于交集 API
“不工作”意味着 DOM 似乎overflow: hidden会触发交集 API,因此我无法延迟加载图像
还有什么可以做的吗?或者那些结果是有意的?
使用IntersectionObserver API,如何找出特定元素何时位于视口之外?
一旦用户滚动经过标题,并且标题不再位于视口内,我就需要输出控制台日志。我想使用IntersectionObserver而不是滚动事件监听器来最小化负载,因为它是异步工作的。到目前为止我的代码是:
let options = {
root: null, //root
rootMargin: '0px',
threshold: 1.0,
};
function onChange(changes, observer) {
changes.forEach(change => {
if (change.intersectionRatio < 0) {
console.log('Header is outside viewport');
}
});
}
let observer = new IntersectionObserver(onChange, options);
let target = document.querySelector('#header');
observer.observe(target);
Run Code Online (Sandbox Code Playgroud)
此代码不输出任何控制台日志。PS:我的<header>元素的 ID 为header.
当表格单元格完全可见时,我正在更改其背景颜色。为了完成这项任务,我使用了交叉点观察器。
所有代码都可以在代码沙箱上使用,并通过演示重现该错误:
我正在使用 useInView 钩子作为交叉观察器:
export const useInView = options => {
const ref = useRef();
const [isVisible, setIsVisible] = useState(false);
const [intersectionRatio, setIntersectionRatio] = useState(false);
useEffect(() => {
const observer = new IntersectionObserver(([entry]) => {
console.log("called");
setIsVisible(entry.isIntersecting);
setIntersectionRatio(entry.intersectionRatio);
}, options);
if (ref.current) observer.observe(ref.current);
return () => {
if (ref.current) observer.unobserve(ref.current);
};
}, [ref, options]);
return [ref, isVisible, intersectionRatio];
};
Run Code Online (Sandbox Code Playgroud)
这是我在其中渲染数据的表:
<div id="my-table" style={{ height: 200, width: 200, overflow: "auto" }}>
<table>
<tbody>
{tableValues.map((row, rowIndex) => (
<tr key={rowIndex}>
{row.map((cell, …Run Code Online (Sandbox Code Playgroud) 我有一个使用相交观察器的组件,并且想开玩笑地测试元素相交时的效果。我已经成功地模拟了交叉口观察者,就像这个答案一样:/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) 到目前为止,这是我的代码:
const mediaInViewport = document.querySelectorAll('.media');
const links = Array.from(document.querySelectorAll('.link'));
let actLink = links[0];
document.body.addEventListener('click', (event) => {
if (event.target.tagName === 'a') {
actLink.classList.remove('active');
actLink = links.find(link => event.target.href === link.href)
actLink.classList.add('active');
}
}, false)
observer = new IntersectionObserver((entries, observer) => {
entries.forEach((entry) => {
if (entry.target && entry.isIntersecting) {
const closestParent = entry.target.closest('section');
if (closestParent) {
actLink.classList.remove('active');
actLink = links.find(link =>
link.href.slice(link.href.lastIndexOf('#')) === `#${closestParent.id}`
)
actLink.classList.add('active');
}
}
});
}, {
threshold: 0
});
window.addEventListener('DOMContentLoaded', () => {
setTimeout( // …Run Code Online (Sandbox Code Playgroud)我正在尝试使用 Intersection Observer API。我有一个在第一次迭代中可以工作的函数。基本逻辑是,如果用户向下滚动并从购物篮中添加或删除项目,一旦购物篮再次出现在视图中(因为它位于文档顶部),我就会触发 API 调用。
问题是它不会在滚动之前触发该函数,如果该项目可见或在滚动后再次变得可见(第二部分正在工作),我想触发它
这是原始js:
var observerTargets = document.querySelectorAll('[id^="mini-trolley"]');
var observerOptions = {
root: null, // null means root is viewport
rootMargin: '0px',
threshold: 0.01 // trigger callback when 1% of the element is visible
}
var activeClass = 'active';
var trigger = $('button');
var isCartItemClicked = false;
trigger.on('click', function() {
isCartItemClicked = true;
});
function observerCallback(entries, observer) {
entries.forEach(entry => {
if(entry.isIntersecting && isCartItemClicked){
$(observerTargets).removeClass(activeClass);
$(entry.target).addClass(activeClass);
isCartItemClicked = false;
console.log('isCartItemClicked and in view');
// do my …Run Code Online (Sandbox Code Playgroud) 我正在构建一个 React 应用程序,它的图像非常重,全部来自 API 调用。我已经完成了loading='lazy'所有这些,但这让我想知道是否可以做更多的事情?我知道您可以使用交叉观察器获得类似的结果,并且仅在视图中渲染它们。
我的问题是更好/实施交叉观察员是否有任何进一步的好处,还是会浪费时间,因为loading='lazy'已经足够了?
谢谢!
在元素上设置相交观察器。当元素滚动经过某个点时,会按预期触发交集观察器处理程序。但是,如果单击按钮将元素滚动经过同一点,则不会触发处理程序。
这是为什么?scrollTo有没有办法在使用/时强制触发处理程序scrollIntoView?
const container = document.getElementById("container");
const hello = document.getElementById("hello");
const button = document.getElementById("button");
const options = {
rootMargin: "-100px 0px 0px 0px",
threshold: 1
}
const handleIntersect = entries => {
entries.forEach((entry) => {
console.log("handleIntersect")
});
};
const observer = new IntersectionObserver(handleIntersect, options);
observer.observe(hello);
button.addEventListener("click", () => {
container.scrollTo({
top: 120
});
})Run Code Online (Sandbox Code Playgroud)
body {
margin: 0;
}
#container {
background-color: #ddd;
height: 400px;
overflow-y: auto;
}
.inner-container {
height: 100px;
border-bottom: 1px solid #bbb; …Run Code Online (Sandbox Code Playgroud)javascript ×8
reactjs ×2
css ×1
image ×1
intersection ×1
jestjs ×1
scroll ×1
vue.js ×1
vuejs2 ×1
webapi ×1