【问题标题】:Two separate scroll areas simple solution两个单独的滚动区域简单的解决方案
【发布时间】:2018-10-12 17:36:09
【问题描述】:

我有一个特定的布局,我试图使用简单的 HTML5 和 CSS 来完成,尽可能少的 jQuery/JS,因为网站必须是高性能和轻量级的。

在这个站点中,我有两个独立的滚动区域。当用户第一次开始向下滚动时,滚动区域 1 向下滚动,固定内容区域 保持固定在其右侧。当用户到达 滚动区域 1 的末尾时,滚动会在固定内容所在的文档正文(即 滚动区域 2)上继续正常滚动区域 不再可见,并且该站点继续按其应有的方式下降。我在很多网站上都看到过这个,但我就是不知道叫什么或者人们是如何完成它的。

同样,我们向下滚动区域 1 直到那里没有更多内容可显示,而 固定内容区域 保持在右侧并可见,然后滚动继续通过 滚动区域 2,我们不再需要显示固定内容。

关于如何开始的任何提示、提示和想法?

这里有一张图来说明:

【问题讨论】:

  • 请提供一个最小、完整和可验证的示例:stackoverflow.com/help/mcve
  • w3schools.com/howto/howto_js_sticky_header.asp了解使用onScroll事件和添加/删除css类的逻辑。这就是完成上述任务所需的全部内容。是的,jQuery 在这里帮不上什么忙。
  • @Twisty 我相信“我从哪里开始”是 SO 中的一个有效问题,不需要最少的代码。包含 3-4 个 CSS 类和基本 HTML 会很不错,但如果有人害怕排除不同的方法,这不是严格要求的。
  • @AlexPakka "您应该只根据您所面临的实际问题提出实用的、可回答的问题。喋喋不休的开放式问题会降低我们网站的实用性,并将其他问题推到首页之外. 你的问题应该有合理的范围。如果你能想象一整本书都能回答你的问题,那你就问得太多了。" - stackoverflow.com/help/dont-ask

标签: javascript jquery html css


【解决方案1】:

创建一个限制在页面垂直部分的固定侧边栏

$(function() {
  if ($('.Scroller').length) {
    $(window).scroll(function() {
      var side = $('.Scroller');
      if ($(side).height() < window.innerHeight) {
        var top = $('.SectionWrap').offset().top,
          bottom = $('.SectionWrap').outerHeight() + top,
          maxY = bottom - $(side).outerHeight(),
          y = $(this).scrollTop() + 90; /*Extra padding for header menu*/
        if (y > top) { /*Scrolled past top of side bar*/
          if (y < maxY) { /*Scrolled past bottom of sidebar minus scroller height*/
            $(side).addClass('Active').removeAttr('style');
          } else {
            $(side).removeClass('Active').css({
              position: 'absolute',
              top: maxY - top - 10 + 'px' /*manual padding*/
            });
          }
        } else {
          $(side).removeClass('Active');
        }
      }
    });
  }
});
header {
  padding: 10px;
  background: #111;
  color: #aaa;
}

.PageWrap {
  display: flex;
}

.Section {
  border: 1px solid #aaa;
  padding: 10px;
  margin: 10px;
}

.SectionWrap {
  position: relative;
  display: flex;
  flex-direction: column;
  background: #eee;
  flex: 0 0 200px;
  /*Sidebar width*/
}

.Scroller {
  width: 200px;
}

.Scroller.Active {
  position: fixed;
  top: 90px;
  /*Match script*/
}

.SideContent {
  display: flex;
  flex-direction: column;
  color: #333;
  font-size: 0.9em;
  padding: 10px;
}

footer {
  background: #111;
  height: 500px;
  /*Simulated*/
  width: 100%;
  padding: 30px;
  color: #aaa;
  margin: 0 auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
  <h1>HEADER</h1>
</header>

<div class="PageWrap">

  <div class="PageContent">
    <div class="Section">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur a lectus eget quam viverra tempor. Integer erat est, condimentum non massa vel, porta rutrum purus. Pellentesque venenatis nulla augue, eu auctor tortor sollicitudin vitae. Maecenas
        hendrerit justo at urna malesuada, eu elementum nibh porta. Vivamus accumsan magna elementum diam dapibus, eleifend bibendum metus dictum. Nulla blandit finibus risus, vitae tincidunt purus rutrum sed. Etiam nec justo tincidunt, sollicitudin lorem
        eget, dapibus odio. Curabitur molestie ac quam in iaculis. Nullam id egestas lorem. Nam sit amet neque sapien. Maecenas volutpat ante ligula, in efficitur augue efficitur eu. Nam sed sapien velit. Mauris eu dapibus orci. Vivamus elit nisi, porta
        id eros eu, semper malesuada nulla. Mauris id interdum nisi. Quisque sit amet sagittis augue.</p>

      <p>Curabitur a finibus libero. Morbi ut velit vitae est placerat laoreet. Donec at quam vestibulum neque volutpat porta quis vitae elit. Vestibulum dignissim commodo placerat. Aenean volutpat nunc in dolor viverra, vel dapibus tortor porta. Ut posuere
        urna sed metus mattis, in hendrerit enim tempor. Quisque porta ex quam, ut rutrum neque ultrices sit amet. Donec dictum nisl sollicitudin, elementum est non, ornare nisl.</p>
    </div>

    <div class="Section">
      <p>Nulla risus nunc, pharetra a odio a, dapibus pretium mauris. Phasellus placerat velit diam, nec aliquam augue iaculis eget. Quisque feugiat fringilla velit, quis rhoncus ex dignissim sed. Class aptent taciti sociosqu ad litora torquent per conubia
        nostra, per inceptos himenaeos. Aliquam mollis odio ac sapien laoreet aliquam. Curabitur euismod nibh lacus, ut fermentum ligula dictum quis. Maecenas auctor ex eros, ac commodo quam pharetra et. Nam fringilla sem sit amet ullamcorper hendrerit.
        Nulla facilisi. Morbi ut faucibus elit, vel mattis lorem. Sed mollis posuere gravida. Nunc sagittis sapien purus, non aliquet velit suscipit non. Sed ut orci fringilla, vehicula elit nec, rutrum nulla. Aenean cursus massa mi, eget laoreet quam
        aliquam sed. Duis eu pulvinar mauris. Curabitur ultrices vestibulum tellus, ac elementum orci dignissim ultrices.</p>
    </div>
  </div>

  <div class="SectionWrap">
    <div class="Scroller">
      <div class="SideContent">
        SECTION SIDE BAR
      </div>
    </div>
  </div>

</div>

<footer>
  FOOTER
</footer>

【讨论】:

  • 是的!这正是我想要完成的。感谢您的回答!你认为有没有使用 jQuery 的方法来达到同样的效果?
  • 是的。如果您愿意,可以使用纯 Javascript。里面没有那么多 jQuery,我相信你可以很容易地转换它。
【解决方案2】:

您可以设置元素的position 属性,当您滚动到sticky 的特定部分时,您希望该属性可见。 Per MDN web docs:

粘性定位元素是其计算位置值为粘性的元素。它被视为相对定位,直到其包含块在其流根(或其滚动的容器)内超过指定阈值(例如将 top 设置为 auto 以外的值),此时它被视为“卡住”,直到满足其包含块的相对边缘。

请注意,此属性值不受支持 in some browsers

请看下面的演示:

body {
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
  grid-gap: 50px;
  font-family: sans-serif;
}

.header, .footer {
  text-transform: uppercase;
  text-align: center;
  padding: 20px;
  color: white;
  background: firebrick;
}
.header::after, .footer::after {
  content: attr(class);
}

.main {
  display: grid;
  grid-template-columns: 300px 1fr;
  grid-gap: 50px;
}
.main__content {
  border-left: 1px solid black;
  padding: 20px;
}

.sidebar {
  background: aqua;
  height: min-content;
  padding: 20px;
}

p {
  margin-bottom: 2em;
  font-size: 1.5rem;
}

/* This is the code that makes the .sidebar visible while you scroll through the .main element*/
.sidebar--sticky {
  position: sticky;
  top: 0;
}
<header class="header"></header>
<main class="main">
  <aside class="sidebar sidebar--sticky">Hello I am the sidebar</aside>
  <section class="main__content">
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eligendi, nisi perspiciatis labore minus at cumque eum aliquam harum voluptatem, suscipit vitae inventore iusto eaque animi similique quibusdam ratione reprehenderit? Fugit?</p>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eligendi, nisi perspiciatis labore minus at cumque eum aliquam harum voluptatem, suscipit vitae inventore iusto eaque animi similique quibusdam ratione reprehenderit? Fugit?</p>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eligendi, nisi perspiciatis labore minus at cumque eum aliquam harum voluptatem, suscipit vitae inventore iusto eaque animi similique quibusdam ratione reprehenderit? Fugit?</p>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eligendi, nisi perspiciatis labore minus at cumque eum aliquam harum voluptatem, suscipit vitae inventore iusto eaque animi similique quibusdam ratione reprehenderit? Fugit?</p>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eligendi, nisi perspiciatis labore minus at cumque eum aliquam harum voluptatem, suscipit vitae inventore iusto eaque animi similique quibusdam ratione reprehenderit? Fugit?</p>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eligendi, nisi perspiciatis labore minus at cumque eum aliquam harum voluptatem, suscipit vitae inventore iusto eaque animi similique quibusdam ratione reprehenderit? Fugit?</p>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eligendi, nisi perspiciatis labore minus at cumque eum aliquam harum voluptatem, suscipit vitae inventore iusto eaque animi similique quibusdam ratione reprehenderit? Fugit?</p>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eligendi, nisi perspiciatis labore minus at cumque eum aliquam harum voluptatem, suscipit vitae inventore iusto eaque animi similique quibusdam ratione reprehenderit? Fugit?</p>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eligendi, nisi perspiciatis labore minus at cumque eum aliquam harum voluptatem, suscipit vitae inventore iusto eaque animi similique quibusdam ratione reprehenderit? Fugit?</p>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eligendi, nisi perspiciatis labore minus at cumque eum aliquam harum voluptatem, suscipit vitae inventore iusto eaque animi similique quibusdam ratione reprehenderit? Fugit?</p>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eligendi, nisi perspiciatis labore minus at cumque eum aliquam harum voluptatem, suscipit vitae inventore iusto eaque animi similique quibusdam ratione reprehenderit? Fugit?</p>
  </section>
</main>
<footer class="footer"></footer>

它的工作原理是这样的,.sidebar.main__content 元素都是 .main 元素的直接子元素,并且此元素的高度由其子元素的高度定义,在本例中为 .main__content 元素高度是视口高度的两倍,并且由于.sidebarposition 属性的值是sticky,它将保持固定在视图中,直到它到达包含块的底部,即.main 元素。

【讨论】:

  • 我喜欢这个解决方案,因为它纯粹是用 CSS 编写的。但是,左侧的 lorem ipsum 文本应该随着滚动向下移动,就像上面 jQuery 中的解决方案一样。 CSS 能实现这种行为吗?
  • 当你说 " 左边的 lorem ipsum 文本应该随着滚动向下移动",如果我理解你的意思的话,文本会随着 sticky 内容滚动只是演示中没有足够的内容来展示这一点。我已经更新了代码示例以使其清楚。
猜你喜欢
  • 2010-09-05
  • 1970-01-01
  • 1970-01-01
  • 2010-12-28
  • 1970-01-01
  • 1970-01-01
  • 2012-06-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多