多个粘性元素

Multiple sticky elements

如何编写 unlimited (#stickyContainer) 元素数量的代码(如下)也能使代码正常工作?现在,一个元素起作用了。

https://jsfiddle.net

function $(id) {
    return document.getElementById(id);
}

function sticky() {
    var stickyBoxHeight = $('stickyBox').offsetHeight;

    var stickyTop = $('stickyBox').getBoundingClientRect();
    var stickyBoxTop = stickyTop.top;

    var stickyBoxBottom = stickyBoxTop + stickyBoxHeight;

    var stickyHeight = $('sticky').offsetHeight;

    if (stickyBoxTop <= 0) {
        $('sticky').className = 'fixed';
    } else if (stickyBoxBottom >= stickyBoxHeight) {
        $('sticky').className = '';
    }

    if (stickyBoxBottom <= stickyHeight) {
        $('sticky').className = 'fixedBottom';
    }
}

window.onscroll = function () {
    sticky();
}

所以在我进入 javascript 和 html 代码之前的第一件事是如果我是你我会研究 css position:sticky 和 sticky polyfill for broswers那不支持它。在这种情况下,它会让你的生活更轻松,因为它会处理容器的宽度,你只需要将位置设置为 sticky 以及你希望它从 window 顶部开始的距离坚持。在未来,这很可能成为网页设计的支柱。另一个好处是,在移动屏幕上,您可以轻松地将元素更改为堆叠,而不是只使用 css 而不是冗长的 javascript 编码。您可以在此处阅读更多相关信息 https://www.sitepoint.com/css-position-sticky-introduction-polyfills/。因此,对于粘性,您只需要将 css 设置为这样的元素即可。

.sticky-box{
  position: -webkit-sticky;
  position: sticky;
  top: 0;
}

然后不支持 css sticky 的浏览器的 polyfill 可以在 https://github.com/wilddeer/stickyfill 下载,你只需包含 polyfill 的路径并使用 javascript 启动所以:

<script src="path/to/stickyfill.min.js"></script>

var stickyElements = document.getElementsByClassName('sticky-box');
for (var i = stickyElements.length - 1; i >= 0; i--) {
    Stickyfill.add(stickyElements[i]);
}

我已经做了一个实际演示。注意:我不得不重写 html 和 css,因为我无法理解你在 fiddle 中的代码,也如评论中所述,你应该只有一个每个页面上的特定 ID。 ID 应该对每页的一个元素是唯一的。所以你会想要使用 classes 来代替。

这里是Css位置粘性演示Fiddle Demo

说了这么多,我们将继续 javascript 方法以及如何为此编写代码。首先,就像我说的那样,您将要使用 class 名称而不是 id,因为您将拥有多个名称。因此,对于标记,您需要一个粘性容器,然后在该容器内放置一个粘性盒子。然后你将容器定位为相对的,然后我们将在添加 classes 时相应地定位粘性框。现在我们要做的是 运行 每个粘性容器在 javascript 中的 for 循环并向它们添加 class 因为这将是最简单的。因此,每当其中一个粘性容器到达顶部时,我们将添加 class 固定到容器而不是粘性容器本身。然后在您的 css 中,您可以使用此父级将位置添加到粘性框中,如下所示:

  <div class="sticky-container">
    <div class="sticky-box">
      Sticky Box
    </div>
  </div>

.fixed .sticky-box{
  position:fixed;
  top:0;
  right:0;
}
.fixedBottom .sticky-box{
  position:absolute;
  top:auto;
  bottom:0;
}

唯一应该放在粘性容器中的是粘性盒子,因此获取信息 div 并将其放在粘性容器之外。然后您需要创建一个 javascript 函数来为框添加宽度,因为当它被固定时,它需要与它所在的容器具有相同的宽度。对于以下示例,因为您已经声明了高度sticky-box 和 sticky-container 我只是使用数字而不是计算容器高度来添加 fixedBottom class 但是如果你的盒子和容器将是动态高度你将不得不写出一些代码计算何时应添加 fixedBottom class。无论如何,我知道这是一个很长的答案,但有很多关于代码的解释,所以这里是我在示例中使用的内容。看看它,看看它是如何工作的。

这是一个 fiddle 演示 Fiddle Demo

以及新的javascript代码

var stickyContainers = document.getElementsByClassName("sticky-container");
function sticky(){
  for(var i = 0; i < stickyContainers.length; i++){
    var stickyContainer = stickyContainers[i];
    if (window.pageYOffset >= stickyContainer.offsetTop){
      stickyContainer.classList.add("fixed");
    }else{
      stickyContainer.classList.remove("fixed");
    }
    if (window.pageYOffset >= stickyContainer.offsetTop + 350){
      stickyContainer.classList.add("fixedBottom");
    }else{
      stickyContainer.classList.remove("fixedBottom");
    }
  }
}
window.onscroll = function() {
  sticky();
}