在达到 50% 视口高度时使用 IntersectionObserver 和 rootMargin 进行更改
Use IntersectionObserver with rootMargin to change when reaching 50% viewport height
路口观察者rootMargin
property让我彻底懵了
我的目标是在元素的一半高度穿过视口的垂直中心时向该元素添加 class。
在我当前的项目中,我所做的任何事情似乎都不会影响 "root intersection rectangle",并且总是立即添加 class。我在最新的 Chrome 和 Firefox 中测试过。
这是简化的测试用例:
// https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
const options = {
root: null, // default, use viewport
rootMargin: '0px 0px -50% 0px',
threshold: 0.5 // half of item height
}
const circle = document.getElementById('circle');
const observerCallback = function(entries, observer) {
console.log('intersected');
circle.classList.add('intersected');
}
window.addEventListener('load', function(event) {
const observer = new IntersectionObserver(observerCallback, options);
observer.observe(circle);
}, false);
.circle {
margin: 100vh auto;
width: 200px;
height: 200px;
background-color: tomato;
border-radius: 50%;
transition: background-color 2s ease-in-out;
}
.circle.intersected {
background-color: mediumseagreen;
}
<div class="circle" id="circle"></div>
我自己有时对 IntersectionObserver 很困惑,但参考 this post,它对我来说更容易掌握。
可能给您带来麻烦的是检查 if 它是否确实相交。所以我添加了一个 if-statement 以及在 IntersectionObserver 条目上找到的 属性 isIntersecting
。
我还添加了对 IntersectionObserver 的检查(如果它在客户端可用)并从选项中删除了 root: null
,因为无论如何它都应该默认为视口。
如果您只使用此 IntersectionObserver 添加一次 class,请不要忘记在不再需要时添加 observer.unobserve(circle)
或 observer.disconnect()
以防止内存泄漏。
// https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
const options = {
rootMargin: '0px 0px -50% 0px',
threshold: 0.5 // half of item height
}
const circle = document.getElementById('circle');
const observer = new IntersectionObserver(entries => {
const [{ isIntersecting }] = entries
if (isIntersecting) {
console.log('intersected');
circle.classList.add('intersected');
} else {
console.log('not-intersecting');
}
}, options);
window.addEventListener('load', () => {
if ('IntersectionObserver' in window) observer.observe(circle);
}, false);
.circle {
margin: 100vh auto;
width: 200px;
height: 200px;
background-color: tomato;
border-radius: 50%;
transition: background-color 2s ease-in-out;
}
.circle.intersected {
background-color: mediumseagreen;
}
<div class="circle" id="circle"></div>
路口观察者rootMargin
property让我彻底懵了
我的目标是在元素的一半高度穿过视口的垂直中心时向该元素添加 class。
在我当前的项目中,我所做的任何事情似乎都不会影响 "root intersection rectangle",并且总是立即添加 class。我在最新的 Chrome 和 Firefox 中测试过。
这是简化的测试用例:
// https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
const options = {
root: null, // default, use viewport
rootMargin: '0px 0px -50% 0px',
threshold: 0.5 // half of item height
}
const circle = document.getElementById('circle');
const observerCallback = function(entries, observer) {
console.log('intersected');
circle.classList.add('intersected');
}
window.addEventListener('load', function(event) {
const observer = new IntersectionObserver(observerCallback, options);
observer.observe(circle);
}, false);
.circle {
margin: 100vh auto;
width: 200px;
height: 200px;
background-color: tomato;
border-radius: 50%;
transition: background-color 2s ease-in-out;
}
.circle.intersected {
background-color: mediumseagreen;
}
<div class="circle" id="circle"></div>
我自己有时对 IntersectionObserver 很困惑,但参考 this post,它对我来说更容易掌握。
可能给您带来麻烦的是检查 if 它是否确实相交。所以我添加了一个 if-statement 以及在 IntersectionObserver 条目上找到的 属性 isIntersecting
。
我还添加了对 IntersectionObserver 的检查(如果它在客户端可用)并从选项中删除了 root: null
,因为无论如何它都应该默认为视口。
如果您只使用此 IntersectionObserver 添加一次 class,请不要忘记在不再需要时添加 observer.unobserve(circle)
或 observer.disconnect()
以防止内存泄漏。
// https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
const options = {
rootMargin: '0px 0px -50% 0px',
threshold: 0.5 // half of item height
}
const circle = document.getElementById('circle');
const observer = new IntersectionObserver(entries => {
const [{ isIntersecting }] = entries
if (isIntersecting) {
console.log('intersected');
circle.classList.add('intersected');
} else {
console.log('not-intersecting');
}
}, options);
window.addEventListener('load', () => {
if ('IntersectionObserver' in window) observer.observe(circle);
}, false);
.circle {
margin: 100vh auto;
width: 200px;
height: 200px;
background-color: tomato;
border-radius: 50%;
transition: background-color 2s ease-in-out;
}
.circle.intersected {
background-color: mediumseagreen;
}
<div class="circle" id="circle"></div>