Position sticky: scrollable, when longer than viewport
当带有 position: sticky 的元素”卡住”并且比视口长时,您只能在滚动到容器底部后才能看到其内容。
如果”卡住”元素随着文档滚动并在到达其底部边缘时停止,那将是很酷的。如果用户向后滚动,同样的事情会再次发生,但相反。
例子
TLDR;有一个库(StickyKit)可以满足我的要求,但在新的异步滚动中表现不佳。
带有 StickyKit 的 JSFiddle – https://jsfiddle.net/cibulka/4nd3b0tt/ – (这符合我的描述,但性能不佳,见下文)
JSFiddle 与原生 position: sticky – https://jsfiddle.net/cibulka/np6afe9c/1/ – https://jsfiddle.net/cibulka/pxz6e0qv/ – (不是)
背景
很长一段时间以来,我都是 StickyKit 的快乐用户。不幸的是,它不适用于异步滚动,越来越多的浏览器使用异步滚动来提高性能。例如,对于新的 Firefox Quantum (57),StickyKit 几乎无法使用。
我在 StickyKit Github 中创建了一个问题,但是包似乎被作者放弃了:https://github.com/leafo/sticky-kit/issues/252
正因为如此,我不得不弃用 StickyKit 并转向原生 position:sticky(用 StickyFill 填充)。不幸的是,有几件事 position:sticky 不能做,这就是其中之一。
position:sticky 还有另一个问题:Position sticky: overlay
我在寻找什么
基本上是关于如何解决此问题的建议。我准备使用不同的 JS/jQuery 库,编写自己的代码或使用一些古怪的 CSS hack 来破解 position:sticky 功能。
- 为了将来参考,我使用了 abouolia.github.io/sticky-sidebar 它就像一个魅力
有一个名为 Sticky Sidebar 的库正是为解决该问题而设计的。
- 谢谢,这终于解决了我的问题…… 1)我的侧边栏比视口高度更长,2)我需要我的侧边栏底部边缘在向下滚动时停止在视口底部,但在滚动页面时滚动回顶部边缘到向上。 Sticky-kit 插件或 position:sticky css 对我不起作用。
我已经接受了 jnns 的答案并对其进行了更新,以便它在滚动之间平滑,就像 Sticky Kit 一样。唯一的问题是它需要一个包含 div s.t. 的幻数。容器在 div 绝对定位时保持其大小 – 这可以通过 css 变量在您的代码中解决。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
window.onscroll = function (e) {
if (window.scrollY < this.prevScrollY) { // Track position state of nav // 1 == stuck to top // 0 == absolute positioning // -1 == stuck to bottom this.stick_pos = scrollUpwards(this.stick_pos); } else { this.stick_pos = scrollDownwards(this.stick_pos); } this.prevScrollY = window.scrollY; } function scrollUpwards(stick_pos) { function scrollDownwards(stick_pos) { |
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
div#section {
/* begin: irrelevant styling */ margin: 5em auto; padding: 0.625rem; max–width: 300px; font–family: sans–serif; font–size: 18px; line–height: 1.5em; text–align: justify; background–color: #dbe4ee; /* end: irrelevant styling */ display: flex; justify–content: space–around; } div#section div#nav–container { position: relative; display: flex; min–width: 2em; } div#section div#nav–container aside { position: sticky; align–self: flex–start; /* begin: irrelevant styling */ background–color: #81a4cd; color: white; text–align: center; width: 2em; } div#section div#nav–container aside div { padding: 0 .3em; } div#section article { margin–left: 0.5em; } div#section article p { margin: 0; } div#section article p + p { margin–top: 1.5em; } |
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
<script src=“https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js”>
<p>Voluptatem optio asperiores dolorem voluptatem. Ipsa alias perspiciatis doloribus est nisi ut. Fuga aut et vitae consequatur dolor corrupti aut minima.</p> <p>Facilis et ut eligendi. Excepturi labore asperiores vero. Perferendis porro sunt molestiae. In sit dolorem eum esse sit inventore est. Atque perspiciatis commodi nihil.</p> <p>Consequatur ipsa id repellendus voluptatem perspiciatis temporibus. Praesentium eveniet nemo laudantium inventore similique impedit nihil esse. Maiores iste commodi molestiae quas odit nihil ex corrupti. Illum id amet non vero.</p> <p>Voluptas soluta itaque et. Aperiam quasi sint eos ullam. Assumenda facilis omnis alias numquam. Odio quia esse vel et minima soluta architecto. Qui saepe consequatur aut rerum. Et et aut voluptatibus inventore.</p> <p>Perferendis ut iusto voluptatem ex temporibus aut autem amet. Sit vero in soluta. Est officia asperiores tenetur vel quam nostrum eum facere. Sed totam quasi libero at facilis doloremque. Non aut velit odio. Tempora dolore sunt recusandae sed quia sunt.</p> <p>Voluptatem optio asperiores dolorem voluptatem. Ipsa alias perspiciatis doloribus est nisi ut. Fuga aut et vitae consequatur dolor corrupti aut minima.</p> <p>Facilis et ut eligendi. Excepturi labore asperiores vero. Perferendis porro sunt molestiae. In sit dolorem eum esse sit inventore est. Atque perspiciatis commodi nihil.</p> <p>Consequatur ipsa id repellendus voluptatem perspiciatis temporibus. Praesentium eveniet nemo laudantium inventore similique impedit nihil esse. Maiores iste commodi molestiae quas odit nihil ex corrupti. Illum id amet non vero.</p> <p>Voluptas soluta itaque et. Aperiam quasi sint eos ullam. Assumenda facilis omnis alias numquam. Odio quia esse vel et minima soluta architecto. Qui saepe consequatur aut rerum. Et et aut voluptatibus inventore.</p> |
您可以尝试根据滚动方向使用jQuery从上到下切换粘性元素的锚点和位置,并且仍然使用CSS的原生position: sticky。
我让它在这个 codepen 中工作,但没有时间在方向改变时消除跳跃。但也许这对你来说已经足够了。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// Use display: flex on the container
window.onscroll = function (e) { function scrollUpwards() { } function scrollDownwards() { |
你看过 Scrollama
它使用新的 Intersection Observer Web API,它基本上是当某个元素出现在视口中时,浏览器会告诉 JS,而 JS 不必监听滚动事件。因此,对于以高性能的方式在 JS 中实现类似 position: sticky 的行为很有用。
- 这似乎不能解决我的问题,因为它似乎与”scrollytelling”用例有关——根据滚动位置切换 div,而不是滚动它们。不过谢谢!
来源:https://www.codenong.com/47618271/