【问题标题】:Hide block when entering footer进入页脚时隐藏块
【发布时间】:2022-01-09 08:31:03
【问题描述】:

我有一个在页面上滚动 200 像素后出现的块

const navShareLink = document.getElementById('navShareLink');
document.addEventListener('scroll', function(e) {
  if(window.scrollY > 200 && window.innerWidth > 576) {
    navShareLink.style.display = "block";
  } else {
    navShareLink.style.display = "none";
  }
});
.article-wrapper {
  min-height: 200vh;
}
.article-wrapper p:first-of-type {
  margin-top: 0;
}

footer {
  min-height: 100vh;
  background-color: #eee;
}

.sidemenu-shares {
  z-index: 999;
  display: flex;
  flex-direction: column;
  align-items: center;
  height: 100%;
  justify-content: center;
  position: fixed;
  top: 0;
  right: 0;
  flex-wrap: nowrap;
  gap: 40px;
}

.rectangle {
  z-index: 998;
  transition: opacity 0.5s;
  padding: 5px;
  height: 106px;
  width: 23px;
  background-color: rgba(0, 0, 0, 0.1);
  border-radius: 24px;
}
<div class="article-wrapper">

<div class="sidemenu-shares">
  <div id="navShareLink" class="rectangle">
  </div>
</div>

<div class="main-banner">
<h1>Title</h1>
</div>

<div>Main content...</div>
<div>Main content...</div>
<div>Main content...</div>
<div>Main content...</div>
<div>Main content...</div>
<div>Main content...</div>
<div>Main content...</div>
<div>Main content...</div>
<div>Main content...</div>

</div>

<footer>
  Footer...
</footer>

但是当它到达页脚所在的页面末尾时,我需要它隐藏起来,这样它就不会爬到页脚中

如果页面具有相同的高度很容易做到,但对我来说它可以是 2500px 或 5000px

是否有可能以某种方式以相反的顺序计算像素,但不是从页面的开头开始,而是从结尾算起 300px?

我试图获取整个页面的高度并减去 300

我用document.documentElement.scrollHeight我以为我只会得到一个像4500这样的数字值,但最后我在打开页面时在弹出窗口中得到了这个值的输出

https://imgur.com/a/kOCjxKX

或者,当它触及页脚时,我可以以某种方式隐藏这个块,是否有可能以某种方式做到这一点?

【问题讨论】:

    标签: javascript html jquery css


    【解决方案1】:

    IntersectionObserver API (MDN)

    此 API 允许您观察页面上的元素并根据它们相对于当前视口的位置调用代码。

    例子:

    1。回调

    const callback = (entries, observer) => {
      entries.forEach(entry => {
        // Each entry describes an intersection change for one observed
        // target element:
        //   entry.boundingClientRect
        //   entry.intersectionRatio
        //   entry.intersectionRect
        //   entry.isIntersecting <- This is what you usually look out for
        //   entry.rootBounds
        //   entry.target
        //   entry.time
    
        if (entry.isIntersecting) {
          document.getElementById('navShareLink').style.display = 'none';
      });
    };
    

    2。创建观察者

    const options = {
      root: document.body,
    
      // This specifies a margin around the target (basically changes the size of the target) - can be negative
      rootMargin: '0px 0px 0px 0px',
    
      // This specifies how much of the target needs to be in the viewport to qualify as 'intersecting' (1 === 100%)
      threshold: 1.0
    }
    
    const observer = new IntersectionObserver(callback, options);
    

    3。监督一个元素

    const target = document.querySelector('footer');
    observer.observe(target);
    

    一个观察者可以观察任意数量的目标。它通常是处理此类事情的最高效方式。

    滚动事件处理程序通常触发非常频繁,因此效率很低。如果您使用滚动处理程序,您至少应该 debounce 他们。

    【讨论】:

    • 一切都这样做了,但没有任何效果,这个元素在进入页脚时不会隐藏
    • 检查哪一个是您的滚动元素(使用浏览器开发工具)。它可能不是 document.body。将root设置为这个(或省略root,默认为document)
    • 抱歉,我不知道在哪里查看
    • 然后尝试省略根字段 :) - 也可以在回调函数中放置一个 console.log() 以便您可以看到观察者的结果!
    【解决方案2】:

    为了解决这个问题,我们需要从关键元素中获取适当的属性:

    • document.body.scrollHeight - 这里的 html 有滚动条并且正文溢出。 scrollHeight 给出了溢出的整个文档的高度。
    • footer.offsetHeight - 页脚的实际高度。
    • wrapper.getBoundingClientRect().y - 当我们向下滚动时,这给出了包装器的 y 位置。这是负面的,因为包装器会上升。

    剩下的数学很简单:

    var sideMenu, footer, wrapper, nsl;
    
    document.addEventListener("DOMContentLoaded", init, false);
    
    function check() {
      var range = document.body.scrollHeight - footer.offsetHeight;
      var position = (nsl.offsetHeight + nsl.getBoundingClientRect().y - wrapper.getBoundingClientRect().y).toFixed(1);
    
      nsl.innerText =
        '\n Range: ' + range +
        '\n Position: ' + position;
    
      if (window.scrollY > 200 && (range > position)) {
        nsl.style.visibility = "visible";
      } else {
        nsl.style.visibility = "hidden";
      }
    };
    
    function init() {
      sideMenu = document.getElementById('sideMenu');
      footer = document.getElementById('footer');
      wrapper = document.getElementById('wrapper');
      nsl = document.getElementById('navShareLink');
    
      window.onscroll = check;
      check();
    }
    .article-wrapper {
      min-height: 200vh;
      position: relative;
      top: 0;
      left: 0;
    }
    
    .article-wrapper p:first-of-type {
      margin-top: 0;
    }
    
    footer {
      min-height: 100vh;
      background-color: lightskyblue;
    }
    
    .sidemenu-shares {
      z-index: 999;
      display: flex;
      flex-direction: column;
      align-items: center;
      height: 100%;
      justify-content: center;
      position: fixed;
      top: 0;
      right: 0;
      flex-wrap: nowrap;
      gap: 40px;
    }
    
    .rectangle {
      z-index: 998;
      transition: opacity 0.5s;
      padding: 5px;
      height: 106px;
      width: 123px;
      background-color: rgba(200, 0, 0, 0.1);
      border-radius: 24px;
    }
    
    .content {
      height: 50px;
      border: 1px dotted gray;
    }
    <div id="wrapper" class="article-wrapper">
    
      <div id='sideMenu' class="sidemenu-shares">
        <div id="navShareLink" class="rectangle">
    
        </div>
      </div>
    
      <div class="main-banner">
        <h1>Title</h1>
      </div>
    
      <div class='content'>Main content...</div>
      <div class='content'>Main content...</div>
      <div class='content'>Main content...</div>
      <div class='content'>Main content...</div>
      <div class='content'>Main content...</div>
      <div class='content'>Main content...</div>
      <div class='content'>Main content...</div>
      <div class='content'>Main content...</div>
      <div class='content'>Main content...</div>
    </div>
    
    <footer id='footer'>
      Footer...
    </footer>


    以全页模式检查输出。

    【讨论】:

    • 我收到一个错误Uncaught ReferenceError: init is not defined at onload
    • 它在 stackoverflow 上运行良好。你有没有包括javascript?脚本中有一个函数function init() {
    • 是的,一切都在那里,我在body 中添加了onload="init ()",但body 位于适用于所有页面的单独app.blade 文件中,也许这就是问题所在?
    • 哦,去掉init和()之间的空格,改成onload='init()'
    • 一切正常,非常感谢您的帮助))))
    【解决方案3】:

    body {
      margin: 0;
    }
    
    .article-wrapper {
      min-height: 200vh;
    }
    
    .article-wrapper p:first-of-type {
      margin-top: 0;
    }
    
    footer {
      min-height: 30px;
      background-color: #eee;
    }
    
    .sidemenu-shares {
      margin: 0;
      display: flex;
      flex-direction: column;
      width: 18vw;
      height: 100vh;
    }
    
    .rectangle {
      background: red;
      width: 100%;
      height: 100%;
    }
    
    .row {
      display: flex;
    }
    
    .column {
      display: flex;
      flex-direction: column;
    }
    
    footer {
      position: absolute;
      bottom: 0;
      width: 100%;
    }
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
    </head>
    
    <body>
    
      <div class="article-wrapper row">
    
        <div class="sidemenu-shares">
          <div class="rectangle">
            <ul>
              <li>Home </li>
              <li>Contact</li>
              <li>About</li>
            </ul>
          </div>
        </div>
    
        <div class="column">
    
          <div class="main-banner">
            <h1>Title</h1>
          </div>
          <div>
            <div>Main content...</div>
            <div>Main content...</div>
            <div>Main content...</div>
            <div>Main content...</div>
            <div>Main content...</div>
            <div>Main content...</div>
          </div>
        </div>
    
      </div>
    
      <footer>
        Footer...
      </footer>
    </body>
    
    </html>

    也许这就是您正在寻找的答案,但我没有将侧边栏放在其他人的顶部,而是将侧边栏和主要内容插入到一个 div 中,然后我添加了 display flex 以使其连续但如果您仍然想将侧边栏放在其他人的顶部,您可以将其位置更改为绝对、粘性或固定,然后为主要内容添加边距,对于页脚,我使用相对位置,这样它就不会受到侧边栏的影响或你可以设置侧边栏的高度

    【讨论】:

    • 我需要这个面板具有特定的大小,并在整个页面中移动到页脚,而不是越过它
    • 我不知道它是否会起作用,但尝试将页脚的位置设置为粘在底部:0;属性然后将其 z-index 设置为高于侧边栏
    • 很遗憾没有帮助
    • 请看我下面的例子,这可能就是你想要的
    【解决方案4】:

    我不太明白您想要什么,但以防万一您希望侧边栏具有粘性,并且当您进入页脚时,它位于该块上方,您必须从 div class="main 中获取侧边栏代码-content”这样的

    /* The important part: */
    
    .sidebar {
      float: right;
      position: sticky;
      top: 8px;
      /* This should match the top margin/padding on the body */
    }
    
    
    /* Cosmetics for the demo: */
    
    .main-content {
      min-height: 200vh;
    }
    
    .main-content p:first-of-type {
      margin-top: 0;
    }
    
    .sidebar {
      width: 25vw;
      min-height: 25vh;
      background-color: #a00;
    }
    
    footer {
      min-height: 100vh;
      background-color: #eee;
    }
    
    html {
      margin: 0;
      padding: 0;
    }
    
    body {
      margin: 0;
      padding: 8px;
    }
    <!DOCTYPE html>
    
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
    </head>
    
    <body>
      <!--  here sidebar  -->
      <div class="sidebar">
        Sidebar...
      </div>
      <div class="main-content">
        <div>Main content...</div>
        <div>Main content...</div>
        <div>Main content...</div>
        <div>Main content...</div>
        <div>Main content...</div>
      </div>
      <footer>
        Footer...
      </footer>
    </body>
    
    </html>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-08
      • 2018-02-14
      • 2019-12-20
      • 2013-01-11
      • 2020-01-23
      • 1970-01-01
      • 2015-03-21
      • 2013-10-13
      相关资源
      最近更新 更多