为什么路口观察者一直在运行?
why does intersection observer keeps on running?
我想使用交集观察器更改 header 的 class。这里的想法是,我有一个具有完整高度和宽度的 header,当我们向下滚动到另一个 div 时,header 缩小为一个小条。
这是我的 javascript 代码。
if('IntersectionObserver' in window){
const options = {
root: null,
rootMargin: '0px',
threshold: 0.0
}
callback = (entries) => {
const header = document.querySelector("header");
const IS_INTERSECTING = entries[0].isIntersecting;
if(!IS_INTERSECTING){
header.classList.replace("header_full","header");
return false;
}else if(IS_INTERSECTING){
header.classList.replace("header","header_full");
return false;
}else{
return false;
}
}
let observer = new IntersectionObserver(callback, options);
let target = document.querySelector('header');
observer.observe(target);
}
这是我的标记
<div class="application">
<header class="header_full">
<div>
<img src="logo_2.png" alt="logo">
<h2>Intersection Observer</h2>
</div>
<div class="bars"></div>
</header>
<div class="full">full_1</div>
<div class="full">full_2</div>
<div class="full">full_3</div>
<div class="full">full_4</div>
<div class="full">full_5</div>
</div>
这是我的 scss 文件
%full{
height: 100vh;
}
body{
margin: unset;
background:whitesmoke;
font-family: Comfortaa;
}
.full{
@extend %full;
}
.header_full{
@extend %full;
background: goldenrod;
display: grid;
place-items:center;
position: relative;
& img{
height: 250px;
width:250px;
object-fit: contain;
}
& h2{
text-align: center;
color: rgb(60, 60, 60);
letter-spacing: 1.4px;
}
& .bars{
&::after{
content: "☰";
font-size:1.3rem;
}
height: 40px;
width: 40px;
display: grid;
place-items:center;
position:absolute;
top:10px;
right: 10px;
color: rgb(60,60,60);
}
}
header{
transition: all 500ms linear;
}
.header{
height: 100px;
max-height: 100px;;
background: goldenrod;
position: fixed;
top:0;
width: 100%;
padding: 10px;
box-sizing: border-box;
animation: bring_down 500ms linear;
& img{
height: 80px;
width:80px;
object-fit: contain;
}
& h2{
display: none;
}
& .bars{
position:static;
}
}
我面临的问题是当我向下滚动时,路口观察器不断切换 classes 即。 header_full 和 header。让它一直闪烁。我试过“observer.unobserve(header)”,但我遇到的问题是停止观察,因此 header 仅更改一次。
我也参考了以下堆栈溢出问题,但没有成功。
Intersection Observer change class based on clientHeight
IntersectionObserver
基于视口(或另一个指定元素根)内的可见性,因此如果您的目标不断进入和退出视口,您将以无限循环告终。
这就是您的代码正在做的事情。 header
退出视口,触发 !IS_INTERSECTING
控制流,立即将其放回视口内。 Re-entering 视口触发 IS_INTERSECTING
控制流,它立即将其推出 - 这是一个无限循环。
您需要 IntersectionObserver
定位静态元素,该元素不会因回调而改变其 DOM 位置。我建议将 header
完全从文档流中取出,并在其后放置一个 100vh
占位符。就剩余内容而言,当您的 header 从 100vh
变为本质上 0px
时,移除 heavy 布局偏移的额外好处.
<div class="application">
<div class="header_placeholder"></div>
<header class="header_full">
<div>
<img src="logo_2.png" alt="logo">
<h2>Intersection Observer</h2>
</div>
<div class="bars"></div>
</header>
<div class="full">full_1</div>
<div class="full">full_2</div>
<div class="full">full_3</div>
<div class="full">full_4</div>
<div class="full">full_5</div>
</div>
%full{
height: 100vh;
}
body{
margin: unset;
background:whitesmoke;
font-family: Comfortaa;
}
.full{
@extend %full;
}
.header_placeholder {
height: 100vh;
}
.header_full{
@extend %full;
background: goldenrod;
display: grid;
place-items:center;
/* move this out of the document flow */
position: absolute;
top: 0;
width: 100%;
& img{
height: 250px;
width:250px;
object-fit: contain;
}
& h2{
text-align: center;
color: rgb(60, 60, 60);
letter-spacing: 1.4px;
}
& .bars{
&::after{
content: "☰";
font-size:1.3rem;
}
height: 40px;
width: 40px;
display: grid;
place-items:center;
position:absolute;
top:10px;
right: 10px;
color: rgb(60,60,60);
}
}
header{
transition: all 500ms linear;
}
.header{
height: 100px;
max-height: 100px;;
background: goldenrod;
position: fixed;
top:0;
width: 100%;
padding: 10px;
box-sizing: border-box;
animation: bring_down 500ms linear;
& img{
height: 80px;
width:80px;
object-fit: contain;
}
& h2{
display: none;
}
& .bars{
position:static;
}
}
if('IntersectionObserver' in window){
const options = {
root: null,
rootMargin: '0px',
threshold: 0.0
}
callback = (entries) => {
const header = document.querySelector("header");
const IS_INTERSECTING = entries[0].isIntersecting;
if(!IS_INTERSECTING){
header.classList.replace("header_full","header");
return false;
}else if(IS_INTERSECTING){
header.classList.replace("header","header_full");
return false;
}else{
return false;
}
}
let observer = new IntersectionObserver(callback, options);
// target the placeholder element here
let target = document.querySelector('.header_placeholder');
observer.observe(target);
}
我想使用交集观察器更改 header 的 class。这里的想法是,我有一个具有完整高度和宽度的 header,当我们向下滚动到另一个 div 时,header 缩小为一个小条。
这是我的 javascript 代码。
if('IntersectionObserver' in window){
const options = {
root: null,
rootMargin: '0px',
threshold: 0.0
}
callback = (entries) => {
const header = document.querySelector("header");
const IS_INTERSECTING = entries[0].isIntersecting;
if(!IS_INTERSECTING){
header.classList.replace("header_full","header");
return false;
}else if(IS_INTERSECTING){
header.classList.replace("header","header_full");
return false;
}else{
return false;
}
}
let observer = new IntersectionObserver(callback, options);
let target = document.querySelector('header');
observer.observe(target);
}
这是我的标记
<div class="application">
<header class="header_full">
<div>
<img src="logo_2.png" alt="logo">
<h2>Intersection Observer</h2>
</div>
<div class="bars"></div>
</header>
<div class="full">full_1</div>
<div class="full">full_2</div>
<div class="full">full_3</div>
<div class="full">full_4</div>
<div class="full">full_5</div>
</div>
这是我的 scss 文件
%full{
height: 100vh;
}
body{
margin: unset;
background:whitesmoke;
font-family: Comfortaa;
}
.full{
@extend %full;
}
.header_full{
@extend %full;
background: goldenrod;
display: grid;
place-items:center;
position: relative;
& img{
height: 250px;
width:250px;
object-fit: contain;
}
& h2{
text-align: center;
color: rgb(60, 60, 60);
letter-spacing: 1.4px;
}
& .bars{
&::after{
content: "☰";
font-size:1.3rem;
}
height: 40px;
width: 40px;
display: grid;
place-items:center;
position:absolute;
top:10px;
right: 10px;
color: rgb(60,60,60);
}
}
header{
transition: all 500ms linear;
}
.header{
height: 100px;
max-height: 100px;;
background: goldenrod;
position: fixed;
top:0;
width: 100%;
padding: 10px;
box-sizing: border-box;
animation: bring_down 500ms linear;
& img{
height: 80px;
width:80px;
object-fit: contain;
}
& h2{
display: none;
}
& .bars{
position:static;
}
}
我面临的问题是当我向下滚动时,路口观察器不断切换 classes 即。 header_full 和 header。让它一直闪烁。我试过“observer.unobserve(header)”,但我遇到的问题是停止观察,因此 header 仅更改一次。
我也参考了以下堆栈溢出问题,但没有成功。
Intersection Observer change class based on clientHeight
IntersectionObserver
基于视口(或另一个指定元素根)内的可见性,因此如果您的目标不断进入和退出视口,您将以无限循环告终。
这就是您的代码正在做的事情。 header
退出视口,触发 !IS_INTERSECTING
控制流,立即将其放回视口内。 Re-entering 视口触发 IS_INTERSECTING
控制流,它立即将其推出 - 这是一个无限循环。
您需要 IntersectionObserver
定位静态元素,该元素不会因回调而改变其 DOM 位置。我建议将 header
完全从文档流中取出,并在其后放置一个 100vh
占位符。就剩余内容而言,当您的 header 从 100vh
变为本质上 0px
时,移除 heavy 布局偏移的额外好处.
<div class="application">
<div class="header_placeholder"></div>
<header class="header_full">
<div>
<img src="logo_2.png" alt="logo">
<h2>Intersection Observer</h2>
</div>
<div class="bars"></div>
</header>
<div class="full">full_1</div>
<div class="full">full_2</div>
<div class="full">full_3</div>
<div class="full">full_4</div>
<div class="full">full_5</div>
</div>
%full{
height: 100vh;
}
body{
margin: unset;
background:whitesmoke;
font-family: Comfortaa;
}
.full{
@extend %full;
}
.header_placeholder {
height: 100vh;
}
.header_full{
@extend %full;
background: goldenrod;
display: grid;
place-items:center;
/* move this out of the document flow */
position: absolute;
top: 0;
width: 100%;
& img{
height: 250px;
width:250px;
object-fit: contain;
}
& h2{
text-align: center;
color: rgb(60, 60, 60);
letter-spacing: 1.4px;
}
& .bars{
&::after{
content: "☰";
font-size:1.3rem;
}
height: 40px;
width: 40px;
display: grid;
place-items:center;
position:absolute;
top:10px;
right: 10px;
color: rgb(60,60,60);
}
}
header{
transition: all 500ms linear;
}
.header{
height: 100px;
max-height: 100px;;
background: goldenrod;
position: fixed;
top:0;
width: 100%;
padding: 10px;
box-sizing: border-box;
animation: bring_down 500ms linear;
& img{
height: 80px;
width:80px;
object-fit: contain;
}
& h2{
display: none;
}
& .bars{
position:static;
}
}
if('IntersectionObserver' in window){
const options = {
root: null,
rootMargin: '0px',
threshold: 0.0
}
callback = (entries) => {
const header = document.querySelector("header");
const IS_INTERSECTING = entries[0].isIntersecting;
if(!IS_INTERSECTING){
header.classList.replace("header_full","header");
return false;
}else if(IS_INTERSECTING){
header.classList.replace("header","header_full");
return false;
}else{
return false;
}
}
let observer = new IntersectionObserver(callback, options);
// target the placeholder element here
let target = document.querySelector('.header_placeholder');
observer.observe(target);
}