javascript - 为什么交叉口观察者一直在运行?
问题描述
我想使用交叉点观察器更改标题的类。这里的想法是我有一个完整的高度和宽度的标题,当我们向下滚动到另一个 div 时,标题会缩小到一个小条。
这是我的 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;
}
}
我面临的问题是当我向下滚动时,交叉点观察者不断切换类,即。header_full 和标题。让它一直闪烁。我试过“observer.unobserve(header)”,但我得到的问题是停止观察,因此只改变了一次标题。
我还提到了以下堆栈溢出问题,但没有运气。
解决方案
IntersectionObserver
基于视口(或另一个指定的元素根)内的可见性,因此如果您的目标不断地进入和退出视口,您将最终陷入无限循环。
这就是您的代码正在做的事情。header
退出视口,触发控制!IS_INTERSECTING
流,立即将其放回视口内。重新进入视口会触发IS_INTERSECTING
控制流,它会立即将其推回 - 这是一个无限循环。
您需要IntersectionObserver
定位一个不会因回调而改变其 DOM 位置的静态元素。我建议您完全退出文档流程并在其后面header
放置一个占位符。100vh
这有一个额外的好处,即当您的标题从到基本上就剩余内容而言时,消除了繁重的布局转换。100vh
0px
<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);
}
推荐阅读
- sql - 如何在 Impala Hadoop 中解压复杂列?
- django - 为什么我无法在我的 html 模板上获得下拉菜单?
- java - 在java中将json字符串反序列化为字符串对象
- stm32 - CubeIDE 确实有管理嵌入式软件包处于非活动状态(安装 Cube.AI)
- elasticsearch - 如何使用另一个分析器动态更新文档术语?
- ios - 信标三边测量算法每次都给出相同的结果。IOS 斯威夫特
- python - pandas.read_excel 会保留列顺序吗?
- c - 改进我的 C 编码并发现代码问题
- php - 如何在使用语句中检测不存在的类
- java - 如何拆分字符串并保留分隔符'='