繁体   English   中英

为什么路口观察器一直在运行?

[英]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;
    }
}

我面临的问题是当我向下滚动时,路口观察者不断切换类,即。 header_full 和 header。让它一直闪烁。 我试过“observer.unobserve(header)”,但我遇到的问题是停止观察,因此 header 仅更改一次。

我还提到了以下堆栈溢出问题,但没有运气。

使用 Intersection Observer (IO) 更改样式标题/导航

路口观察者根据clientHeight改成class

IntersectionObserver基于视口(或另一个指定元素根)内的可见性,因此如果您的目标不断进入和退出视口,您将以无限循环结束。

这就是您的代码正在做的事情。 header退出视口,触发!IS_INTERSECTING控制流,立即将其放回视口内。 重新进入视口会触发IS_INTERSECTING控制流,它会立即将其推出 - 这是一个无限循环。

您需要将IntersectionObserver定位到 static 元素,该元素不会因回调而更改其 DOM position。 我建议将您的header完全从文档流中取出,并在其后面放置一个100vh占位符。 就剩余内容而言,当您的 header 从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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM